First pass on the new SDL sensor API
authorSam Lantinga <slouken@libsdl.org>
Tue, 21 Aug 2018 12:11:34 -0700
changeset 1213024142c5073a4
parent 12129 42ff8f08c740
child 12131 9601849b3079
First pass on the new SDL sensor API
.hgignore
Android.mk
CMakeLists.txt
Makefile.in
Makefile.minimal
Makefile.pandora
Makefile.psp
Makefile.wiz
Xcode/SDL/SDL.xcodeproj/project.pbxproj
configure
configure.in
include/SDL.h
include/SDL_config_android.h
include/SDL_events.h
include/SDL_sensor.h
src/SDL.c
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
src/events/SDL_events.c
src/sensor/SDL_sensor.c
src/sensor/SDL_sensor_c.h
src/sensor/SDL_syssensor.h
src/sensor/android/SDL_androidsensor.c
src/sensor/android/SDL_androidsensor.h
test/Makefile.in
test/testsensor.c
     1.1 --- a/.hgignore	Tue Aug 21 11:59:13 2018 -0700
     1.2 +++ b/.hgignore	Tue Aug 21 12:11:34 2018 -0700
     1.3 @@ -112,6 +112,7 @@
     1.4  test/testrumble
     1.5  test/testscale
     1.6  test/testsem
     1.7 +test/testsensor
     1.8  test/testshader
     1.9  test/testshape
    1.10  test/testsprite2
     2.1 --- a/Android.mk	Tue Aug 21 11:59:13 2018 -0700
     2.2 +++ b/Android.mk	Tue Aug 21 12:11:34 2018 -0700
     2.3 @@ -36,6 +36,8 @@
     2.4  	$(wildcard $(LOCAL_PATH)/src/power/*.c) \
     2.5  	$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
     2.6  	$(wildcard $(LOCAL_PATH)/src/filesystem/android/*.c) \
     2.7 +	$(wildcard $(LOCAL_PATH)/src/sensor/*.c) \
     2.8 +	$(wildcard $(LOCAL_PATH)/src/sensor/android/*.c) \
     2.9  	$(wildcard $(LOCAL_PATH)/src/render/*.c) \
    2.10  	$(wildcard $(LOCAL_PATH)/src/render/*/*.c) \
    2.11  	$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
     3.1 --- a/CMakeLists.txt	Tue Aug 21 11:59:13 2018 -0700
     3.2 +++ b/CMakeLists.txt	Tue Aug 21 12:11:34 2018 -0700
     3.3 @@ -750,6 +750,10 @@
     3.4    file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/*.c)
     3.5    set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES})
     3.6  endif()
     3.7 +if(SDL_SENSOR)
     3.8 +  file(GLOB SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/*.c)
     3.9 +  set(SOURCE_FILES ${SOURCE_FILES} ${SENSOR_SOURCES})
    3.10 +endif()
    3.11  if(SDL_POWER)
    3.12    file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/*.c)
    3.13    set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES})
     4.1 --- a/Makefile.in	Tue Aug 21 11:59:13 2018 -0700
     4.2 +++ b/Makefile.in	Tue Aug 21 12:11:34 2018 -0700
     4.3 @@ -101,6 +101,7 @@
     4.4  	SDL_render.h \
     4.5  	SDL_rwops.h \
     4.6  	SDL_scancode.h \
     4.7 +	SDL_sensor.h \
     4.8  	SDL_shape.h \
     4.9  	SDL_stdinc.h \
    4.10  	SDL_surface.h \
     5.1 --- a/Makefile.minimal	Tue Aug 21 11:59:13 2018 -0700
     5.2 +++ b/Makefile.minimal	Tue Aug 21 12:11:34 2018 -0700
     5.3 @@ -22,6 +22,7 @@
     5.4  	src/filesystem/dummy/*.c \
     5.5  	src/render/*.c \
     5.6  	src/render/software/*.c \
     5.7 +	src/sensor/*.c \
     5.8  	src/stdlib/*.c \
     5.9  	src/thread/*.c \
    5.10  	src/thread/generic/*.c \
     6.1 --- a/Makefile.pandora	Tue Aug 21 11:59:13 2018 -0700
     6.2 +++ b/Makefile.pandora	Tue Aug 21 12:11:34 2018 -0700
     6.3 @@ -13,7 +13,7 @@
     6.4  TARGET  = libSDL.a
     6.5  
     6.6  SOURCES = ./src/*.c ./src/audio/*.c ./src/cpuinfo/*.c ./src/events/*.c \
     6.7 -	./src/file/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \
     6.8 +	./src/file/*.c ./src/sensor/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \
     6.9  	./src/joystick/*.c ./src/haptic/*.c ./src/power/*.c ./src/video/dummy/*.c ./src/audio/disk/*.c \
    6.10  	./src/audio/dummy/*.c ./src/loadso/dlopen/*.c ./src/audio/dsp/*.c \
    6.11  	./src/thread/pthread/SDL_systhread.c ./src/thread/pthread/SDL_syssem.c \
     7.1 --- a/Makefile.psp	Tue Aug 21 11:59:13 2018 -0700
     7.2 +++ b/Makefile.psp	Tue Aug 21 12:11:34 2018 -0700
     7.3 @@ -42,6 +42,7 @@
     7.4        src/render/software/SDL_drawpoint.o \
     7.5        src/render/software/SDL_render_sw.o \
     7.6        src/render/software/SDL_rotate.o \
     7.7 +      src/sensor/SDL_sensor.o \
     7.8        src/stdlib/SDL_getenv.o \
     7.9        src/stdlib/SDL_iconv.o \
    7.10        src/stdlib/SDL_malloc.o \
     8.1 --- a/Makefile.wiz	Tue Aug 21 11:59:13 2018 -0700
     8.2 +++ b/Makefile.wiz	Tue Aug 21 12:11:34 2018 -0700
     8.3 @@ -13,7 +13,7 @@
     8.4  TARGET_SHARED  = libSDL2.so
     8.5  
     8.6  SOURCES = ./src/*.c ./src/audio/*.c ./src/cpuinfo/*.c ./src/events/*.c \
     8.7 -	./src/file/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \
     8.8 +	./src/file/*.c ./src/sensor/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \
     8.9  	./src/joystick/*.c ./src/haptic/*.c ./src/video/dummy/*.c ./src/audio/disk/*.c \
    8.10  	./src/audio/dummy/*.c ./src/loadso/dlopen/*.c ./src/audio/dsp/*.c \
    8.11  	./src/thread/pthread/SDL_systhread.c ./src/thread/pthread/SDL_syssem.c \
     9.1 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Tue Aug 21 11:59:13 2018 -0700
     9.2 +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Tue Aug 21 12:11:34 2018 -0700
     9.3 @@ -904,6 +904,18 @@
     9.4  		DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; };
     9.5  		DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; };
     9.6  		DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; };
     9.7 +		F30D9C84212BC94F0047DF2E /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C81212BC94E0047DF2E /* SDL_sensor_c.h */; };
     9.8 +		F30D9C85212BC94F0047DF2E /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C81212BC94E0047DF2E /* SDL_sensor_c.h */; };
     9.9 +		F30D9C86212BC94F0047DF2E /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C81212BC94E0047DF2E /* SDL_sensor_c.h */; };
    9.10 +		F30D9C87212BC94F0047DF2E /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C82212BC94F0047DF2E /* SDL_syssensor.h */; };
    9.11 +		F30D9C88212BC94F0047DF2E /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C82212BC94F0047DF2E /* SDL_syssensor.h */; };
    9.12 +		F30D9C89212BC94F0047DF2E /* SDL_syssensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9C82212BC94F0047DF2E /* SDL_syssensor.h */; };
    9.13 +		F30D9C8A212BC94F0047DF2E /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F30D9C83212BC94F0047DF2E /* SDL_sensor.c */; };
    9.14 +		F30D9C8B212BC94F0047DF2E /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F30D9C83212BC94F0047DF2E /* SDL_sensor.c */; };
    9.15 +		F30D9C8C212BC94F0047DF2E /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F30D9C83212BC94F0047DF2E /* SDL_sensor.c */; };
    9.16 +		F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
    9.17 +		F3950CD9212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
    9.18 +		F3950CDA212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
    9.19  		FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
    9.20  		FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
    9.21  		FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
    9.22 @@ -1229,6 +1241,10 @@
    9.23  		D55A1B80179F262300625D7C /* SDL_cocoamousetap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamousetap.m; sourceTree = "<group>"; };
    9.24  		DB31407717554B71006C0E22 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
    9.25  		DB89958518A1A5C50092407C /* SDL_syshaptic_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_syshaptic_c.h; sourceTree = "<group>"; };
    9.26 +		F30D9C81212BC94E0047DF2E /* SDL_sensor_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sensor_c.h; sourceTree = "<group>"; };
    9.27 +		F30D9C82212BC94F0047DF2E /* SDL_syssensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_syssensor.h; sourceTree = "<group>"; };
    9.28 +		F30D9C83212BC94F0047DF2E /* SDL_sensor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_sensor.c; sourceTree = "<group>"; };
    9.29 +		F3950CD7212BC88D00F51292 /* SDL_sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sensor.h; sourceTree = "<group>"; };
    9.30  		F59C710300D5CB5801000001 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ReadMe.txt; sourceTree = "<group>"; };
    9.31  		F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = "<group>"; };
    9.32  		F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; };
    9.33 @@ -1348,6 +1364,7 @@
    9.34  				AA7557EB1595D4D800BBD41B /* SDL_revision.h */,
    9.35  				AA7557EC1595D4D800BBD41B /* SDL_rwops.h */,
    9.36  				AA7557ED1595D4D800BBD41B /* SDL_scancode.h */,
    9.37 +				F3950CD7212BC88D00F51292 /* SDL_sensor.h */,
    9.38  				AA7557EE1595D4D800BBD41B /* SDL_shape.h */,
    9.39  				AA7557EF1595D4D800BBD41B /* SDL_stdinc.h */,
    9.40  				AA7557F01595D4D800BBD41B /* SDL_surface.h */,
    9.41 @@ -1856,6 +1873,7 @@
    9.42  				04BDFE2F12E6671700899322 /* loadso */,
    9.43  				04BDFE4512E6671700899322 /* power */,
    9.44  				041B2C9712FA0D680087D585 /* render */,
    9.45 +				F3950CDB212BC8BC00F51292 /* sensor */,
    9.46  				04BDFE5D12E6671700899322 /* stdlib */,
    9.47  				04BDFE6412E6671800899322 /* thread */,
    9.48  				04BDFE9512E6671800899322 /* timer */,
    9.49 @@ -1980,6 +1998,17 @@
    9.50  			name = "Linked Frameworks";
    9.51  			sourceTree = "<group>";
    9.52  		};
    9.53 +		F3950CDB212BC8BC00F51292 /* sensor */ = {
    9.54 +			isa = PBXGroup;
    9.55 +			children = (
    9.56 +				F30D9C81212BC94E0047DF2E /* SDL_sensor_c.h */,
    9.57 +				F30D9C83212BC94F0047DF2E /* SDL_sensor.c */,
    9.58 +				F30D9C82212BC94F0047DF2E /* SDL_syssensor.h */,
    9.59 +			);
    9.60 +			name = sensor;
    9.61 +			path = ../../src/sensor;
    9.62 +			sourceTree = SOURCE_ROOT;
    9.63 +		};
    9.64  		F59C70FC00D5CB5801000001 /* pkg-support */ = {
    9.65  			isa = PBXGroup;
    9.66  			children = (
    9.67 @@ -2011,6 +2040,7 @@
    9.68  				AA75585E1595D4D800BBD41B /* SDL.h in Headers */,
    9.69  				AA7557FE1595D4D800BBD41B /* SDL_assert.h in Headers */,
    9.70  				AA7558001595D4D800BBD41B /* SDL_atomic.h in Headers */,
    9.71 +				F30D9C87212BC94F0047DF2E /* SDL_syssensor.h in Headers */,
    9.72  				AA7558021595D4D800BBD41B /* SDL_audio.h in Headers */,
    9.73  				AADA5B8716CCAB3000107CF7 /* SDL_bits.h in Headers */,
    9.74  				AA7558041595D4D800BBD41B /* SDL_blendmode.h in Headers */,
    9.75 @@ -2031,7 +2061,9 @@
    9.76  				AA75581A1595D4D800BBD41B /* SDL_hints.h in Headers */,
    9.77  				AA75581E1595D4D800BBD41B /* SDL_joystick.h in Headers */,
    9.78  				AA7558201595D4D800BBD41B /* SDL_keyboard.h in Headers */,
    9.79 +				F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */,
    9.80  				AA7558221595D4D800BBD41B /* SDL_keycode.h in Headers */,
    9.81 +				F30D9C84212BC94F0047DF2E /* SDL_sensor_c.h in Headers */,
    9.82  				AA7558241595D4D800BBD41B /* SDL_loadso.h in Headers */,
    9.83  				AA7558261595D4D800BBD41B /* SDL_log.h in Headers */,
    9.84  				5C2EF6F91FC9EE35003F5197 /* SDL_egl_c.h in Headers */,
    9.85 @@ -2186,6 +2218,7 @@
    9.86  				AA7558051595D4D800BBD41B /* SDL_blendmode.h in Headers */,
    9.87  				AA7558071595D4D800BBD41B /* SDL_clipboard.h in Headers */,
    9.88  				AA75580B1595D4D800BBD41B /* SDL_config.h in Headers */,
    9.89 +				F30D9C85212BC94F0047DF2E /* SDL_sensor_c.h in Headers */,
    9.90  				AA7558091595D4D800BBD41B /* SDL_config_macosx.h in Headers */,
    9.91  				AA75580D1595D4D800BBD41B /* SDL_copying.h in Headers */,
    9.92  				AA75580F1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */,
    9.93 @@ -2230,6 +2263,7 @@
    9.94  				AA7558511595D4D800BBD41B /* SDL_syswm.h in Headers */,
    9.95  				AAC070FA195606770073DCDF /* SDL_opengl_glext.h in Headers */,
    9.96  				AA7558531595D4D800BBD41B /* SDL_thread.h in Headers */,
    9.97 +				F30D9C88212BC94F0047DF2E /* SDL_syssensor.h in Headers */,
    9.98  				AA7558551595D4D800BBD41B /* SDL_timer.h in Headers */,
    9.99  				AA7558571595D4D800BBD41B /* SDL_touch.h in Headers */,
   9.100  				AA7558591595D4D800BBD41B /* SDL_types.h in Headers */,
   9.101 @@ -2269,6 +2303,7 @@
   9.102  				04BD028212E6671800899322 /* SDL_sysjoystick_c.h in Headers */,
   9.103  				04BD028C12E6671800899322 /* SDL_joystick_c.h in Headers */,
   9.104  				04BD028D12E6671800899322 /* SDL_sysjoystick.h in Headers */,
   9.105 +				F3950CD9212BC88D00F51292 /* SDL_sensor.h in Headers */,
   9.106  				04BD02B512E6671800899322 /* SDL_assert_c.h in Headers */,
   9.107  				04BD02B812E6671800899322 /* SDL_error_c.h in Headers */,
   9.108  				04BD02D912E6671800899322 /* SDL_sysmutex_c.h in Headers */,
   9.109 @@ -2352,6 +2387,7 @@
   9.110  				DB313FCD17554B71006C0E22 /* SDL_blendmode.h in Headers */,
   9.111  				DB313FCE17554B71006C0E22 /* SDL_clipboard.h in Headers */,
   9.112  				DB313FD017554B71006C0E22 /* SDL_config.h in Headers */,
   9.113 +				F30D9C86212BC94F0047DF2E /* SDL_sensor_c.h in Headers */,
   9.114  				DB313FCF17554B71006C0E22 /* SDL_config_macosx.h in Headers */,
   9.115  				DB313FD117554B71006C0E22 /* SDL_copying.h in Headers */,
   9.116  				DB313FD217554B71006C0E22 /* SDL_cpuinfo.h in Headers */,
   9.117 @@ -2396,6 +2432,7 @@
   9.118  				DB313FF217554B71006C0E22 /* SDL_syswm.h in Headers */,
   9.119  				AAC070FB195606770073DCDF /* SDL_opengl_glext.h in Headers */,
   9.120  				DB313FF317554B71006C0E22 /* SDL_thread.h in Headers */,
   9.121 +				F30D9C89212BC94F0047DF2E /* SDL_syssensor.h in Headers */,
   9.122  				DB313FF417554B71006C0E22 /* SDL_timer.h in Headers */,
   9.123  				DB313FF517554B71006C0E22 /* SDL_touch.h in Headers */,
   9.124  				DB313FF617554B71006C0E22 /* SDL_types.h in Headers */,
   9.125 @@ -2435,6 +2472,7 @@
   9.126  				DB313F8C17554B71006C0E22 /* SDL_sysjoystick_c.h in Headers */,
   9.127  				DB313F8D17554B71006C0E22 /* SDL_joystick_c.h in Headers */,
   9.128  				DB313F8E17554B71006C0E22 /* SDL_sysjoystick.h in Headers */,
   9.129 +				F3950CDA212BC88D00F51292 /* SDL_sensor.h in Headers */,
   9.130  				DB313F8F17554B71006C0E22 /* SDL_assert_c.h in Headers */,
   9.131  				DB313F9017554B71006C0E22 /* SDL_error_c.h in Headers */,
   9.132  				DB313F9217554B71006C0E22 /* SDL_sysmutex_c.h in Headers */,
   9.133 @@ -2774,6 +2812,7 @@
   9.134  				0442EC5A12FE1C60004C9285 /* SDL_x11framebuffer.c in Sources */,
   9.135  				0442EC5F12FE1C75004C9285 /* SDL_hints.c in Sources */,
   9.136  				56A67024185654B40007D20F /* SDL_dynapi.c in Sources */,
   9.137 +				F30D9C8A212BC94F0047DF2E /* SDL_sensor.c in Sources */,
   9.138  				04BAC0C81300C2160055DE28 /* SDL_log.c in Sources */,
   9.139  				5C2EF6EE1FC9D0ED003F5197 /* SDL_cocoaopengles.m in Sources */,
   9.140  				0435673E1303160F00BA5428 /* SDL_shaders_gl.c in Sources */,
   9.141 @@ -2909,6 +2948,7 @@
   9.142  				04F7805E12FB74A200FC43C0 /* SDL_drawpoint.c in Sources */,
   9.143  				0442EC1912FE1BBA004C9285 /* SDL_render_gl.c in Sources */,
   9.144  				0442EC1F12FE1BCB004C9285 /* SDL_render_sw.c in Sources */,
   9.145 +				F30D9C8B212BC94F0047DF2E /* SDL_sensor.c in Sources */,
   9.146  				56A67025185654B40007D20F /* SDL_dynapi.c in Sources */,
   9.147  				0442EC5C12FE1C60004C9285 /* SDL_x11framebuffer.c in Sources */,
   9.148  				0442EC6012FE1C75004C9285 /* SDL_hints.c in Sources */,
   9.149 @@ -3044,6 +3084,7 @@
   9.150  				DB31406017554B71006C0E22 /* SDL_drawpoint.c in Sources */,
   9.151  				DB31406117554B71006C0E22 /* SDL_render_gl.c in Sources */,
   9.152  				DB31406217554B71006C0E22 /* SDL_render_sw.c in Sources */,
   9.153 +				F30D9C8C212BC94F0047DF2E /* SDL_sensor.c in Sources */,
   9.154  				56A67026185654B40007D20F /* SDL_dynapi.c in Sources */,
   9.155  				DB31406317554B71006C0E22 /* SDL_x11framebuffer.c in Sources */,
   9.156  				DB31406417554B71006C0E22 /* SDL_hints.c in Sources */,
    10.1 --- a/configure	Tue Aug 21 11:59:13 2018 -0700
    10.2 +++ b/configure	Tue Aug 21 12:11:34 2018 -0700
    10.3 @@ -785,6 +785,7 @@
    10.4  enable_events
    10.5  enable_joystick
    10.6  enable_haptic
    10.7 +enable_sensor
    10.8  enable_power
    10.9  enable_filesystem
   10.10  enable_threads
   10.11 @@ -1523,6 +1524,7 @@
   10.12    --enable-joystick       Enable the joystick subsystem [[default=yes]]
   10.13    --enable-haptic         Enable the haptic (force feedback) subsystem
   10.14                            [[default=yes]]
   10.15 +  --enable-sensor         Enable the sensor subsystem [[default=yes]]
   10.16    --enable-power          Enable the power subsystem [[default=yes]]
   10.17    --enable-filesystem     Enable the filesystem subsystem [[default=yes]]
   10.18    --enable-threads        Enable the threading subsystem [[default=yes]]
   10.19 @@ -16884,6 +16886,7 @@
   10.20  #SOURCES="$SOURCES $srcdir/src/filesystem/*.c"
   10.21  SOURCES="$SOURCES $srcdir/src/render/*.c"
   10.22  SOURCES="$SOURCES $srcdir/src/render/*/*.c"
   10.23 +SOURCES="$SOURCES $srcdir/src/sensor/*.c"
   10.24  SOURCES="$SOURCES $srcdir/src/stdlib/*.c"
   10.25  SOURCES="$SOURCES $srcdir/src/thread/*.c"
   10.26  SOURCES="$SOURCES $srcdir/src/timer/*.c"
   10.27 @@ -16989,6 +16992,20 @@
   10.28  else
   10.29      SUMMARY_modules="${SUMMARY_modules} haptic"
   10.30  fi
   10.31 +# Check whether --enable-sensor was given.
   10.32 +if test "${enable_sensor+set}" = set; then :
   10.33 +  enableval=$enable_sensor;
   10.34 +else
   10.35 +  enable_sensor=yes
   10.36 +fi
   10.37 +
   10.38 +if test x$enable_sensor != xyes; then
   10.39 +
   10.40 +$as_echo "#define SDL_SENSOR_DISABLED 1" >>confdefs.h
   10.41 +
   10.42 +else
   10.43 +    SUMMARY_modules="${SUMMARY_modules} sensor"
   10.44 +fi
   10.45  # Check whether --enable-power was given.
   10.46  if test "${enable_power+set}" = set; then :
   10.47    enableval=$enable_power;
    11.1 --- a/configure.in	Tue Aug 21 11:59:13 2018 -0700
    11.2 +++ b/configure.in	Tue Aug 21 12:11:34 2018 -0700
    11.3 @@ -346,6 +346,7 @@
    11.4  #SOURCES="$SOURCES $srcdir/src/filesystem/*.c"
    11.5  SOURCES="$SOURCES $srcdir/src/render/*.c"
    11.6  SOURCES="$SOURCES $srcdir/src/render/*/*.c"
    11.7 +SOURCES="$SOURCES $srcdir/src/sensor/*.c"
    11.8  SOURCES="$SOURCES $srcdir/src/stdlib/*.c"
    11.9  SOURCES="$SOURCES $srcdir/src/thread/*.c"
   11.10  SOURCES="$SOURCES $srcdir/src/timer/*.c"
   11.11 @@ -410,6 +411,14 @@
   11.12  else
   11.13      SUMMARY_modules="${SUMMARY_modules} haptic"
   11.14  fi
   11.15 +AC_ARG_ENABLE(sensor,
   11.16 +AC_HELP_STRING([--enable-sensor], [Enable the sensor subsystem [[default=yes]]]),
   11.17 +              , enable_sensor=yes)
   11.18 +if test x$enable_sensor != xyes; then
   11.19 +    AC_DEFINE(SDL_SENSOR_DISABLED, 1, [ ])
   11.20 +else
   11.21 +    SUMMARY_modules="${SUMMARY_modules} sensor"
   11.22 +fi
   11.23  AC_ARG_ENABLE(power,
   11.24  AC_HELP_STRING([--enable-power], [Enable the power subsystem [[default=yes]]]),
   11.25                , enable_power=yes)
    12.1 --- a/include/SDL.h	Tue Aug 21 11:59:13 2018 -0700
    12.2 +++ b/include/SDL.h	Tue Aug 21 12:11:34 2018 -0700
    12.3 @@ -51,6 +51,7 @@
    12.4  #include "SDL_power.h"
    12.5  #include "SDL_render.h"
    12.6  #include "SDL_rwops.h"
    12.7 +#include "SDL_sensor.h"
    12.8  #include "SDL_shape.h"
    12.9  #include "SDL_system.h"
   12.10  #include "SDL_thread.h"
   12.11 @@ -80,10 +81,11 @@
   12.12  #define SDL_INIT_HAPTIC         0x00001000u
   12.13  #define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
   12.14  #define SDL_INIT_EVENTS         0x00004000u
   12.15 +#define SDL_INIT_SENSOR         0x00008000u
   12.16  #define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
   12.17  #define SDL_INIT_EVERYTHING ( \
   12.18                  SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
   12.19 -                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
   12.20 +                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
   12.21              )
   12.22  /* @} */
   12.23  
    13.1 --- a/include/SDL_config_android.h	Tue Aug 21 11:59:13 2018 -0700
    13.2 +++ b/include/SDL_config_android.h	Tue Aug 21 12:11:34 2018 -0700
    13.3 @@ -137,6 +137,9 @@
    13.4  #define SDL_JOYSTICK_HIDAPI    1
    13.5  #define SDL_HAPTIC_ANDROID    1
    13.6  
    13.7 +/* Enable sensor driver */
    13.8 +#define SDL_SENSOR_ANDROID  1
    13.9 +
   13.10  /* Enable various shared object loading systems */
   13.11  #define SDL_LOADSO_DLOPEN   1
   13.12  
    14.1 --- a/include/SDL_events.h	Tue Aug 21 11:59:13 2018 -0700
    14.2 +++ b/include/SDL_events.h	Tue Aug 21 12:11:34 2018 -0700
    14.3 @@ -144,6 +144,9 @@
    14.4      SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
    14.5      SDL_AUDIODEVICEREMOVED,        /**< An audio device has been removed. */
    14.6  
    14.7 +    /* Sensor events */
    14.8 +    SDL_SENSORUPDATE = 0x1200,     /**< A sensor was updated */
    14.9 +
   14.10      /* Render events */
   14.11      SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
   14.12      SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
   14.13 @@ -472,6 +475,17 @@
   14.14  
   14.15  
   14.16  /**
   14.17 + *  \brief Sensor event structure (event.sensor.*)
   14.18 + */
   14.19 +typedef struct SDL_SensorEvent
   14.20 +{
   14.21 +    Uint32 type;        /**< ::SDL_SENSORUPDATE */
   14.22 +    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
   14.23 +    Sint32 which;       /**< The instance ID of the sensor */
   14.24 +    float data[6];      /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
   14.25 +} SDL_SensorEvent;
   14.26 +
   14.27 +/**
   14.28   *  \brief The "quit requested" event
   14.29   */
   14.30  typedef struct SDL_QuitEvent
   14.31 @@ -542,6 +556,7 @@
   14.32      SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
   14.33      SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
   14.34      SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
   14.35 +    SDL_SensorEvent sensor;         /**< Sensor event data */
   14.36      SDL_QuitEvent quit;             /**< Quit request event data */
   14.37      SDL_UserEvent user;             /**< Custom event data */
   14.38      SDL_SysWMEvent syswm;           /**< System dependent window event data */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/include/SDL_sensor.h	Tue Aug 21 12:11:34 2018 -0700
    15.3 @@ -0,0 +1,201 @@
    15.4 +/*
    15.5 +  Simple DirectMedia Layer
    15.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    15.7 +
    15.8 +  This software is provided 'as-is', without any express or implied
    15.9 +  warranty.  In no event will the authors be held liable for any damages
   15.10 +  arising from the use of this software.
   15.11 +
   15.12 +  Permission is granted to anyone to use this software for any purpose,
   15.13 +  including commercial applications, and to alter it and redistribute it
   15.14 +  freely, subject to the following restrictions:
   15.15 +
   15.16 +  1. The origin of this software must not be misrepresented; you must not
   15.17 +     claim that you wrote the original software. If you use this software
   15.18 +     in a product, an acknowledgment in the product documentation would be
   15.19 +     appreciated but is not required.
   15.20 +  2. Altered source versions must be plainly marked as such, and must not be
   15.21 +     misrepresented as being the original software.
   15.22 +  3. This notice may not be removed or altered from any source distribution.
   15.23 +*/
   15.24 +
   15.25 +/**
   15.26 + *  \file SDL_sensor.h
   15.27 + *
   15.28 + *  Include file for SDL sensor event handling
   15.29 + *
   15.30 + */
   15.31 +
   15.32 +#ifndef _SDL_sensor_h
   15.33 +#define _SDL_sensor_h
   15.34 +
   15.35 +#include "SDL_stdinc.h"
   15.36 +#include "SDL_error.h"
   15.37 +
   15.38 +#include "begin_code.h"
   15.39 +/* Set up for C function definitions, even when using C++ */
   15.40 +#ifdef __cplusplus
   15.41 +/* *INDENT-OFF* */
   15.42 +extern "C" {
   15.43 +/* *INDENT-ON* */
   15.44 +#endif
   15.45 +
   15.46 +/**
   15.47 + *  \file SDL_sensor.h
   15.48 + *
   15.49 + *  In order to use these functions, SDL_Init() must have been called
   15.50 + *  with the ::SDL_INIT_SENSOR flag.  This causes SDL to scan the system
   15.51 + *  for sensors, and load appropriate drivers.
   15.52 + */
   15.53 +
   15.54 +struct _SDL_Sensor;
   15.55 +typedef struct _SDL_Sensor SDL_Sensor;
   15.56 +
   15.57 +/**
   15.58 + * This is a unique ID for a sensor for the time it is connected to the system,
   15.59 + * and is never reused for the lifetime of the application.
   15.60 + *
   15.61 + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
   15.62 + */
   15.63 +typedef Sint32 SDL_JoystickID;
   15.64 +typedef int SDL_SensorID;
   15.65 +
   15.66 +/* The different sensor types */
   15.67 +typedef enum
   15.68 +{
   15.69 +    SDL_SENSOR_INVALID = -1,    /**< Returned for an invalid sensor */
   15.70 +    SDL_SENSOR_UNKNOWN,         /**< Unknown sensor type */
   15.71 +    SDL_SENSOR_ACCEL,           /**< Accelerometer */
   15.72 +    SDL_SENSOR_GYRO,            /**< Gyroscope */
   15.73 +} SDL_SensorType;
   15.74 +
   15.75 +/* Function prototypes */
   15.76 +
   15.77 +/**
   15.78 + *  \brief Count the number of sensors attached to the system right now
   15.79 + */
   15.80 +extern DECLSPEC int SDLCALL SDL_NumSensors(void);
   15.81 +
   15.82 +/**
   15.83 + *  \brief Get the implementation dependent name of a sensor.
   15.84 + *
   15.85 + *  This can be called before any sensors are opened.
   15.86 + * 
   15.87 + *  \return The sensor name, or NULL if device_index is out of range.
   15.88 + */
   15.89 +extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index);
   15.90 +
   15.91 +/**
   15.92 + *  \brief Get the type of a sensor.
   15.93 + *
   15.94 + *  This can be called before any sensors are opened.
   15.95 + *
   15.96 + *  \return The sensor type, or SDL_SENSOR_INVALID if device_index is out of range.
   15.97 + */
   15.98 +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index);
   15.99 +
  15.100 +/**
  15.101 + *  \brief Get the platform dependent type of a sensor.
  15.102 + *
  15.103 + *  This can be called before any sensors are opened.
  15.104 + *
  15.105 + *  \return The sensor platform dependent type, or -1 if device_index is out of range.
  15.106 + */
  15.107 +extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index);
  15.108 +
  15.109 +/**
  15.110 + *  \brief Get the instance ID of a sensor.
  15.111 + *
  15.112 + *  This can be called before any sensors are opened.
  15.113 + *
  15.114 + *  \return The sensor instance ID, or -1 if device_index is out of range.
  15.115 + */
  15.116 +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index);
  15.117 +
  15.118 +/**
  15.119 + *  \brief Open a sensor for use.
  15.120 + *
  15.121 + *  The index passed as an argument refers to the N'th sensor on the system.
  15.122 + *
  15.123 + *  \return A sensor identifier, or NULL if an error occurred.
  15.124 + */
  15.125 +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index);
  15.126 +
  15.127 +/**
  15.128 + * Return the SDL_Sensor associated with an instance id.
  15.129 + */
  15.130 +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id);
  15.131 +
  15.132 +/**
  15.133 + *  \brief Get the implementation dependent name of a sensor.
  15.134 + *
  15.135 + *  \return The sensor name, or NULL if the sensor is NULL.
  15.136 + */
  15.137 +extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor);
  15.138 +
  15.139 +/**
  15.140 + *  \brief Get the type of a sensor.
  15.141 + *
  15.142 + *  This can be called before any sensors are opened.
  15.143 + *
  15.144 + *  \return The sensor type, or SDL_SENSOR_INVALID if the sensor is NULL.
  15.145 + */
  15.146 +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor);
  15.147 +
  15.148 +/**
  15.149 + *  \brief Get the platform dependent type of a sensor.
  15.150 + *
  15.151 + *  This can be called before any sensors are opened.
  15.152 + *
  15.153 + *  \return The sensor platform dependent type, or -1 if the sensor is NULL.
  15.154 + */
  15.155 +extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor);
  15.156 +
  15.157 +/**
  15.158 + *  \brief Get the instance ID of a sensor.
  15.159 + *
  15.160 + *  This can be called before any sensors are opened.
  15.161 + *
  15.162 + *  \return The sensor instance ID, or -1 if the sensor is NULL.
  15.163 + */
  15.164 +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor);
  15.165 +
  15.166 +/**
  15.167 + *  Get the current state of an opened sensor.
  15.168 + *
  15.169 + *  The number of values and interpretation of the data is sensor dependent.
  15.170 + *
  15.171 + *  \param sensor The sensor to query
  15.172 + *  \param data A pointer filled with the current sensor state
  15.173 + *  \param num_values The number of values to write to data
  15.174 + *
  15.175 + *  \return 0 or -1 if an error occurred.
  15.176 + */
  15.177 +extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values);
  15.178 +
  15.179 +/**
  15.180 + *  Close a sensor previously opened with SDL_SensorOpen()
  15.181 + */
  15.182 +extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor);
  15.183 +
  15.184 +/**
  15.185 + *  Update the current state of the open sensors.
  15.186 + *
  15.187 + *  This is called automatically by the event loop if sensor events are enabled.
  15.188 + *
  15.189 + *  This needs to be called from the thread that initialized the sensor subsystem.
  15.190 + */
  15.191 +extern DECLSPEC void SDLCALL SDL_SensorUpdate(void);
  15.192 +
  15.193 +
  15.194 +/* Ends C function definitions when using C++ */
  15.195 +#ifdef __cplusplus
  15.196 +/* *INDENT-OFF* */
  15.197 +}
  15.198 +/* *INDENT-ON* */
  15.199 +#endif
  15.200 +#include "close_code.h"
  15.201 +
  15.202 +#endif /* _SDL_sensor_h */
  15.203 +
  15.204 +/* vi: set ts=4 sw=4 expandtab: */
    16.1 --- a/src/SDL.c	Tue Aug 21 11:59:13 2018 -0700
    16.2 +++ b/src/SDL.c	Tue Aug 21 12:11:34 2018 -0700
    16.3 @@ -33,6 +33,7 @@
    16.4  #include "events/SDL_events_c.h"
    16.5  #include "haptic/SDL_haptic_c.h"
    16.6  #include "joystick/SDL_joystick_c.h"
    16.7 +#include "sensor/SDL_sensor_c.h"
    16.8  
    16.9  /* Initialization/Cleanup routines */
   16.10  #if !SDL_TIMERS_DISABLED
   16.11 @@ -232,6 +233,20 @@
   16.12  #endif
   16.13      }
   16.14  
   16.15 +    /* Initialize the sensor subsystem */
   16.16 +    if ((flags & SDL_INIT_SENSOR)){
   16.17 +#if !SDL_SENSOR_DISABLED
   16.18 +        if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) {
   16.19 +            if (SDL_SensorInit() < 0) {
   16.20 +                return (-1);
   16.21 +            }
   16.22 +        }
   16.23 +        SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR);
   16.24 +#else
   16.25 +        return SDL_SetError("SDL not built with sensor support");
   16.26 +#endif
   16.27 +    }
   16.28 +
   16.29      return (0);
   16.30  }
   16.31  
   16.32 @@ -245,6 +260,15 @@
   16.33  SDL_QuitSubSystem(Uint32 flags)
   16.34  {
   16.35      /* Shut down requested initialized subsystems */
   16.36 +#if !SDL_SENSOR_DISABLED
   16.37 +    if ((flags & SDL_INIT_SENSOR)) {
   16.38 +        if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
   16.39 +			SDL_SensorQuit();
   16.40 +		}
   16.41 +        SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
   16.42 +    }
   16.43 +#endif
   16.44 +
   16.45  #if !SDL_JOYSTICK_DISABLED
   16.46      if ((flags & SDL_INIT_GAMECONTROLLER)) {
   16.47          /* game controller implies joystick */
    17.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Tue Aug 21 11:59:13 2018 -0700
    17.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Tue Aug 21 12:11:34 2018 -0700
    17.3 @@ -681,3 +681,18 @@
    17.4  #define SDL_GameControllerRumble SDL_GameControllerRumble_REAL
    17.5  #define SDL_JoystickRumble SDL_JoystickRumble_REAL
    17.6  #define SDL_IsTablet SDL_IsTablet_REAL
    17.7 +#define SDL_IsTablet SDL_IsTablet_REAL
    17.8 +#define SDL_NumSensors SDL_NumSensors_REAL
    17.9 +#define SDL_SensorGetDeviceName SDL_SensorGetDeviceName_REAL
   17.10 +#define SDL_SensorGetDeviceType SDL_SensorGetDeviceType_REAL
   17.11 +#define SDL_SensorGetDeviceNonPortableType SDL_SensorGetDeviceNonPortableType_REAL
   17.12 +#define SDL_SensorGetDeviceInstanceID SDL_SensorGetDeviceInstanceID_REAL
   17.13 +#define SDL_SensorOpen SDL_SensorOpen_REAL
   17.14 +#define SDL_SensorFromInstanceID SDL_SensorFromInstanceID_REAL
   17.15 +#define SDL_SensorGetName SDL_SensorGetName_REAL
   17.16 +#define SDL_SensorGetType SDL_SensorGetType_REAL
   17.17 +#define SDL_SensorGetNonPortableType SDL_SensorGetNonPortableType_REAL
   17.18 +#define SDL_SensorGetInstanceID SDL_SensorGetInstanceID_REAL
   17.19 +#define SDL_SensorGetData SDL_SensorGetData_REAL
   17.20 +#define SDL_SensorClose SDL_SensorClose_REAL
   17.21 +#define SDL_SensorUpdate SDL_SensorUpdate_REAL
    18.1 --- a/src/dynapi/SDL_dynapi_procs.h	Tue Aug 21 11:59:13 2018 -0700
    18.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Tue Aug 21 12:11:34 2018 -0700
    18.3 @@ -725,3 +725,17 @@
    18.4  #if defined(__ANDROID__) || defined(__IPHONEOS__)
    18.5  SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return)
    18.6  #endif
    18.7 +SDL_DYNAPI_PROC(int,SDL_NumSensors,(void),(),return)
    18.8 +SDL_DYNAPI_PROC(const char*,SDL_SensorGetDeviceName,(int a),(a),return)
    18.9 +SDL_DYNAPI_PROC(SDL_SensorType,SDL_SensorGetDeviceType,(int a),(a),return)
   18.10 +SDL_DYNAPI_PROC(int,SDL_SensorGetDeviceNonPortableType,(int a),(a),return)
   18.11 +SDL_DYNAPI_PROC(SDL_SensorID,SDL_SensorGetDeviceInstanceID,(int a),(a),return)
   18.12 +SDL_DYNAPI_PROC(SDL_Sensor*,SDL_SensorOpen,(int a),(a),return)
   18.13 +SDL_DYNAPI_PROC(SDL_Sensor*,SDL_SensorFromInstanceID,(SDL_SensorID a),(a),return)
   18.14 +SDL_DYNAPI_PROC(const char*,SDL_SensorGetName,(SDL_Sensor *a),(a),return)
   18.15 +SDL_DYNAPI_PROC(SDL_SensorType,SDL_SensorGetType,(SDL_Sensor *a),(a),return)
   18.16 +SDL_DYNAPI_PROC(int,SDL_SensorGetNonPortableType,(SDL_Sensor *a),(a),return)
   18.17 +SDL_DYNAPI_PROC(SDL_SensorID,SDL_SensorGetInstanceID,(SDL_Sensor *a),(a),return)
   18.18 +SDL_DYNAPI_PROC(int,SDL_SensorGetData,(SDL_Sensor *a, float *b, int c),(a,b,c),return)
   18.19 +SDL_DYNAPI_PROC(void,SDL_SensorClose,(SDL_Sensor *a),(a),)
   18.20 +SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),)
    19.1 --- a/src/events/SDL_events.c	Tue Aug 21 11:59:13 2018 -0700
    19.2 +++ b/src/events/SDL_events.c	Tue Aug 21 12:11:34 2018 -0700
    19.3 @@ -657,6 +657,13 @@
    19.4      }
    19.5  #endif
    19.6  
    19.7 +#if !SDL_SENSOR_DISABLED
    19.8 +    /* Check for sensor state change */
    19.9 +    if (!SDL_disabled_events[SDL_SENSORUPDATE >> 8]) {
   19.10 +        SDL_SensorUpdate();
   19.11 +    }
   19.12 +#endif
   19.13 +
   19.14      SDL_SendPendingQuit();  /* in case we had a signal handler fire, etc. */
   19.15  }
   19.16  
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/sensor/SDL_sensor.c	Tue Aug 21 12:11:34 2018 -0700
    20.3 @@ -0,0 +1,548 @@
    20.4 +/*
    20.5 +  Simple DirectMedia Layer
    20.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    20.7 +
    20.8 +  This software is provided 'as-is', without any express or implied
    20.9 +  warranty.  In no event will the authors be held liable for any damages
   20.10 +  arising from the use of this software.
   20.11 +
   20.12 +  Permission is granted to anyone to use this software for any purpose,
   20.13 +  including commercial applications, and to alter it and redistribute it
   20.14 +  freely, subject to the following restrictions:
   20.15 +
   20.16 +  1. The origin of this software must not be misrepresented; you must not
   20.17 +     claim that you wrote the original software. If you use this software
   20.18 +     in a product, an acknowledgment in the product documentation would be
   20.19 +     appreciated but is not required.
   20.20 +  2. Altered source versions must be plainly marked as such, and must not be
   20.21 +     misrepresented as being the original software.
   20.22 +  3. This notice may not be removed or altered from any source distribution.
   20.23 +*/
   20.24 +#include "../SDL_internal.h"
   20.25 +
   20.26 +/* This is the sensor API for Simple DirectMedia Layer */
   20.27 +
   20.28 +#include "SDL.h"
   20.29 +#include "SDL_atomic.h"
   20.30 +#include "SDL_events.h"
   20.31 +#include "SDL_syssensor.h"
   20.32 +#include "SDL_assert.h"
   20.33 +
   20.34 +#if !SDL_EVENTS_DISABLED
   20.35 +#include "../events/SDL_events_c.h"
   20.36 +#endif
   20.37 +
   20.38 +static SDL_SensorDriver *SDL_sensor_drivers[] = {
   20.39 +#if 0 //defined(__IPHONEOS__) || defined(__TVOS__)
   20.40 +    &SDL_IOS_SensorDriver,
   20.41 +#endif
   20.42 +#ifdef SDL_SENSOR_ANDROID
   20.43 +    &SDL_ANDROID_SensorDriver,
   20.44 +#endif
   20.45 +};
   20.46 +static SDL_Sensor *SDL_sensors = NULL;
   20.47 +static SDL_bool SDL_updating_sensor = SDL_FALSE;
   20.48 +static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
   20.49 +static SDL_atomic_t SDL_next_sensor_instance_id;
   20.50 +
   20.51 +void
   20.52 +SDL_LockSensors(void)
   20.53 +{
   20.54 +    if (SDL_sensor_lock) {
   20.55 +        SDL_LockMutex(SDL_sensor_lock);
   20.56 +    }
   20.57 +}
   20.58 +
   20.59 +void
   20.60 +SDL_UnlockSensors(void)
   20.61 +{
   20.62 +    if (SDL_sensor_lock) {
   20.63 +        SDL_UnlockMutex(SDL_sensor_lock);
   20.64 +    }
   20.65 +}
   20.66 +
   20.67 +
   20.68 +int
   20.69 +SDL_SensorInit(void)
   20.70 +{
   20.71 +    int i, status;
   20.72 +
   20.73 +    /* Create the sensor list lock */
   20.74 +    if (!SDL_sensor_lock) {
   20.75 +        SDL_sensor_lock = SDL_CreateMutex();
   20.76 +    }
   20.77 +
   20.78 +#if !SDL_EVENTS_DISABLED
   20.79 +    if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {
   20.80 +        return -1;
   20.81 +    }
   20.82 +#endif /* !SDL_EVENTS_DISABLED */
   20.83 +
   20.84 +    if (SDL_arraysize(SDL_sensor_drivers) == 0) {
   20.85 +        /* What should we return here? We'll just return 0 with no sensors for now. */
   20.86 +        status = 0;
   20.87 +    }
   20.88 +
   20.89 +    status = -1;
   20.90 +    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
   20.91 +        if (SDL_sensor_drivers[i]->Init() >= 0) {
   20.92 +            status = 0;
   20.93 +        }
   20.94 +    }
   20.95 +    return status;
   20.96 +}
   20.97 +
   20.98 +/*
   20.99 + * Count the number of sensors attached to the system
  20.100 + */
  20.101 +int
  20.102 +SDL_NumSensors(void)
  20.103 +{
  20.104 +    int i, total_sensors = 0;
  20.105 +    SDL_LockSensors();
  20.106 +    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
  20.107 +        total_sensors += SDL_sensor_drivers[i]->GetCount();
  20.108 +    }
  20.109 +    SDL_UnlockSensors();
  20.110 +    return total_sensors;
  20.111 +}
  20.112 +
  20.113 +/*
  20.114 + * Return the next available sensor instance ID
  20.115 + * This may be called by drivers from multiple threads, unprotected by any locks
  20.116 + */
  20.117 +SDL_SensorID SDL_GetNextSensorInstanceID()
  20.118 +{
  20.119 +    return SDL_AtomicIncRef(&SDL_next_sensor_instance_id);
  20.120 +}
  20.121 +
  20.122 +/*
  20.123 + * Get the driver and device index for an API device index
  20.124 + * This should be called while the sensor lock is held, to prevent another thread from updating the list
  20.125 + */
  20.126 +SDL_bool
  20.127 +SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index)
  20.128 +{
  20.129 +    int i, num_sensors, total_sensors = 0;
  20.130 +
  20.131 +    if (device_index >= 0) {
  20.132 +        for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
  20.133 +            num_sensors = SDL_sensor_drivers[i]->GetCount();
  20.134 +            if (device_index < num_sensors) {
  20.135 +                *driver = SDL_sensor_drivers[i];
  20.136 +                *driver_index = device_index;
  20.137 +                return SDL_TRUE;
  20.138 +            }
  20.139 +            device_index -= num_sensors;
  20.140 +            total_sensors += num_sensors;
  20.141 +        }
  20.142 +    }
  20.143 +
  20.144 +    SDL_SetError("There are %d sensors available", total_sensors);
  20.145 +    return SDL_FALSE;
  20.146 +}
  20.147 +
  20.148 +/*
  20.149 + * Get the implementation dependent name of a sensor
  20.150 + */
  20.151 +const char *
  20.152 +SDL_SensorGetDeviceName(int device_index)
  20.153 +{
  20.154 +    SDL_SensorDriver *driver;
  20.155 +    const char *name = NULL;
  20.156 +
  20.157 +    SDL_LockSensors();
  20.158 +    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
  20.159 +        name = driver->GetDeviceName(device_index);
  20.160 +    }
  20.161 +    SDL_UnlockSensors();
  20.162 +
  20.163 +    /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
  20.164 +    return name;
  20.165 +}
  20.166 +
  20.167 +SDL_SensorType
  20.168 +SDL_SensorGetDeviceType(int device_index)
  20.169 +{
  20.170 +    SDL_SensorDriver *driver;
  20.171 +    SDL_SensorType type = SDL_SENSOR_INVALID;
  20.172 +
  20.173 +    SDL_LockSensors();
  20.174 +    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
  20.175 +        type = driver->GetDeviceType(device_index);
  20.176 +    }
  20.177 +    SDL_UnlockSensors();
  20.178 +
  20.179 +    return type;
  20.180 +}
  20.181 +
  20.182 +SDL_SensorType
  20.183 +SDL_SensorGetDeviceNonPortableType(int device_index)
  20.184 +{
  20.185 +    SDL_SensorDriver *driver;
  20.186 +    int type = -1;
  20.187 +
  20.188 +    SDL_LockSensors();
  20.189 +    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
  20.190 +        type = driver->GetDeviceNonPortableType(device_index);
  20.191 +    }
  20.192 +    SDL_UnlockSensors();
  20.193 +
  20.194 +    return type;
  20.195 +}
  20.196 +
  20.197 +SDL_SensorID
  20.198 +SDL_SensorGetDeviceInstanceID(int device_index)
  20.199 +{
  20.200 +    SDL_SensorDriver *driver;
  20.201 +    SDL_SensorID instance_id = -1;
  20.202 +
  20.203 +    SDL_LockSensors();
  20.204 +    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
  20.205 +        instance_id = driver->GetDeviceInstanceID(device_index);
  20.206 +    }
  20.207 +    SDL_UnlockSensors();
  20.208 +
  20.209 +    return instance_id;
  20.210 +}
  20.211 +
  20.212 +/*
  20.213 + * Open a sensor for use - the index passed as an argument refers to
  20.214 + * the N'th sensor on the system.  This index is the value which will
  20.215 + * identify this sensor in future sensor events.
  20.216 + *
  20.217 + * This function returns a sensor identifier, or NULL if an error occurred.
  20.218 + */
  20.219 +SDL_Sensor *
  20.220 +SDL_SensorOpen(int device_index)
  20.221 +{
  20.222 +    SDL_SensorDriver *driver;
  20.223 +    SDL_SensorID instance_id;
  20.224 +    SDL_Sensor *sensor;
  20.225 +    SDL_Sensor *sensorlist;
  20.226 +    const char *sensorname = NULL;
  20.227 +
  20.228 +    SDL_LockSensors();
  20.229 +
  20.230 +    if (!SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
  20.231 +        SDL_UnlockSensors();
  20.232 +        return NULL;
  20.233 +    }
  20.234 +
  20.235 +    sensorlist = SDL_sensors;
  20.236 +    /* If the sensor is already open, return it
  20.237 +     * it is important that we have a single sensor * for each instance id
  20.238 +     */
  20.239 +    instance_id = driver->GetDeviceInstanceID(device_index);
  20.240 +    while (sensorlist) {
  20.241 +        if (instance_id == sensorlist->instance_id) {
  20.242 +                sensor = sensorlist;
  20.243 +                ++sensor->ref_count;
  20.244 +                SDL_UnlockSensors();
  20.245 +                return sensor;
  20.246 +        }
  20.247 +        sensorlist = sensorlist->next;
  20.248 +    }
  20.249 +
  20.250 +    /* Create and initialize the sensor */
  20.251 +    sensor = (SDL_Sensor *) SDL_calloc(sizeof(*sensor), 1);
  20.252 +    if (sensor == NULL) {
  20.253 +        SDL_OutOfMemory();
  20.254 +        SDL_UnlockSensors();
  20.255 +        return NULL;
  20.256 +    }
  20.257 +    sensor->driver = driver;
  20.258 +    sensor->instance_id = instance_id;
  20.259 +    sensor->type = driver->GetDeviceType(device_index);
  20.260 +    sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);
  20.261 +
  20.262 +    if (driver->Open(sensor, device_index) < 0) {
  20.263 +        SDL_free(sensor);
  20.264 +        SDL_UnlockSensors();
  20.265 +        return NULL;
  20.266 +    }
  20.267 +
  20.268 +    sensorname = driver->GetDeviceName(device_index);
  20.269 +    if (sensorname) {
  20.270 +        sensor->name = SDL_strdup(sensorname);
  20.271 +    } else {
  20.272 +        sensor->name = NULL;
  20.273 +    }
  20.274 +
  20.275 +    /* Add sensor to list */
  20.276 +    ++sensor->ref_count;
  20.277 +    /* Link the sensor in the list */
  20.278 +    sensor->next = SDL_sensors;
  20.279 +    SDL_sensors = sensor;
  20.280 +
  20.281 +    SDL_UnlockSensors();
  20.282 +
  20.283 +    driver->Update(sensor);
  20.284 +
  20.285 +    return sensor;
  20.286 +}
  20.287 +
  20.288 +/*
  20.289 + * Find the SDL_Sensor that owns this instance id
  20.290 + */
  20.291 +SDL_Sensor *
  20.292 +SDL_SensorFromInstanceID(SDL_SensorID instance_id)
  20.293 +{
  20.294 +    SDL_Sensor *sensor;
  20.295 +
  20.296 +    SDL_LockSensors();
  20.297 +    for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
  20.298 +        if (sensor->instance_id == instance_id) {
  20.299 +            break;
  20.300 +        }
  20.301 +    }
  20.302 +    SDL_UnlockSensors();
  20.303 +    return sensor;
  20.304 +}
  20.305 +
  20.306 +/*
  20.307 + * Checks to make sure the sensor is valid.
  20.308 + */
  20.309 +static int
  20.310 +SDL_PrivateSensorValid(SDL_Sensor * sensor)
  20.311 +{
  20.312 +    int valid;
  20.313 +
  20.314 +    if (sensor == NULL) {
  20.315 +        SDL_SetError("Sensor hasn't been opened yet");
  20.316 +        valid = 0;
  20.317 +    } else {
  20.318 +        valid = 1;
  20.319 +    }
  20.320 +
  20.321 +    return valid;
  20.322 +}
  20.323 +
  20.324 +/*
  20.325 + * Get the friendly name of this sensor
  20.326 + */
  20.327 +const char *
  20.328 +SDL_SensorGetName(SDL_Sensor * sensor)
  20.329 +{
  20.330 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.331 +        return NULL;
  20.332 +    }
  20.333 +
  20.334 +    return sensor->name;
  20.335 +}
  20.336 +
  20.337 +/*
  20.338 + * Get the type of this sensor
  20.339 + */
  20.340 +SDL_SensorType
  20.341 +SDL_SensorGetType(SDL_Sensor * sensor)
  20.342 +{
  20.343 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.344 +        return SDL_SENSOR_INVALID;
  20.345 +    }
  20.346 +
  20.347 +    return sensor->type;
  20.348 +}
  20.349 +
  20.350 +/*
  20.351 + * Get the platform dependent type of this sensor
  20.352 + */
  20.353 +int
  20.354 +SDL_SensorGetNonPortableType(SDL_Sensor * sensor)
  20.355 +{
  20.356 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.357 +        return -1;
  20.358 +    }
  20.359 +
  20.360 +    return sensor->non_portable_type;
  20.361 +}
  20.362 +
  20.363 +/*
  20.364 + * Get the instance id for this opened sensor
  20.365 + */
  20.366 +SDL_SensorID
  20.367 +SDL_SensorGetInstanceID(SDL_Sensor * sensor)
  20.368 +{
  20.369 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.370 +        return -1;
  20.371 +    }
  20.372 +
  20.373 +    return sensor->instance_id;
  20.374 +}
  20.375 +
  20.376 +/*
  20.377 + * Get the current state of this sensor
  20.378 + */
  20.379 +int
  20.380 +SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values)
  20.381 +{
  20.382 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.383 +        return -1;
  20.384 +    }
  20.385 +
  20.386 +    num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
  20.387 +    SDL_memcpy(data, sensor->data, num_values*sizeof(*data));
  20.388 +    return 0;
  20.389 +}
  20.390 +
  20.391 +/*
  20.392 + * Close a sensor previously opened with SDL_SensorOpen()
  20.393 + */
  20.394 +void
  20.395 +SDL_SensorClose(SDL_Sensor * sensor)
  20.396 +{
  20.397 +    SDL_Sensor *sensorlist;
  20.398 +    SDL_Sensor *sensorlistprev;
  20.399 +
  20.400 +    if (!SDL_PrivateSensorValid(sensor)) {
  20.401 +        return;
  20.402 +    }
  20.403 +
  20.404 +    SDL_LockSensors();
  20.405 +
  20.406 +    /* First decrement ref count */
  20.407 +    if (--sensor->ref_count > 0) {
  20.408 +        SDL_UnlockSensors();
  20.409 +        return;
  20.410 +    }
  20.411 +
  20.412 +    if (SDL_updating_sensor) {
  20.413 +        SDL_UnlockSensors();
  20.414 +        return;
  20.415 +    }
  20.416 +
  20.417 +    sensor->driver->Close(sensor);
  20.418 +    sensor->hwdata = NULL;
  20.419 +
  20.420 +    sensorlist = SDL_sensors;
  20.421 +    sensorlistprev = NULL;
  20.422 +    while (sensorlist) {
  20.423 +        if (sensor == sensorlist) {
  20.424 +            if (sensorlistprev) {
  20.425 +                /* unlink this entry */
  20.426 +                sensorlistprev->next = sensorlist->next;
  20.427 +            } else {
  20.428 +                SDL_sensors = sensor->next;
  20.429 +            }
  20.430 +            break;
  20.431 +        }
  20.432 +        sensorlistprev = sensorlist;
  20.433 +        sensorlist = sensorlist->next;
  20.434 +    }
  20.435 +
  20.436 +    SDL_free(sensor->name);
  20.437 +
  20.438 +    /* Free the data associated with this sensor */
  20.439 +    SDL_free(sensor);
  20.440 +
  20.441 +    SDL_UnlockSensors();
  20.442 +}
  20.443 +
  20.444 +void
  20.445 +SDL_SensorQuit(void)
  20.446 +{
  20.447 +    int i;
  20.448 +
  20.449 +    /* Make sure we're not getting called in the middle of updating sensors */
  20.450 +    SDL_assert(!SDL_updating_sensor);
  20.451 +
  20.452 +    SDL_LockSensors();
  20.453 +
  20.454 +    /* Stop the event polling */
  20.455 +    while (SDL_sensors) {
  20.456 +        SDL_sensors->ref_count = 1;
  20.457 +        SDL_SensorClose(SDL_sensors);
  20.458 +    }
  20.459 +
  20.460 +    /* Quit the sensor setup */
  20.461 +    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
  20.462 +       SDL_sensor_drivers[i]->Quit();
  20.463 +    }
  20.464 +
  20.465 +    SDL_UnlockSensors();
  20.466 +
  20.467 +#if !SDL_EVENTS_DISABLED
  20.468 +    SDL_QuitSubSystem(SDL_INIT_EVENTS);
  20.469 +#endif
  20.470 +
  20.471 +    if (SDL_sensor_lock) {
  20.472 +        SDL_DestroyMutex(SDL_sensor_lock);
  20.473 +        SDL_sensor_lock = NULL;
  20.474 +    }
  20.475 +}
  20.476 +
  20.477 +
  20.478 +/* These are global for SDL_syssensor.c and SDL_events.c */
  20.479 +
  20.480 +int
  20.481 +SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values)
  20.482 +{
  20.483 +    int posted;
  20.484 +
  20.485 +    /* Allow duplicate events, for things like steps and heartbeats */
  20.486 +
  20.487 +    /* Update internal sensor state */
  20.488 +    num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
  20.489 +    SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
  20.490 +
  20.491 +    /* Post the event, if desired */
  20.492 +    posted = 0;
  20.493 +#if !SDL_EVENTS_DISABLED
  20.494 +    if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) {
  20.495 +        SDL_Event event;
  20.496 +        event.type = SDL_SENSORUPDATE;
  20.497 +        event.sensor.which = sensor->instance_id;
  20.498 +        num_values = SDL_min(num_values, SDL_arraysize(event.sensor.data));
  20.499 +        SDL_memset(event.sensor.data, 0, sizeof(event.sensor.data));
  20.500 +        SDL_memcpy(event.sensor.data, data, num_values*sizeof(*data));
  20.501 +        posted = SDL_PushEvent(&event) == 1;
  20.502 +    }
  20.503 +#endif /* !SDL_EVENTS_DISABLED */
  20.504 +    return posted;
  20.505 +}
  20.506 +
  20.507 +void
  20.508 +SDL_SensorUpdate(void)
  20.509 +{
  20.510 +    int i;
  20.511 +    SDL_Sensor *sensor;
  20.512 +
  20.513 +    SDL_LockSensors();
  20.514 +
  20.515 +    if (SDL_updating_sensor) {
  20.516 +        /* The sensors are already being updated */
  20.517 +        SDL_UnlockSensors();
  20.518 +        return;
  20.519 +    }
  20.520 +
  20.521 +    SDL_updating_sensor = SDL_TRUE;
  20.522 +
  20.523 +    /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
  20.524 +    SDL_UnlockSensors();
  20.525 +
  20.526 +    for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
  20.527 +        sensor->driver->Update(sensor);
  20.528 +    }
  20.529 +
  20.530 +    SDL_LockSensors();
  20.531 +
  20.532 +    SDL_updating_sensor = SDL_FALSE;
  20.533 +
  20.534 +    /* If any sensors were closed while updating, free them here */
  20.535 +    for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
  20.536 +        if (sensor->ref_count <= 0) {
  20.537 +            SDL_SensorClose(sensor);
  20.538 +        }
  20.539 +    }
  20.540 +
  20.541 +    /* this needs to happen AFTER walking the sensor list above, so that any
  20.542 +       dangling hardware data from removed devices can be free'd
  20.543 +     */
  20.544 +    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
  20.545 +        SDL_sensor_drivers[i]->Detect();
  20.546 +    }
  20.547 +
  20.548 +    SDL_UnlockSensors();
  20.549 +}
  20.550 +
  20.551 +/* vi: set ts=4 sw=4 expandtab: */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/sensor/SDL_sensor_c.h	Tue Aug 21 12:11:34 2018 -0700
    21.3 @@ -0,0 +1,38 @@
    21.4 +/*
    21.5 +  Simple DirectMedia Layer
    21.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    21.7 +
    21.8 +  This software is provided 'as-is', without any express or implied
    21.9 +  warranty.  In no event will the authors be held liable for any damages
   21.10 +  arising from the use of this software.
   21.11 +
   21.12 +  Permission is granted to anyone to use this software for any purpose,
   21.13 +  including commercial applications, and to alter it and redistribute it
   21.14 +  freely, subject to the following restrictions:
   21.15 +
   21.16 +  1. The origin of this software must not be misrepresented; you must not
   21.17 +     claim that you wrote the original software. If you use this software
   21.18 +     in a product, an acknowledgment in the product documentation would be
   21.19 +     appreciated but is not required.
   21.20 +  2. Altered source versions must be plainly marked as such, and must not be
   21.21 +     misrepresented as being the original software.
   21.22 +  3. This notice may not be removed or altered from any source distribution.
   21.23 +*/
   21.24 +#include "SDL_config.h"
   21.25 +
   21.26 +struct _SDL_SensorDriver;
   21.27 +
   21.28 +/* Useful functions and variables from SDL_sensor.c */
   21.29 +#include "SDL_sensor.h"
   21.30 +
   21.31 +/* Function to get the next available sensor instance ID */
   21.32 +extern SDL_SensorID SDL_GetNextSensorInstanceID(void);
   21.33 +
   21.34 +/* Initialization and shutdown functions */
   21.35 +extern int SDL_SensorInit(void);
   21.36 +extern void SDL_SensorQuit(void);
   21.37 +
   21.38 +/* Internal event queueing functions */
   21.39 +extern int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values);
   21.40 +
   21.41 +/* vi: set ts=4 sw=4 expandtab: */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/sensor/SDL_syssensor.h	Tue Aug 21 12:11:34 2018 -0700
    22.3 @@ -0,0 +1,97 @@
    22.4 +/*
    22.5 +  Simple DirectMedia Layer
    22.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    22.7 +
    22.8 +  This software is provided 'as-is', without any express or implied
    22.9 +  warranty.  In no event will the authors be held liable for any damages
   22.10 +  arising from the use of this software.
   22.11 +
   22.12 +  Permission is granted to anyone to use this software for any purpose,
   22.13 +  including commercial applications, and to alter it and redistribute it
   22.14 +  freely, subject to the following restrictions:
   22.15 +
   22.16 +  1. The origin of this software must not be misrepresented; you must not
   22.17 +     claim that you wrote the original software. If you use this software
   22.18 +     in a product, an acknowledgment in the product documentation would be
   22.19 +     appreciated but is not required.
   22.20 +  2. Altered source versions must be plainly marked as such, and must not be
   22.21 +     misrepresented as being the original software.
   22.22 +  3. This notice may not be removed or altered from any source distribution.
   22.23 +*/
   22.24 +#include "SDL_config.h"
   22.25 +
   22.26 +/* This is the system specific header for the SDL sensor API */
   22.27 +
   22.28 +#include "SDL_sensor.h"
   22.29 +#include "SDL_sensor_c.h"
   22.30 +
   22.31 +/* The SDL sensor structure */
   22.32 +struct _SDL_Sensor
   22.33 +{
   22.34 +    SDL_SensorID instance_id;       /* Device instance, monotonically increasing from 0 */
   22.35 +    char *name;                     /* Sensor name - system dependent */
   22.36 +    SDL_SensorType type;            /* Type of the sensor */
   22.37 +    int non_portable_type;          /* Platform dependent type of the sensor */
   22.38 +
   22.39 +    float data[16];                 /* The current state of the sensor */
   22.40 +
   22.41 +    struct _SDL_SensorDriver *driver;
   22.42 +
   22.43 +    struct sensor_hwdata *hwdata;   /* Driver dependent information */
   22.44 +
   22.45 +    int ref_count;                  /* Reference count for multiple opens */
   22.46 +
   22.47 +    struct _SDL_Sensor *next;       /* pointer to next sensor we have allocated */
   22.48 +};
   22.49 +
   22.50 +typedef struct _SDL_SensorDriver
   22.51 +{
   22.52 +    /* Function to scan the system for sensors.
   22.53 +     * sensor 0 should be the system default sensor.
   22.54 +     * This function should return 0, or -1 on an unrecoverable fatal error.
   22.55 +     */
   22.56 +    int (*Init)(void);
   22.57 +
   22.58 +    /* Function to return the number of sensors available right now */
   22.59 +    int (*GetCount)(void);
   22.60 +
   22.61 +    /* Function to check to see if the available sensors have changed */
   22.62 +    void (*Detect)(void);
   22.63 +
   22.64 +    /* Function to get the device-dependent name of a sensor */
   22.65 +    const char *(*GetDeviceName)(int device_index);
   22.66 +
   22.67 +    /* Function to get the type of a sensor */
   22.68 +    SDL_SensorType (*GetDeviceType)(int device_index);
   22.69 +
   22.70 +    /* Function to get the platform dependent type of a sensor */
   22.71 +    int (*GetDeviceNonPortableType)(int device_index);
   22.72 +
   22.73 +    /* Function to get the current instance id of the sensor located at device_index */
   22.74 +    SDL_SensorID (*GetDeviceInstanceID)(int device_index);
   22.75 +
   22.76 +    /* Function to open a sensor for use.
   22.77 +       The sensor to open is specified by the device index.
   22.78 +       It returns 0, or -1 if there is an error.
   22.79 +     */
   22.80 +    int (*Open)(SDL_Sensor * sensor, int device_index);
   22.81 +
   22.82 +    /* Function to update the state of a sensor - called as a device poll.
   22.83 +     * This function shouldn't update the sensor structure directly,
   22.84 +     * but instead should call SDL_PrivateSensorUpdate() to deliver events
   22.85 +     * and update sensor device state.
   22.86 +     */
   22.87 +    void (*Update)(SDL_Sensor * sensor);
   22.88 +
   22.89 +    /* Function to close a sensor after use */
   22.90 +    void (*Close)(SDL_Sensor * sensor);
   22.91 +
   22.92 +    /* Function to perform any system-specific sensor related cleanup */
   22.93 +    void (*Quit)(void);
   22.94 +
   22.95 +} SDL_SensorDriver;
   22.96 +
   22.97 +/* The available sensor drivers */
   22.98 +extern SDL_SensorDriver SDL_ANDROID_SensorDriver;
   22.99 +
  22.100 +/* vi: set ts=4 sw=4 expandtab: */
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/sensor/android/SDL_androidsensor.c	Tue Aug 21 12:11:34 2018 -0700
    23.3 @@ -0,0 +1,211 @@
    23.4 +/*
    23.5 +  Simple DirectMedia Layer
    23.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    23.7 +
    23.8 +  This software is provided 'as-is', without any express or implied
    23.9 +  warranty.  In no event will the authors be held liable for any damages
   23.10 +  arising from the use of this software.
   23.11 +
   23.12 +  Permission is granted to anyone to use this software for any purpose,
   23.13 +  including commercial applications, and to alter it and redistribute it
   23.14 +  freely, subject to the following restrictions:
   23.15 +
   23.16 +  1. The origin of this software must not be misrepresented; you must not
   23.17 +     claim that you wrote the original software. If you use this software
   23.18 +     in a product, an acknowledgment in the product documentation would be
   23.19 +     appreciated but is not required.
   23.20 +  2. Altered source versions must be plainly marked as such, and must not be
   23.21 +     misrepresented as being the original software.
   23.22 +  3. This notice may not be removed or altered from any source distribution.
   23.23 +*/
   23.24 +
   23.25 +#include "SDL_config.h"
   23.26 +
   23.27 +#ifdef SDL_SENSOR_ANDROID
   23.28 +
   23.29 +/* This is the system specific header for the SDL sensor API */
   23.30 +#include <android/sensor.h>
   23.31 +
   23.32 +#include "SDL_error.h"
   23.33 +#include "SDL_sensor.h"
   23.34 +#include "SDL_androidsensor.h"
   23.35 +#include "../SDL_syssensor.h"
   23.36 +#include "../SDL_sensor_c.h"
   23.37 +//#include "../../core/android/SDL_android.h"
   23.38 +
   23.39 +#ifndef LOOPER_ID_USER
   23.40 +#define LOOPER_ID_USER  3
   23.41 +#endif
   23.42 +
   23.43 +typedef struct
   23.44 +{
   23.45 +    ASensorRef asensor;
   23.46 +    SDL_SensorID instance_id;
   23.47 +} SDL_AndroidSensor;
   23.48 +
   23.49 +static ASensorManager* SDL_sensor_manager;
   23.50 +static ALooper* SDL_sensor_looper;
   23.51 +static SDL_AndroidSensor *SDL_sensors;
   23.52 +static int SDL_sensors_count;
   23.53 +
   23.54 +static int
   23.55 +SDL_ANDROID_SensorInit(void)
   23.56 +{
   23.57 +    int i, sensors_count;
   23.58 +    ASensorList sensors;
   23.59 +
   23.60 +    SDL_sensor_manager = ASensorManager_getInstance();
   23.61 +    if (!SDL_sensor_manager) {
   23.62 +        return SDL_SetError("Couldn't create sensor manager");
   23.63 +    }
   23.64 +
   23.65 +    SDL_sensor_looper = ALooper_forThread();
   23.66 +    if (!SDL_sensor_looper) {
   23.67 +        SDL_sensor_looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
   23.68 +        if (!SDL_sensor_looper) {
   23.69 +            return SDL_SetError("Couldn't create sensor event loop");
   23.70 +        }
   23.71 +    }
   23.72 +
   23.73 +    /* FIXME: Is the sensor list dynamic? */
   23.74 +    sensors_count = ASensorManager_getSensorList(SDL_sensor_manager, &sensors);
   23.75 +    if (sensors_count > 0) {
   23.76 +        SDL_sensors = (SDL_AndroidSensor *)SDL_calloc(sensors_count, sizeof(*SDL_sensors));
   23.77 +        if (!SDL_sensors) {
   23.78 +            return SDL_OutOfMemory();
   23.79 +        }
   23.80 +
   23.81 +        for (i = 0; i < sensors_count; ++i) {
   23.82 +            SDL_sensors[i].asensor = sensors[i];
   23.83 +            SDL_sensors[i].instance_id = SDL_GetNextSensorInstanceID();
   23.84 +        }
   23.85 +        SDL_sensors_count = sensors_count;
   23.86 +    }
   23.87 +    return 0;
   23.88 +}
   23.89 +
   23.90 +static int
   23.91 +SDL_ANDROID_SensorGetCount(void)
   23.92 +{
   23.93 +    return SDL_sensors_count;
   23.94 +}
   23.95 +
   23.96 +static void
   23.97 +SDL_ANDROID_SensorDetect(void)
   23.98 +{
   23.99 +}
  23.100 +
  23.101 +static const char *
  23.102 +SDL_ANDROID_SensorGetDeviceName(int device_index)
  23.103 +{
  23.104 +    return ASensor_getName(SDL_sensors[device_index].asensor);
  23.105 +}
  23.106 +
  23.107 +static SDL_SensorType
  23.108 +SDL_ANDROID_SensorGetDeviceType(int device_index)
  23.109 +{
  23.110 +    switch (ASensor_getType(SDL_sensors[device_index].asensor)) {
  23.111 +    case 0x00000001:
  23.112 +        return SDL_SENSOR_ACCEL;
  23.113 +    case 0x00000004:
  23.114 +        return SDL_SENSOR_GYRO;
  23.115 +    default:
  23.116 +        return SDL_SENSOR_UNKNOWN;
  23.117 +    }
  23.118 +}
  23.119 +
  23.120 +static int
  23.121 +SDL_ANDROID_SensorGetDeviceNonPortableType(int device_index)
  23.122 +{
  23.123 +    return ASensor_getType(SDL_sensors[device_index].asensor);
  23.124 +}
  23.125 +
  23.126 +static SDL_SensorID
  23.127 +SDL_ANDROID_SensorGetDeviceInstanceID(int device_index)
  23.128 +{
  23.129 +    return SDL_sensors[device_index].instance_id;
  23.130 +}
  23.131 +
  23.132 +static int
  23.133 +SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index)
  23.134 +{
  23.135 +    struct sensor_hwdata *hwdata;
  23.136 +
  23.137 +    hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata));
  23.138 +    if (hwdata == NULL) {
  23.139 +        return SDL_OutOfMemory();
  23.140 +    }
  23.141 +
  23.142 +    hwdata->asensor = SDL_sensors[device_index].asensor;
  23.143 +    hwdata->eventqueue = ASensorManager_createEventQueue(SDL_sensor_manager, SDL_sensor_looper, LOOPER_ID_USER, NULL, NULL);
  23.144 +    if (!hwdata->eventqueue) {
  23.145 +        SDL_free(hwdata);
  23.146 +        return SDL_SetError("Couldn't create sensor event queue");
  23.147 +    }
  23.148 +
  23.149 +    if (ASensorEventQueue_enableSensor(hwdata->eventqueue, hwdata->asensor) < 0) {
  23.150 +        ASensorManager_destroyEventQueue(SDL_sensor_manager, hwdata->eventqueue);
  23.151 +        SDL_free(hwdata);
  23.152 +        return SDL_SetError("Couldn't enable sensor");
  23.153 +    }
  23.154 +
  23.155 +    /* FIXME: What rate should we set for this sensor? 60 FPS? Let's try the default rate for now... */
  23.156 +
  23.157 +    sensor->hwdata = hwdata;
  23.158 +    return 0;
  23.159 +}
  23.160 +    
  23.161 +static void
  23.162 +SDL_ANDROID_SensorUpdate(SDL_Sensor* sensor)
  23.163 +{
  23.164 +    int events;
  23.165 +    ASensorEvent event;
  23.166 +    struct android_poll_source* source;
  23.167 +
  23.168 +    if (ALooper_pollAll(0, NULL, &events, (void**)&source) == LOOPER_ID_USER) {
  23.169 +        SDL_zero(event);
  23.170 +        while (ASensorEventQueue_getEvents(sensor->hwdata->eventqueue, &event, 1) > 0) {
  23.171 +            SDL_PrivateSensorUpdate(sensor, event.data, SDL_arraysize(event.data));
  23.172 +        }
  23.173 +    }
  23.174 +}
  23.175 +
  23.176 +static void
  23.177 +SDL_ANDROID_SensorClose(SDL_Sensor * sensor)
  23.178 +{
  23.179 +    if (sensor->hwdata) {
  23.180 +        ASensorEventQueue_disableSensor(sensor->hwdata->eventqueue, sensor->hwdata->asensor);
  23.181 +        ASensorManager_destroyEventQueue(SDL_sensor_manager, sensor->hwdata->eventqueue);
  23.182 +        SDL_free(sensor->hwdata);
  23.183 +        sensor->hwdata = NULL;
  23.184 +    }
  23.185 +}
  23.186 +
  23.187 +static void
  23.188 +SDL_ANDROID_SensorQuit(void)
  23.189 +{
  23.190 +    if (SDL_sensors) {
  23.191 +        SDL_free(SDL_sensors);
  23.192 +        SDL_sensors = NULL;
  23.193 +        SDL_sensors_count = 0;
  23.194 +    }
  23.195 +}
  23.196 +
  23.197 +SDL_SensorDriver SDL_ANDROID_SensorDriver =
  23.198 +{
  23.199 +    SDL_ANDROID_SensorInit,
  23.200 +    SDL_ANDROID_SensorGetCount,
  23.201 +    SDL_ANDROID_SensorDetect,
  23.202 +    SDL_ANDROID_SensorGetDeviceName,
  23.203 +    SDL_ANDROID_SensorGetDeviceType,
  23.204 +    SDL_ANDROID_SensorGetDeviceNonPortableType,
  23.205 +    SDL_ANDROID_SensorGetDeviceInstanceID,
  23.206 +    SDL_ANDROID_SensorOpen,
  23.207 +    SDL_ANDROID_SensorUpdate,
  23.208 +    SDL_ANDROID_SensorClose,
  23.209 +    SDL_ANDROID_SensorQuit,
  23.210 +};
  23.211 +
  23.212 +#endif /* SDL_SENSOR_ANDROID */
  23.213 +
  23.214 +/* vi: set ts=4 sw=4 expandtab: */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/sensor/android/SDL_androidsensor.h	Tue Aug 21 12:11:34 2018 -0700
    24.3 @@ -0,0 +1,31 @@
    24.4 +/*
    24.5 +  Simple DirectMedia Layer
    24.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    24.7 +
    24.8 +  This software is provided 'as-is', without any express or implied
    24.9 +  warranty.  In no event will the authors be held liable for any damages
   24.10 +  arising from the use of this software.
   24.11 +
   24.12 +  Permission is granted to anyone to use this software for any purpose,
   24.13 +  including commercial applications, and to alter it and redistribute it
   24.14 +  freely, subject to the following restrictions:
   24.15 +
   24.16 +  1. The origin of this software must not be misrepresented; you must not
   24.17 +     claim that you wrote the original software. If you use this software
   24.18 +     in a product, an acknowledgment in the product documentation would be
   24.19 +     appreciated but is not required.
   24.20 +  2. Altered source versions must be plainly marked as such, and must not be
   24.21 +     misrepresented as being the original software.
   24.22 +  3. This notice may not be removed or altered from any source distribution.
   24.23 +*/
   24.24 +#include "SDL_config.h"
   24.25 +
   24.26 +/* The private structure used to keep track of a sensor */
   24.27 +struct sensor_hwdata
   24.28 +{
   24.29 +    ASensorRef asensor;
   24.30 +    ASensorEventQueue *eventqueue;
   24.31 +};
   24.32 +
   24.33 +
   24.34 +/* vi: set ts=4 sw=4 expandtab: */
    25.1 --- a/test/Makefile.in	Tue Aug 21 11:59:13 2018 -0700
    25.2 +++ b/test/Makefile.in	Tue Aug 21 12:11:34 2018 -0700
    25.3 @@ -55,6 +55,7 @@
    25.4  	testrumble$(EXE) \
    25.5  	testscale$(EXE) \
    25.6  	testsem$(EXE) \
    25.7 +	testsensor$(EXE) \
    25.8  	testshader$(EXE) \
    25.9  	testshape$(EXE) \
   25.10  	testsprite2$(EXE) \
   25.11 @@ -240,6 +241,9 @@
   25.12  testsem$(EXE): $(srcdir)/testsem.c
   25.13  	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
   25.14  
   25.15 +testsensor$(EXE): $(srcdir)/testsensor.c
   25.16 +	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
   25.17 +
   25.18  testshader$(EXE): $(srcdir)/testshader.c
   25.19  	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
   25.20  
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/test/testsensor.c	Tue Aug 21 12:11:34 2018 -0700
    26.3 @@ -0,0 +1,117 @@
    26.4 +/*
    26.5 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
    26.6 +
    26.7 +  This software is provided 'as-is', without any express or implied
    26.8 +  warranty.  In no event will the authors be held liable for any damages
    26.9 +  arising from the use of this software.
   26.10 +
   26.11 +  Permission is granted to anyone to use this software for any purpose,
   26.12 +  including commercial applications, and to alter it and redistribute it
   26.13 +  freely.
   26.14 +*/
   26.15 +
   26.16 +/* Simple test of the SDL sensor code */
   26.17 +
   26.18 +#include "SDL.h"
   26.19 +
   26.20 +static const char *GetSensorTypeString(SDL_SensorType type)
   26.21 +{
   26.22 +    static char unknown_type[64];
   26.23 +
   26.24 +    switch (type)
   26.25 +    {
   26.26 +    case SDL_SENSOR_INVALID:
   26.27 +        return "SDL_SENSOR_INVALID";
   26.28 +    case SDL_SENSOR_UNKNOWN:
   26.29 +        return "SDL_SENSOR_UNKNOWN";
   26.30 +    case SDL_SENSOR_ACCEL:
   26.31 +        return "SDL_SENSOR_ACCEL";
   26.32 +    case SDL_SENSOR_GYRO:
   26.33 +        return "SDL_SENSOR_GYRO";
   26.34 +    default:
   26.35 +        SDL_snprintf(unknown_type, sizeof(unknown_type), "UNKNOWN (%d)", type);
   26.36 +        return unknown_type;
   26.37 +    }
   26.38 +}
   26.39 +
   26.40 +static void HandleSensorEvent(SDL_SensorEvent *event)
   26.41 +{
   26.42 +    SDL_Sensor *sensor = SDL_SensorFromInstanceID(event->which);
   26.43 +    if (!sensor) {
   26.44 +        SDL_Log("Couldn't get sensor for sensor event\n");
   26.45 +        return;
   26.46 +    }
   26.47 +
   26.48 +    switch (SDL_SensorGetType(sensor)) {
   26.49 +    case SDL_SENSOR_ACCEL:
   26.50 +        SDL_Log("Accelerometer update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]);
   26.51 +        break;
   26.52 +    case SDL_SENSOR_GYRO:
   26.53 +        SDL_Log("Gyro update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]);
   26.54 +        break;
   26.55 +    default:
   26.56 +        SDL_Log("Sensor update for sensor type %s\n", GetSensorTypeString(SDL_SensorGetType(sensor)));
   26.57 +        break;
   26.58 +    }
   26.59 +}
   26.60 +
   26.61 +int
   26.62 +main(int argc, char **argv)
   26.63 +{
   26.64 +    int i;
   26.65 +    int num_sensors, num_opened;
   26.66 +
   26.67 +    /* Load the SDL library */
   26.68 +    if (SDL_Init(SDL_INIT_SENSOR) < 0) {
   26.69 +        SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError());
   26.70 +        return (1);
   26.71 +    }
   26.72 +
   26.73 +    num_sensors = SDL_NumSensors();
   26.74 +    num_opened = 0;
   26.75 +
   26.76 +    SDL_Log("There are %d sensors available\n", num_sensors);
   26.77 +    for (i = 0; i < num_sensors; ++i) {
   26.78 +        SDL_Log("Sensor %d: %s, type %s, platform type %d\n",
   26.79 +            SDL_SensorGetDeviceInstanceID(i),
   26.80 +            SDL_SensorGetDeviceName(i),
   26.81 +            GetSensorTypeString(SDL_SensorGetDeviceType(i)),
   26.82 +            SDL_SensorGetDeviceNonPortableType(i));
   26.83 +
   26.84 +        if (SDL_SensorGetDeviceType(i) != SDL_SENSOR_UNKNOWN) {
   26.85 +            SDL_Sensor *sensor = SDL_SensorOpen(i);
   26.86 +            if (sensor == NULL) {
   26.87 +                SDL_Log("Couldn't open sensor %d: %s\n", SDL_SensorGetDeviceInstanceID(i), SDL_GetError());
   26.88 +            } else {
   26.89 +                ++num_opened;
   26.90 +            }
   26.91 +        }
   26.92 +    }
   26.93 +    SDL_Log("Opened %d sensors\n", num_opened);
   26.94 +
   26.95 +    if (num_opened > 0) {
   26.96 +        SDL_bool done = SDL_FALSE;
   26.97 +        SDL_Event event;
   26.98 +
   26.99 +        SDL_CreateWindow("Sensor Test", 0, 0, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
  26.100 +        while (!done) {
  26.101 +            while (SDL_PollEvent(&event) > 0) {
  26.102 +                switch (event.type) {
  26.103 +                case SDL_SENSORUPDATE:
  26.104 +                    HandleSensorEvent(&event.sensor);
  26.105 +                    break;
  26.106 +                case SDL_MOUSEBUTTONUP:
  26.107 +                case SDL_KEYUP:
  26.108 +                case SDL_QUIT:
  26.109 +                    done = SDL_TRUE;
  26.110 +                    break;
  26.111 +                default:
  26.112 +                    break;
  26.113 +                }
  26.114 +            }
  26.115 +        }
  26.116 +    }
  26.117 +
  26.118 +    SDL_Quit();
  26.119 +    return (0);
  26.120 +}