1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
|
/*
PsychToolbox3/Source/Common/Screen/RegisterProject.c
PROJECTS:
Screen only.
AUTHORS:
Allen.Ingling@nyu.edu awi
mario.kleiner.de@gmail.com mk
PLATFORMS:
All.
HISTORY:
8/20/02 awi Created.
DESCRIPTION:
The psychtoolbox is seperated into two layers:
-A lower layer which includes C files and all headers included
by Psych.h. All Psychtoolbox projects should include Psych.h
-An upper layer which includes all C files and headers specific
to the project, for example only the Screen project includes
Screen.h, which includes among other things declarations for
Screen.h functions.
That the entry point (e.g. MexFunction) for the module is in the
lower Psych.h layer breaks the typical inclusion heirarchy where the
library headers are included in the project headers but not vice
versa. So with Psychtoolbox project the library must include
the project headers and to do this cleanly and portably we allow
the lower layer to contain only one header file from the
upper layer which is alwyas named RegisterProject.h, which in turn
includes the the header for the project (e.g. Screen.h). This
avoids the messiness of having to name project-specific headers
for every project within a portable library; The library would
have to be modified to be used in a project.
Every psychtoolbox project must contain the RegisterProject.h
header file, and that file should #include the project header file,
(e.g. Screen.h).
Every psychtoolbox project should include the function
PsychModuleInit() which is called when the compiled module is loaded:
PsychModuleInit should do whatever initilization is the project requires
and register subfunctions. The Psychtoolbox provides two functions
for registering projects:
PsychError PsychRegisterProjectExit(PsychExitFunctionType *exitFunc)
-Registers a cleanup function which is invoked before the module
is purged.
PsychError PsychRegisterProjectFunction(char *name, func)
-When called with the name argument and NULL for the function
argument it registers name as the project name.
-When called with name and a non-null func value registers
func as to be invoked if the module is called with the name as
the first or second argument.
-when called with NULL for name and a non-null for func
registers a module function to be called when the module is
invoked with no subcommand name. The resulting behavior varies
depeinding on whether the project uses named subfunctions.
The psychoolbox operates in either of two ways depending on
whether named subfunctions are used.
-If ONLY the null name function is regsitered then the library
operates in "direct mode" where control passes to the function
passed in the func argument whenever the module is invoked.
-If any named subfunction is registered then the function
registered with the NULL name is invoked whenever the module
is invoked with no arguments.
*/
// begin include once
#include "RegisterProject.h"
// This special sauce only on the Unices:
#if PSYCH_SYSTEM != PSYCH_WINDOWS
// Note: On Linux, _GNU_SOURCE must be defined at the compiler command line, so we
// can use GNU specific extensions to dlopen(), as well as the dladdr()
// function below. On OSX, that #define is not needed, as it is part of standard BSD.
#include <dlfcn.h>
#endif
// PsychModuleInit is in Screen.cpp
// PsychProjectExit is in Screen.cpp
// PsychProjectSelectFunction is in Screen.cpp
PsychError PsychModuleInit(void)
{
// Initialize all Screen('Preference', ...); settings to startup defaults:
// This will also set an override level of verbosity if the relevant environment
// variable has been set for low-level debugging purposes.
PrepareScreenPreferences();
// This little Screen reloading gem disabled, as it is bad, bad, bad!
// Wasn't useful for exporting ConsoleInputHelper(), as that approach proved
// way too fragile. Additionally it now causes trouble with some workaround for
// a Mesa bug: Exporting Screen()'s symbols causes moglcore to link against them
// for GLEW stuff, and thereby it prevents 'clear Screen' if moglcore itself is
// not cleared itself, as moglcore holds references to symbols in Screen.
// Disable this code, so symbols of Screen() stay private to Screen.mex itself
// on Linux and this specific problem is hopefully avoided.
#if PSYCH_SYSTEM != PSYCH_WINDOWS
#if 0
// Try to reopen ourselves, ie. the currently used Screen() MEX file, in "noload" mode,
// aka RTLD_NOLOAD.
//
// We are not really reloaded, as we are obviously already present, but our symbols are
// made available globally in the process due to reopening with RTLD_GLOBAL, therefore
// other PTB mex file modules have some access to our functions, allowing cross-module
// C-Function calls. PsychHID needs this to call our ConsoleInputHelper() function inside
// SCREENGetMouseHelper.c to reenable keystroke dispatch to octave or matlab -nojvm from
// their controlling tty's -- To undo a ListenChar(2) issued in such a setup when CTRL+C
// is detected. There may be future other uses, e.g., with IOPort et al. to trigger or wait
// completion of actions in Screen() in response to I/O trigger reception, or before emission
// of I/O trigger/control events.
//
// This functionality is Unix specifc, as it is only supported by GLibc with the
// _GNU_SOURCE flag defined, or on BSD systems like OSX:
Dl_info screen_info;
void* screenHandle = NULL;
// Retrieve the full path and filename of the shared library which contains
// the C-Function "ScreenExitFunction". As Screen() is the only mex file which
// defines this function, ie., ourselves, this will hopefully retrieve info
// about our running loaded instance of Screen():
if (dladdr((void*) ScreenExitFunction, &screen_info)) {
// Yes, got the info.
if (PsychPrefStateGet_Verbosity() > 4) printf("PTB-DEBUG: Screen() plugin path as detected by dladdr(): %s\n", screen_info.dli_fname);
// Try to re-open us and get a handle to ourselves. This will not really
// reload us due to RTLD_NOLOAD, just return the handle, increment our
// refcount and most importantly, make all our public symbols available
// globally to the whole address space of the runtime process, so other
// modules can access our non-private symbols and call our non-private
// functions (aka RTLD_GLOBAL):
dlerror();
screenHandle = dlopen(screen_info.dli_fname, RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL);
if (screenHandle) {
// Worked! Close us again, so the refcount drops back to the old value
// and the runtime isn't prevented from clear'ing us if needed:
dlclose(screenHandle);
if (PsychPrefStateGet_Verbosity() > 4) printf("PTB-DEBUG: Reopened Screen() mex plugin with global symbol scope!\n");
}
else {
if (PsychPrefStateGet_Verbosity() > 4) printf("PTB-WARNING: Could not re-dlopen() Screen() from file %s! [%s]\n", screen_info.dli_fname, dlerror());
}
} else {
if (PsychPrefStateGet_Verbosity() > 4) printf("PTB-WARNING: Could not get module info for Screen() from dladd()!\n");
}
if (!screenHandle && (PsychPrefStateGet_Verbosity() > 4)) printf("PTB-WARNING: Other PTB modules can't cross-call Screen's internal functions.\n");
#endif
#endif
// Register the project exit function
PsychErrorExitMsg(PsychRegisterExit(&ScreenExitFunction), "Failed to register the Screen exit function.");
// Register the project function which is called when the module
// is invoked with no arguments:
PsychErrorExitMsg(PsychRegister(NULL, &PsychDisplayScreenSynopsis), "Failed to register the Screen synopsis function.");
// Register the module name
PsychErrorExitMsg(PsychRegister("Screen", NULL), "Failed to register the Screen module name.");
// Register named subfunctions
// Enable for debugging purposes
PsychErrorExit(PsychRegister("Null", &SCREENNull));
// Public api functions:
PsychErrorExit(PsychRegister("Version", &MODULEVersion));
PsychErrorExit(PsychRegister("Computer", &SCREENComputer));
PsychErrorExit(PsychRegister("Screens", &SCREENScreens));
PsychErrorExit(PsychRegister("PixelSize",&SCREENPixelSize));
PsychErrorExit(PsychRegister("PixelSizes",&SCREENPixelSizes));
PsychErrorExit(PsychRegister("OpenWindow", &SCREENOpenWindow));
PsychErrorExit(PsychRegister("OpenOffscreenWindow", &SCREENOpenOffscreenWindow));
PsychErrorExit(PsychRegister("Close", &SCREENClose));
PsychErrorExit(PsychRegister("CloseAll", &SCREENCloseAll));
PsychErrorExit(PsychRegister("Flip", &SCREENFlip));
PsychErrorExit(PsychRegister("AsyncFlipBegin", &SCREENFlip));
PsychErrorExit(PsychRegister("AsyncFlipEnd", &SCREENFlip));
PsychErrorExit(PsychRegister("AsyncFlipCheckEnd", &SCREENFlip));
PsychErrorExit(PsychRegister("WaitUntilAsyncFlipCertain" , &SCREENWaitUntilAsyncFlipCertain));
PsychErrorExit(PsychRegister("FillRect", &SCREENFillRect));
PsychErrorExit(PsychRegister("GetImage", &SCREENGetImage));
PsychErrorExit(PsychRegister("PutImage", &SCREENPutImage));
PsychErrorExit(PsychRegister("HideCursorHelper", &SCREENHideCursorHelper));
PsychErrorExit(PsychRegister("ShowCursorHelper", &SCREENShowCursorHelper));
PsychErrorExit(PsychRegister("SetMouseHelper", &SCREENSetMouseHelper));
PsychErrorExit(PsychRegister("Rect", &SCREENRect));
PsychErrorExit(PsychRegister("WindowScreenNumber", &SCREENWindowScreenNumber));
PsychErrorExit(PsychRegister("Windows", &SCREENWindows));
PsychErrorExit(PsychRegister("WindowKind", &SCREENWindowKind));
PsychErrorExit(PsychRegister("IsOffscreen", &SCREENIsOffscreen));
PsychErrorExit(PsychRegister("ReadNormalizedGammaTable", &SCREENReadNormalizedGammaTable));
PsychErrorExit(PsychRegister("LoadNormalizedGammaTable", &SCREENLoadNormalizedGammaTable));
PsychErrorExit(PsychRegister("FrameRate", &SCREENNominalFramerate));
PsychErrorExit(PsychRegister("NominalFrameRate", &SCREENNominalFramerate));
PsychErrorExit(PsychRegister("glPoint", &SCREENglPoint));
PsychErrorExit(PsychRegister("gluDisk", &SCREENgluDisk));
PsychErrorExit(PsychRegister("FillOval", &SCREENFillOval));
PsychErrorExit(PsychRegister("FrameOval", &SCREENFrameOval));
PsychErrorExit(PsychRegister("TextModes", &SCREENTextModes));
PsychErrorExit(PsychRegister("TextMode", &SCREENTextMode));
PsychErrorExit(PsychRegister("TextSize", &SCREENTextSize));
PsychErrorExit(PsychRegister("TextStyle", &SCREENTextStyle));
PsychErrorExit(PsychRegister("TextFont", &SCREENTextFont));
PsychErrorExit(PsychRegister("TextBounds", &SCREENTextBounds));
PsychErrorExit(PsychRegister("DrawText", &SCREENDrawText));
PsychErrorExit(PsychRegister("TextColor", &SCREENTextColor));
PsychErrorExit(PsychRegister("Preference", &SCREENPreference));
PsychErrorExit(PsychRegister("MakeTexture", &SCREENMakeTexture));
PsychErrorExit(PsychRegister("DrawTexture", &SCREENDrawTexture));
PsychErrorExit(PsychRegister("FrameRect", &SCREENFrameRect));
PsychErrorExit(PsychRegister("DrawLine", &SCREENDrawLine));
PsychErrorExit(PsychRegister("FillPoly", &SCREENFillPoly));
PsychErrorExit(PsychRegister("FramePoly", &SCREENFramePoly));
PsychErrorExit(PsychRegister("GlobalRect", &SCREENGlobalRect));
PsychErrorExit(PsychRegister("DrawDots", &SCREENDrawDots));
PsychErrorExit(PsychRegister("GetTimeList", &SCREENGetTimeList));
PsychErrorExit(PsychRegister("ClearTimeList", &SCREENClearTimeList));
PsychErrorExit(PsychRegister("BlendFunction", &SCREENBlendFunction));
PsychErrorExit(PsychRegister("WindowSize", &SCREENWindowSize));
PsychErrorExit(PsychRegister("GetMouseHelper", &SCREENGetMouseHelper));
PsychErrorExit(PsychRegister("TextBackgroundColor", &SCREENTextBackgroundColor));
PsychErrorExit(PsychRegister("LineStipple", &SCREENLineStipple));
PsychErrorExit(PsychRegister("SelectStereoDrawBuffer", &SCREENSelectStereoDrawBuffer));
PsychErrorExit(PsychRegister("DrawingFinished", &SCREENDrawingFinished));
PsychErrorExit(PsychRegister("DrawLines", &SCREENDrawLines));
PsychErrorExit(PsychRegister("GetFlipInterval", &SCREENGetFlipInterval));
PsychErrorExit(PsychRegister("CloseMovie", &SCREENCloseMovie));
PsychErrorExit(PsychRegister("OpenMovie", &SCREENOpenMovie));
PsychErrorExit(PsychRegister("PlayMovie", &SCREENPlayMovie));
PsychErrorExit(PsychRegister("SetMovieTimeIndex", &SCREENSetMovieTimeIndex));
PsychErrorExit(PsychRegister("GetMovieTimeIndex", &SCREENGetMovieTimeIndex));
PsychErrorExit(PsychRegister("GetMovieImage", &SCREENGetMovieImage));
PsychErrorExit(PsychRegister("glPushMatrix", &SCREENglPushMatrix));
PsychErrorExit(PsychRegister("glPopMatrix", &SCREENglPopMatrix));
PsychErrorExit(PsychRegister("glLoadIdentity", &SCREENglLoadIdentity));
PsychErrorExit(PsychRegister("glTranslate", &SCREENglTranslate));
PsychErrorExit(PsychRegister("glScale", &SCREENglScale));
PsychErrorExit(PsychRegister("glRotate", &SCREENglRotate));
PsychErrorExit(PsychRegister("PreloadTextures", &SCREENPreloadTextures));
PsychErrorExit(PsychRegister("FillArc", &SCREENFillArc));
PsychErrorExit(PsychRegister("DrawArc", &SCREENDrawArc));
PsychErrorExit(PsychRegister("FrameArc", &SCREENFrameArc));
PsychErrorExit(PsychRegister("CopyWindow", &SCREENCopyWindow));
PsychErrorExit(PsychRegister("WaitBlanking", &SCREENWaitBlanking));
PsychErrorExit(PsychRegister("GetOpenGLTexture", &SCREENGetOpenGLTexture));
PsychErrorExit(PsychRegister("SetOpenGLTexture", &SCREENSetOpenGLTexture));
PsychErrorExit(PsychRegister("BeginOpenGL", &SCREENBeginOpenGL));
PsychErrorExit(PsychRegister("EndOpenGL", &SCREENEndOpenGL));
PsychErrorExit(PsychRegister("OpenVideoCapture", &SCREENOpenVideoCapture));
PsychErrorExit(PsychRegister("CloseVideoCapture", &SCREENCloseVideoCapture));
PsychErrorExit(PsychRegister("StartVideoCapture", &SCREENStartVideoCapture));
PsychErrorExit(PsychRegister("StopVideoCapture", &SCREENStopVideoCapture));
PsychErrorExit(PsychRegister("GetCapturedImage", &SCREENGetCapturedImage));
PsychErrorExit(PsychRegister("SetVideoCaptureParameter", &SCREENSetVideoCaptureParameter));
PsychErrorExit(PsychRegister("VideoCaptureDevices", &SCREENVideoCaptureDevices));
PsychErrorExit(PsychRegister("LoadCLUT", &SCREENLoadCLUT));
PsychErrorExit(PsychRegister("DisplaySize", &SCREENDisplaySize));
PsychErrorExit(PsychRegister("SetOpenGLTextureFromMemPointer", &SCREENSetOpenGLTextureFromMemPointer));
PsychErrorExit(PsychRegister("ColorRange", &SCREENColorRange));
PsychErrorExit(PsychRegister("HookFunction", &SCREENHookFunction));
PsychErrorExit(PsychRegister("OpenProxy", &SCREENOpenProxy));
PsychErrorExit(PsychRegister("TransformTexture", &SCREENTransformTexture));
PsychErrorExit(PsychRegister("DrawTextures", &SCREENDrawTextures));
PsychErrorExit(PsychRegister("GetWindowInfo", &SCREENGetWindowInfo));
PsychErrorExit(PsychRegister("GetOpenGLDrawMode", &SCREENGetOpenGLDrawMode));
PsychErrorExit(PsychRegister("Resolutions", &SCREENResolutions));
PsychErrorExit(PsychRegister("Resolution", &SCREENResolution));
PsychErrorExit(PsychRegister("ConfigureDisplay", &SCREENConfigureDisplay));
PsychErrorExit(PsychRegister("CreateMovie", &SCREENCreateMovie));
PsychErrorExit(PsychRegister("FinalizeMovie", &SCREENFinalizeMovie));
PsychErrorExit(PsychRegister("AddFrameToMovie", &SCREENGetImage));
PsychErrorExit(PsychRegister("AddAudioBufferToMovie", &SCREENAddAudioBufferToMovie));
PsychErrorExit(PsychRegister("GetFlipInfo", &SCREENGetFlipInfo));
PsychErrorExit(PsychRegister("PanelFitter", &SCREENPanelFitter));
PsychErrorExit(PsychRegister("TextTransform", &SCREENTextTransform));
PsychErrorExit(PsychRegister("ConstrainCursor", &SCREENConstrainCursor));
PsychErrorExit(PsychRegister("ReadHDRImage", &SCREENReadHDRImage));
PsychSetModuleAuthorByInitials("awi");
PsychSetModuleAuthorByInitials("dhb");
PsychSetModuleAuthorByInitials("dgp");
PsychSetModuleAuthorByInitials("kas");
PsychSetModuleAuthorByInitials("fjc");
PsychSetModuleAuthorByInitials("mk");
PsychSetModuleAuthorByInitials("cb");
InitializeSynopsis();
if (PsychError_none != InitWindowBank())
printf("PTB-CRITICAL: ERROR: Out of memory when trying to allocate windowBank! Expect complete failure soon!!\n");
PsychMovieInit();
PsychVideoCaptureInit();
PsychMovieWritingInit();
// Call wait-routine for 0.1 secs: This to initialize the time glue on MS-Windows,
// so the first call to a timing function won't delay:
PsychWaitIntervalSeconds(0.1);
// Reset the "userspaceGL" flag which tells PTB that userspace GL rendering was active
// due to Screen('BeginOpenGL') command.
PsychSetUserspaceGLFlag(FALSE);
// Call display glue init last, as its error handling could go crazy if triggered
// before the init routines above got executed:
InitializePsychDisplayGlue();
return(PsychError_none);
}
|