Permalink
Browse files

Merge pull request #83 from Psychtoolbox-3/master

BETA RELEASE "Dancersizing, Grey & Hopeless"

"Dancersizing, Grey & Hopeless" mostly fixes small bugs, improves small details and improves GetChar support on Windows Vista+, matlab -nojvm and octave.

* GetChar, CharAvail, FlushEvents and ListenChar now (ab)use keyboard queue functionality on setups where use of Java based GetChar et al. is ineffective or impossible: This should enable good support for Windows Vista/7/8, matlab in -nojvm mode, and GNU/Octave in CLI and GUI mode.

* Minor fixes and improvements to PsychPortAudio, Screen, IOPort, PsychGPUControl and M-Files.

* CRS OptiCal support by Andreas Widmann.
  • Loading branch information...
kleinerm committed Nov 11, 2012
2 parents 759f023 + 76714f3 commit 9b5c690196bb818107414eba2fa96f3be2170dd7
Showing with 2,293 additions and 470 deletions.
  1. +1 −1 PsychSourceGL/Cohorts/FTGLTextRenderer/libptbdrawtext_ftgl.cpp
  2. +27 −0 PsychSourceGL/Cohorts/FTGLTextRenderer/linuxexportlist.txt
  3. +1 −1 PsychSourceGL/Cohorts/PsychtoolboxOSXKernelDriver/PsychtoolboxKernelDriver.cpp
  4. +6 −0 PsychSourceGL/Projects/MacOSX/PsychToolbox/PsychToolbox64.xcodeproj/project.pbxproj
  5. +16 −2 PsychSourceGL/Source/Common/Base/PsychScriptingGlue.cc
  6. +14 −2 PsychSourceGL/Source/Common/IOPort/PsychSerialUnixGlue.c
  7. +3 −1 PsychSourceGL/Source/Common/PsychHID/PsychHID.h
  8. +45 −2 PsychSourceGL/Source/Common/PsychHID/PsychHIDGetDevices.c
  9. +25 −2 PsychSourceGL/Source/Common/PsychHID/PsychHIDHelpers.c
  10. +94 −21 PsychSourceGL/Source/Common/PsychHID/PsychHIDKbQueueCreate.c
  11. +5 −1 PsychSourceGL/Source/Common/PsychHID/PsychHIDKbQueueFlush.c
  12. +5 −1 PsychSourceGL/Source/Common/PsychHID/PsychHIDKbQueueRelease.c
  13. +3 −0 PsychSourceGL/Source/Common/PsychHID/PsychHIDKbQueueStart.c
  14. +446 −0 PsychSourceGL/Source/Common/PsychHID/PsychHIDKeyboardHelper.c
  15. +3 −0 PsychSourceGL/Source/Common/PsychHID/PsychHIDSynopsis.c
  16. +1 −0 PsychSourceGL/Source/Common/PsychHID/RegisterProject.c
  17. +15 −2 PsychSourceGL/Source/Common/PsychPortAudio/PsychPortAudio.c
  18. +6 −3 PsychSourceGL/Source/Common/Screen/PsychVideoCaptureSupportGStreamer.c
  19. +64 −2 PsychSourceGL/Source/Common/Screen/RegisterProject.c
  20. +3 −0 PsychSourceGL/Source/Common/Screen/SCREENCloseAll.c
  21. +81 −34 PsychSourceGL/Source/Common/Screen/SCREENGetMouseHelper.c
  22. +14 −0 PsychSourceGL/Source/Linux/PsychHID/PsychHIDStandardInterfaces.c
  23. +3 −0 PsychSourceGL/Source/Linux/PsychHID/PsychHIDStandardInterfaces.h
  24. +1 −1 PsychSourceGL/Source/Linux/Screen/PsychScreenGlue.c
  25. +6 −11 PsychSourceGL/Source/Linux/Screen/PsychWindowGlue.c
  26. +128 −0 PsychSourceGL/Source/OSX/Screen/PsychCocoaGlue.c
  27. +8 −0 PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c
  28. +19 −7 PsychSourceGL/Source/Windows/IOPort/PsychSerialWindowsGlue.c
  29. +1 −1 PsychSourceGL/Source/Windows/Screen/PsychScreenGlue.c
  30. +2 −2 PsychSourceGL/Source/linuxmakeit64_ubuntugutsy.m
  31. +2 −2 PsychSourceGL/Source/linuxmakeit_ubuntugutsy.m
  32. +2 −2 PsychSourceGL/Source/linuxmakeitoctave3_ubuntugutsy.m
  33. +1 −1 PsychSourceGL/Source/osxmakeit.m
  34. +1 −1 PsychSourceGL/Source/osxmakeitoctave3.m
  35. +2 −0 PsychSourceGL/Source/striplibsfrommexfile.m
  36. +80 −27 Psychtoolbox/PsychBasic/CharAvail.m
  37. +65 −31 Psychtoolbox/PsychBasic/FlushEvents.m
  38. +148 −86 Psychtoolbox/PsychBasic/GetChar.m
  39. BIN Psychtoolbox/PsychBasic/IOPort.mexa64
  40. BIN Psychtoolbox/PsychBasic/IOPort.mexglx
  41. BIN Psychtoolbox/PsychBasic/IOPort.mexmaci
  42. BIN Psychtoolbox/PsychBasic/IOPort.mexmaci64
  43. +20 −0 Psychtoolbox/PsychBasic/IsWinVista.m
  44. +5 −0 Psychtoolbox/PsychBasic/KbEventAvail.m
  45. +5 −0 Psychtoolbox/PsychBasic/KbEventFlush.m
  46. +9 −0 Psychtoolbox/PsychBasic/KbEventGet.m
  47. +8 −2 Psychtoolbox/PsychBasic/KbQueueCheck.m
  48. +10 −9 Psychtoolbox/PsychBasic/KbQueueCreate.m
  49. +9 −0 Psychtoolbox/PsychBasic/KbQueueFlush.m
  50. +10 −2 Psychtoolbox/PsychBasic/KbQueueRelease.m
  51. +85 −0 Psychtoolbox/PsychBasic/KbQueueReserve.m
  52. +8 −2 Psychtoolbox/PsychBasic/KbQueueStart.m
  53. +9 −0 Psychtoolbox/PsychBasic/KbQueueStop.m
  54. +5 −0 Psychtoolbox/PsychBasic/KbQueueWait.m
  55. +12 −0 Psychtoolbox/PsychBasic/KbTriggerWait.m
  56. +177 −21 Psychtoolbox/PsychBasic/ListenChar.m
  57. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/IOPort.mexw32
  58. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/IOPort.mexw64
  59. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/PsychHID.mexw32
  60. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/PsychHID.mexw64
  61. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/PsychPortAudio.mexw32
  62. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/PsychPortAudio.mexw64
  63. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/Screen.mexw32
  64. BIN Psychtoolbox/PsychBasic/MatlabWindowsFilesR2007a/Screen.mexw64
  65. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/Eyelink.mex
  66. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/GetSecs.mex
  67. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/IOPort.mex
  68. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/PsychHID.mex
  69. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/PsychKinectCore.mex
  70. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/PsychPortAudio.mex
  71. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/Screen.mex
  72. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/WaitSecs.mex
  73. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles/pnet.mex
  74. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/Eyelink.mex
  75. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/GetSecs.mex
  76. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/IOPort.mex
  77. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/PsychHID.mex
  78. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/PsychKinectCore.mex
  79. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/PsychPortAudio.mex
  80. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/Screen.mex
  81. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/WaitSecs.mex
  82. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/moalcore.mex
  83. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/moglcore.mex
  84. BIN Psychtoolbox/PsychBasic/Octave3LinuxFiles64/pnet.mex
  85. BIN Psychtoolbox/PsychBasic/Octave3OSXFiles64/IOPort.mex
  86. BIN Psychtoolbox/PsychBasic/Octave3OSXFiles64/PsychHID.mex
  87. BIN Psychtoolbox/PsychBasic/Octave3OSXFiles64/PsychPortAudio.mex
  88. BIN Psychtoolbox/PsychBasic/Octave3OSXFiles64/Screen.mex
  89. BIN Psychtoolbox/PsychBasic/PsychHID.mexa64
  90. BIN Psychtoolbox/PsychBasic/PsychHID.mexglx
  91. BIN Psychtoolbox/PsychBasic/PsychHID.mexmaci
  92. BIN Psychtoolbox/PsychBasic/PsychHID.mexmaci64
  93. BIN Psychtoolbox/PsychBasic/PsychPlugins/libptbdrawtext_ftgl.so.1
  94. BIN Psychtoolbox/PsychBasic/PsychPlugins/libptbdrawtext_ftgl64.so.1
  95. +2 −2 Psychtoolbox/PsychBasic/PsychPortAudio.m
  96. BIN Psychtoolbox/PsychBasic/PsychPortAudio.mexa64
  97. BIN Psychtoolbox/PsychBasic/PsychPortAudio.mexglx
  98. BIN Psychtoolbox/PsychBasic/PsychPortAudio.mexmaci
  99. BIN Psychtoolbox/PsychBasic/PsychPortAudio.mexmaci64
  100. BIN Psychtoolbox/PsychBasic/Screen.mexa64
  101. BIN Psychtoolbox/PsychBasic/Screen.mexglx
  102. BIN Psychtoolbox/PsychBasic/Screen.mexmaci
  103. BIN Psychtoolbox/PsychBasic/Screen.mexmaci64
  104. +7 −2 Psychtoolbox/PsychDemos/BasicSoundOutputDemo.m
  105. +29 −10 Psychtoolbox/PsychDocumentation/GStreamer.m
  106. +18 −6 Psychtoolbox/PsychDocumentation/SyncTrouble.m
  107. +3 −3 Psychtoolbox/PsychGLImageProcessing/private/bvlWaitForInput.m
  108. +16 −5 Psychtoolbox/PsychHardware/BitsPlusToolbox/BitsPlusTests/BitsPlusIdentityClutTest.m
  109. +12 −18 Psychtoolbox/PsychHardware/Contents.m
  110. +41 −4 Psychtoolbox/PsychHardware/DatapixxToolbox/DatapixxBasic/DatapixxAudioKey.m
  111. +1 −1 Psychtoolbox/PsychHardware/DatapixxToolbox/DatapixxBasic/PsychDataPixx.m
  112. +216 −0 Psychtoolbox/PsychHardware/OptiCAL.m
  113. +1 −0 Psychtoolbox/PsychOneliners/Contents.m
  114. +15 −0 Psychtoolbox/PsychOneliners/IsGUI.m
  115. +15 −4 Psychtoolbox/PsychOneliners/PsychGPUControl.m
  116. +35 −23 Psychtoolbox/PsychSound/InitializePsychSound.m
  117. +2 −2 Psychtoolbox/PsychTests/GetCharTest.m
  118. +55 −24 Psychtoolbox/PsychTests/PsychPortAudioDataPixxTimingTest.m
  119. +86 −42 Psychtoolbox/PsychTests/PsychPortAudioTimingTest.m
  120. +11 −32 Psychtoolbox/PsychtoolboxPostInstallRoutine.m
  121. +9 −9 managementtools/parseptblog.php
@@ -44,7 +44,7 @@
*
* Building for Linux:
*
- * g++ -g -fPIC -I. -I/usr/include/ -I/usr/include/freetype2/ -L/usr/lib -l GL -l GLU -l fontconfig -l freetype -pie -shared -o libptbdrawtext_ftgl.so.1 libptbdrawtext_ftgl.cpp qstringqcharemulation.cpp OGLFT.cpp
+ * g++ -g -fPIC -I. -I/usr/include/ -I/usr/include/freetype2/ -L/usr/lib -l GL -l GLU -l fontconfig -l freetype -pie -shared -Wl,-Bsymbolic -Wl,-Bsymbolic-functions -Wl,--version-script=linuxexportlist.txt -o libptbdrawtext_ftgl.so.1 libptbdrawtext_ftgl.cpp qstringqcharemulation.cpp OGLFT.cpp
*
* libptbdrawtext_ftgl is copyright (c) 2010 by Mario Kleiner.
* It is licensed to you under the LGPL license as follows:
@@ -0,0 +1,27 @@
+# This file is passed to the linker. It defines that
+# only functions which start with prefix "Psych", e.g.,
+# PsychDrawText, PsychMeasureText, ... have global
+# scope in the process which loads the ptbdrawtext_ftgl.so
+# DrawText text rendering plugin.
+#
+# All other functions only have local scope - they are
+# invisible to the hosting process.
+#
+# We add this to avoid polluting the host process with
+# definitions of our own QT-Toolkit "lookalike" implementations
+# of a few internally used QT classes. Our lookalikes are
+# very thin emulations of the real QT classes, stripped to
+# the bare essentials needed for the OGLFT code to by happy.
+# They are incomplete, but API compatible bits, which are
+# entirely ABI incompatible.
+#
+# This is important because Octave's native GUI uses the QT
+# toolkit for its GUI code and we want to avoid any kind of
+# possible interference between our plugin and the QT-GUI.
+#
+{
+ global:
+ Psych*;
+ local:
+ *;
+};
@@ -96,7 +96,7 @@ static UInt32 crtcoff[(DCE4_MAXHEADID + 1)] = { EVERGREEN_CRTC0_REGISTER_OFFSET,
#define super IOService
OSDefineMetaClassAndStructors(PsychtoolboxKernelDriver, IOService)
-/* Mappings up to date for June 2012 (last update commit 5-Jun-2012). Will need updates for anything after June 2012 */
+/* Mappings up to date for October 2012 (last update e-mail patch / commit 16-Oct-2012). Will need updates for anything after October 2012 */
/* Is a given ATI/AMD GPU a DCE6.1 type ASIC, i.e., with the new display engine? */
bool PsychtoolboxKernelDriver::isDCE61(void)
@@ -660,6 +660,8 @@
8306696D0D3920D50009C12B /* PsychGraphicsHardwareHALSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306696B0D3920D50009C12B /* PsychGraphicsHardwareHALSupport.c */; };
830982E00DB2DF4100E7D371 /* IOPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B16C307788CC100359736 /* IOPort.c */; };
830982E10DB2DF4500E7D371 /* IOPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B16C307788CC100359736 /* IOPort.c */; };
+ 830C8DA4163BA879009B354B /* PsychHIDKeyboardHelper.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C8DA3163BA879009B354B /* PsychHIDKeyboardHelper.c */; };
+ 830C8DA5163BA879009B354B /* PsychHIDKeyboardHelper.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C8DA3163BA879009B354B /* PsychHIDKeyboardHelper.c */; };
8310AC490F87C222004AAE79 /* PsychHIDCloseUSBDevice.c in Sources */ = {isa = PBXBuildFile; fileRef = F16C715D0F86999500A8BE72 /* PsychHIDCloseUSBDevice.c */; };
8310AC4A0F87C237004AAE79 /* PsychHIDOpenUSBDevice.c in Sources */ = {isa = PBXBuildFile; fileRef = F16C715E0F86999500A8BE72 /* PsychHIDOpenUSBDevice.c */; };
8310AC4B0F87C24C004AAE79 /* PsychHIDUSBControlTransfer.c in Sources */ = {isa = PBXBuildFile; fileRef = F1BCA5ED0F8676BD00EABA6F /* PsychHIDUSBControlTransfer.c */; };
@@ -2176,6 +2178,7 @@
830669BD0D3954B10009C12B /* PsychUserKernelShared.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PsychUserKernelShared.h; path = ../../../Source/OSX/Screen/PsychUserKernelShared.h; sourceTree = SOURCE_ROOT; };
83066A8A0D39AEAF0009C12B /* PsychGraphicsCardRegisterSpecs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PsychGraphicsCardRegisterSpecs.h; path = ../../../Source/Common/Screen/PsychGraphicsCardRegisterSpecs.h; sourceTree = SOURCE_ROOT; };
83097FD70DB18BAF00E7D371 /* PsychSerialUnixGlue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PsychSerialUnixGlue.h; path = ../../../Source/Common/IOPort/PsychSerialUnixGlue.h; sourceTree = SOURCE_ROOT; };
+ 830C8DA3163BA879009B354B /* PsychHIDKeyboardHelper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PsychHIDKeyboardHelper.c; path = ../../../Source/Common/PsychHID/PsychHIDKeyboardHelper.c; sourceTree = "<group>"; };
831A455F12A6EB5400FFF235 /* PsychMovieSupportQuickTime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PsychMovieSupportQuickTime.h; path = ../../../Source/Common/Screen/PsychMovieSupportQuickTime.h; sourceTree = SOURCE_ROOT; };
831A456212A6EE1000FFF235 /* PsychMovieSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PsychMovieSupport.h; path = ../../../Source/Common/Screen/PsychMovieSupport.h; sourceTree = SOURCE_ROOT; };
831A458412A6EEC500FFF235 /* PsychMovieSupport.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = PsychMovieSupport.c; path = ../../../Source/Common/Screen/PsychMovieSupport.c; sourceTree = SOURCE_ROOT; };
@@ -3601,6 +3604,7 @@
8325CED10CAF15DC00B498CD /* PsychHIDKbQueueStop.c */,
8325CED40CAF15E900B498CD /* PsychHIDKbTriggerWait.c */,
CF566E6D07F7D2FC00D4957A /* PsychHIDKbWait.c */,
+ 830C8DA3163BA879009B354B /* PsychHIDKeyboardHelper.c */,
2F5434E40904C61F0051D6CC /* PsychHIDReceiveReports.c */,
2F5434E60904C6A40051D6CC /* PsychHIDReceiveReportsStop.c */,
CF566E6B07F7D2FC00D4957A /* PsychHIDSetReport.c */,
@@ -6894,6 +6898,7 @@
F16C715F0F86999500A8BE72 /* PsychHIDCloseUSBDevice.c in Sources */,
F16C71600F86999500A8BE72 /* PsychHIDOpenUSBDevice.c in Sources */,
833A17A013DA1D2900C1911E /* PsychHIDGenericUSBLibSupport.c in Sources */,
+ 830C8DA4163BA879009B354B /* PsychHIDKeyboardHelper.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -7609,6 +7614,7 @@
8310AC4A0F87C237004AAE79 /* PsychHIDOpenUSBDevice.c in Sources */,
8310AC4B0F87C24C004AAE79 /* PsychHIDUSBControlTransfer.c in Sources */,
833A17A113DA1D2900C1911E /* PsychHIDGenericUSBLibSupport.c in Sources */,
+ 830C8DA5163BA879009B354B /* PsychHIDKeyboardHelper.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -604,6 +604,10 @@ static mxArray *mxCreateDoubleMatrix3D(psych_int64 m, psych_int64 n, psych_int64
EXP void mexFunction(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[]);
#endif
+// firstTime: This flag defines if this is the first invocation of the module
+// since it was (re-)loaded:
+static psych_bool firstTime = TRUE;
+
#if PSYCH_LANGUAGE == PSYCH_OCTAVE
PsychError PsychExitOctaveGlue(void);
static psych_bool jettisoned = FALSE;
@@ -650,7 +654,6 @@ EXP void mexFunction(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
EXP octave_value_list octFunction(const octave_value_list& prhs, const int nlhs)
#endif
{
- static psych_bool firstTime = TRUE;
psych_bool errorcondition = FALSE;
psych_bool isArgThere[2], isArgEmptyMat[2], isArgText[2], isArgFunction[2];
PsychFunctionPtr fArg[2], baseFunction;
@@ -1104,8 +1107,19 @@ PsychError PsychExitOctaveGlue(void)
*/
void PsychExitGlue(void)
{
+ // Reset firstTime flag, so reloading the module leads to a full init cycle.
+ // This is especially important on Octave, as it doesn't fully unload/reload
+ // mex file modules at "clear" time, so the static firstTime variable won't
+ // get automatically reset to its inital load default of TRUE:
+ // firstTime = TRUE;
+
+ // Perform platform independent shutdown:
PsychErrorExitMsg(PsychExit(),NULL);
-}
+
+ // And we are dead! Now the runtime will flush us from process memory,
+ // at least on Matlab. In any case no further invocation will happen
+ // until reload.
+}
/*
@@ -364,9 +364,21 @@ void* PsychSerialUnixGlueReaderThreadMain( void* deviceToCast)
if ((nread = read(device->fileDescriptor, &(device->readBuffer[(device->readerThreadWritePos) % (device->readBufferSize)]), naccumread)) != naccumread) {
// Should not happen, unless device is in cooked (canonical) input processing mode, where any read() will
// at most return the content of a single line of buffered input, regardless of requested amount. In this
- // case it is not only a perfectly valid and expected result, but also safe, becuse our memset() above will
+ // case it is not only a perfectly valid and expected result, but also safe, because our memset() above will
// zero-fill the remainder of the buffer with a defined value. For this reason we only output an error
- // if high verbosity level is selected for debug output:
+ // if high verbosity level is selected for debug output.
+
+ // One special case: Zero bytes read due to read timeout exceeded. In this case we just skip and retry,
+ // instead of storing a complete zero-filled block of readGranularity bytes. Padding is nice, but returning
+ // completely empty data, which is indistinguishable from a sequence of zeros is not good. This caused serious
+ // pain when trying to receive one-byte scanner triggers, and it timed out due to scan not yet started and the
+ // valid scanner trigger bytes are value==zero bytes, indistinguishable by usercode from timeout. This injected
+ // "ghost triggers" from the usercodes perspective, very bad! Note that the actual timeout case is handled by
+ // the high level read code by independent checking for timeout. The high level code will hit timeout if we
+ // hit this "continue" too often, and will return a empty [] variable, reliably signalling to calling code that
+ // timeout occured - something that can be cleanly handled by caller.
+ if (nread == 0) continue;
+
if (verbosity > 5) fprintf(stderr, "PTB-ERROR: In IOPort:PsychSerialUnixGlueReaderThreadMain(): Failed to read %i bytes of data for unknown reason (Got only %i bytes)! Padding...\n", naccumread, nread);
}
@@ -216,8 +216,10 @@ PsychError PSYCHHIDGiveMeReports(void); // PsychHIDGiveMeReports.c
PsychError PSYCHHIDOpenUSBDevice(void); // PSYCHHIDOpenUSBDevice.c
PsychError PSYCHHIDCloseUSBDevice(void); // PSYCHHIDCloseUSBDevice.c
PsychError PSYCHHIDUSBControlTransfer(void); // PSYCHHIDUSBControlTransfer.c
+PsychError PSYCHHIDKeyboardHelper(void); // PSYCHHIDKeyboardHelper.c
//internal function protototypes
+void ConsoleInputHelper(int ccode); // PsychHIDKeyboardHelper.c -- Called from kbqueue handling thread.
PsychError PsychHIDReceiveReportsCleanup(void); // PsychHIDReceiveReports.c
PsychError ReceiveReports(int deviceIndex); // PsychHIDReceiveReports.c
PsychError GiveMeReport(int deviceIndex, psych_bool *reportAvailablePtr, unsigned char *reportBuffer, psych_uint32 *reportBytesPtr, double *reportTimePtr); // PsychHIDReceiveReports.c
@@ -287,7 +289,7 @@ void PsychHIDOSKbTriggerWait(int deviceIndex, int numScankeys, int* scanKeys);
psych_bool PsychHIDCreateEventBuffer(int deviceIndex);
psych_bool PsychHIDDeleteEventBuffer(int deviceIndex);
psych_bool PsychHIDFlushEventBuffer(int deviceIndex);
-unsigned int PsychHIDAvailEventBuffer(int deviceIndex);
+unsigned int PsychHIDAvailEventBuffer(int deviceIndex, unsigned int flags);
int PsychHIDReturnEventFromEventBuffer(int deviceIndex, int outArgIndex, double maxWaitTimeSecs);
int PsychHIDAddEventToEventBuffer(int deviceIndex, PsychHIDEventRecord* evt);
@@ -18,13 +18,39 @@
#include "PsychHID.h"
+#if PSYCH_SYSTEM == PSYCH_OSX
+
+#define NUMDEVICEUSAGES 7
+
+int PsychHIDOSXGetRealDefaultKbQueueDevice(void)
+{
+ long KbDeviceUsagePages[NUMDEVICEUSAGES] = {kHIDPage_GenericDesktop, kHIDPage_GenericDesktop, kHIDPage_GenericDesktop, kHIDPage_GenericDesktop, kHIDPage_GenericDesktop, kHIDPage_GenericDesktop, kHIDPage_GenericDesktop};
+ long KbDeviceUsages[NUMDEVICEUSAGES] = {kHIDUsage_GD_Keyboard, kHIDUsage_GD_Keypad, kHIDUsage_GD_Mouse, kHIDUsage_GD_Pointer, kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController};
+ int numDeviceUsages = NUMDEVICEUSAGES;
+
+ int deviceIndices[PSYCH_HID_MAX_KEYBOARD_DEVICES];
+ pRecDevice deviceRecords[PSYCH_HID_MAX_KEYBOARD_DEVICES];
+ int numDeviceIndices;
+
+ // Enumerate all possible candidates for default keyboard device:
+ PsychHIDGetDeviceListByUsages(numDeviceUsages, KbDeviceUsagePages, KbDeviceUsages, &numDeviceIndices, deviceIndices, deviceRecords);
+
+ // Nothing?
+ if (numDeviceIndices == 0) PsychErrorExitMsg(PsychError_user, "No keyboard or keypad devices detected.");
+
+ // Return the default keyboard or keypad device as the first keyboard device or, if no keyboard, the first keypad:
+ return(deviceIndices[0]);
+}
+#endif
+
static char useString[]= "devices=PsychHID('Devices' [, deviceClass])";
static char synopsisString[] = "Return a struct array describing each connected USB HID device.\n"
"'deviceClass' optionally selects for the class of input device. "
"This is not supported on all operating systems and will be silently "
"ignored if unsupported. On Linux you can select the following classes "
"of input devices: 1 = MasterPointer, 2 = MasterKeyboard, 3 = SlavePointer "
"4 = SlaveKeyboard, 5 = Floating slave device.\n\n"
+ "deviceClass -1 returns the numeric deviceIndex of the default keyboard device for keyboard queues.\n\n"
"Not all device properties are returned on all operating systems. A zero, "
"empty or -1 value for a property in the returned structs can mean that "
"the information could not be returned.\n";
@@ -49,9 +75,26 @@ PsychError PSYCHHIDGetDevices(void)
if (PsychCopyInIntegerArg(1, FALSE, &deviceClass)) {
// Operating system specific enumeration of devices, selected by deviceClass:
- // Currently unsupported on OSX:
+
+ // Other classes currently unsupported on OSX:
#if PSYCH_SYSTEM != PSYCH_OSX
- return(PsychHIDEnumerateHIDInputDevices(deviceClass));
+ if (deviceClass == -1) {
+ PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) PsychHIDGetDefaultKbQueueDevice());
+ return(PsychError_none);
+ }
+
+ return(PsychHIDEnumerateHIDInputDevices(deviceClass));
+ #else
+ // Horrible hack: Usercode wants 'deviceIndex' or real default HID keyboard,
+ // but we can't use PsychHIDGetDefaultKbQueueDevice() as on other OS'es, as
+ // that always has to return a hard-coded zero, because much of our code relies
+ // on that function for indexing into keyboard queues, and on OSX there is only
+ // one keyboard queue with index zero, regardless what deviceIndex is attached to
+ // that queue:
+ if (deviceClass == -1) {
+ PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) PsychHIDOSXGetRealDefaultKbQueueDevice());
+ return(PsychError_none);
+ }
#endif
}
@@ -150,6 +150,10 @@ PsychError PsychHIDCleanup(void)
// Disable online help system:
PsychClearGiveHelp();
+ // Disable any kind of low-level stdin<->tty magic for character reception
+ // or suppression in console mode (for octave and matlab -nojvm):
+ ConsoleInputHelper(-10);
+
// Shutdown USB-HID report low-level functions, e.g., for DAQ toolbox on OS/X:
error = PsychHIDReceiveReportsCleanup(); // PsychHIDReceiveReport.c
@@ -295,15 +299,34 @@ psych_bool PsychHIDFlushEventBuffer(int deviceIndex)
return(TRUE);
}
-unsigned int PsychHIDAvailEventBuffer(int deviceIndex)
+/* Return number of events in buffer for 'deviceIndex':
+ * flags == 0 -> All events.
+ * flags & 1 -> Only keypress events with valid mapped ASCII CookedKey keycode.
+ */
+unsigned int PsychHIDAvailEventBuffer(int deviceIndex, unsigned int flags)
{
- unsigned int navail;
+ unsigned int navail, i, j;
+
if (deviceIndex < 0) deviceIndex = PsychHIDGetDefaultKbQueueDevice();
if (!hidEventBuffer[deviceIndex]) return(0);
PsychLockMutex(&hidEventBufferMutex[deviceIndex]);
+
+ // Compute total number of available events by default:
navail = hidEventBufferWritePos[deviceIndex] - hidEventBufferReadPos[deviceIndex];
+
+ // Only count of valid "CookedKey" mapped keypress events, e.g., for use by CharAvail(), requested?
+ if (flags & 1) {
+ // Yes: Iterate over all available events and only count number of keypress events
+ // with meaningful 'CookedKey' field:
+ navail = 0;
+ for (i = hidEventBufferReadPos[deviceIndex]; i < hidEventBufferWritePos[deviceIndex]; i++) {
+ j = i % hidEventBufferCapacity[deviceIndex];
+ if ((hidEventBuffer[deviceIndex][j].status & (1<<0)) && (hidEventBuffer[deviceIndex][j].cookedEventCode > 0)) navail++;
+ }
+ }
+
PsychUnlockMutex(&hidEventBufferMutex[deviceIndex]);
return(navail);
Oops, something went wrong.

0 comments on commit 9b5c690

Please sign in to comment.