Beispiel #1
0
bool RTCALL VBoxOglIs3DAccelerationSupported()
{
    if (RTEnvGet("VBOX_CROGL_FORCE_SUPPORTED"))
    {
        LogRel(("VBOX_CROGL_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n"));
        return true;
    }

    CGDirectDisplayID   display = CGMainDisplayID ();
    CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask (display);
    CGLPixelFormatObj   pixelFormat = NULL;
    GLint numPixelFormats = 0;

    CGLPixelFormatAttribute attribs[] = {
        kCGLPFADisplayMask,
        (CGLPixelFormatAttribute)cglDisplayMask,
        kCGLPFAAccelerated,
        kCGLPFADoubleBuffer,
        kCGLPFAWindow,
        (CGLPixelFormatAttribute)NULL
    };

    display = CGMainDisplayID();
    cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(display);
    CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats);

    if (pixelFormat)
    {
        CGLContextObj cglContext = 0;
        CGLCreateContext(pixelFormat, NULL, &cglContext);
        CGLDestroyPixelFormat(pixelFormat);
        if (cglContext)
        {
            GLboolean isSupported = GL_TRUE;
#ifdef VBOX_WITH_COCOA_QT
            /* On the Cocoa port we depend on the GL_EXT_framebuffer_object &
             * the GL_EXT_texture_rectangle extension. If they are not
             * available, disable 3D support. */
            CGLSetCurrentContext(cglContext);
            const GLubyte* strExt;
            strExt = glGetString(GL_EXTENSIONS);
            isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_framebuffer_object", strExt);
            if (isSupported)
            {
                isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_texture_rectangle", strExt);
                if (!isSupported)
                    LogRel(("OpenGL Info: GL_EXT_texture_rectangle extension not supported\n"));
            }
            else
                LogRel(("OpenGL Info: GL_EXT_framebuffer_object extension not supported\n"));
#endif /* VBOX_WITH_COCOA_QT */
            CGLDestroyContext(cglContext);
            return isSupported == GL_TRUE ? true : false;
        }
    }

    return false;
}
Beispiel #2
0
static int Open(void * hwnd)
{
    CGLRendererInfoObj renderer;
    long numRenderer;
	CGDirectDisplayID l[32];
	CGDisplayCount count;

	SYS_ASSERT(g_pCGLC == 0);
	UNUSED(hwnd);
	CGGetActiveDisplayList (sizeof(l), l, &count);

#ifdef _DEBUG
	// Debug in multiple monitor. Use the secondary monitor for rendering
	g_cgDisplayID = l[count-1];
#else
	g_cgDisplayID = CGMainDisplayID ();
#endif

	g_cgPrevDisplayMode = CGDisplayCurrentMode (g_cgDisplayID);
	g_cgDisplayModeList = CGDisplayAvailableModes (g_cgDisplayID);

    CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(g_cgDisplayID), &renderer, &numRenderer);
    CGLDestroyRendererInfo(renderer);

    return 0;
}
Beispiel #3
0
//-------------------------------------------------------------------------------------------------//
void OSXWindow::swapCGLBuffers(void)
{
	CGLFlushDrawable(mCGLContext);
	CGLContextObj curCtx = CGLGetCurrentContext();
	if(curCtx != mCGLContext)
	{
		CGLSetCurrentContext(mCGLContext);
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
        CGLSetFullScreenOnDisplay(mCGLContext, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay));
#else
        CGLSetFullScreen(mCGLContext);
#endif
	}
}
Beispiel #4
0
static int checkAppleVideoCard(void) 
{
	CGLRendererInfoObj rend;
	long theErr;
	unsigned long display_mask;
	long nrend;
	int j;
	long value;
	long maxvram = 0;   /* we get always more than 1 renderer, check one, at least, has 8 Mo */
	
	display_mask = CGDisplayIDToOpenGLDisplayMask (CGMainDisplayID() );	
	
	theErr = CGLQueryRendererInfo( display_mask, &rend, &nrend);
	if (theErr == 0) {
		theErr = CGLDescribeRenderer (rend, 0, kCGLRPRendererCount, &nrend);
		if (theErr == 0) {
			for (j = 0; j < nrend; j++) {
				theErr = CGLDescribeRenderer (rend, j, kCGLRPVideoMemory, &value); 
				if (value > maxvram)
					maxvram = value;
				if ((theErr == 0) && (value >= 20000000)) {
					theErr = CGLDescribeRenderer (rend, j, kCGLRPAccelerated, &value); 
					if ((theErr == 0) && (value != 0)) {
						theErr = CGLDescribeRenderer (rend, j, kCGLRPCompliant, &value); 
						if ((theErr == 0) && (value != 0)) {
							/*fprintf(stderr,"make it big\n");*/
							CGLDestroyRendererInfo (rend);
							macPrefState = 8;
							return 1;
						}
					}
				}
			}
		}
	}
	if (maxvram < 7500000 ) {       /* put a standard alert and quit*/ 
		SInt16 junkHit;
		char  inError[] = "* Not enough VRAM    ";
		char  inText[] = "* blender needs at least 8Mb    ";
		inError[0] = 16;
		inText[0] = 28;
		
		fprintf(stderr, " vram is %li . not enough, aborting\n", maxvram);
		StandardAlert (   kAlertStopAlert, (ConstStr255Param) &inError, (ConstStr255Param)&inText,NULL,&junkHit);
		abort();
	}
CGLDestroyRendererInfo (rend);
return 0;
}
Beispiel #5
0
void macosx_opengl_init(void) {
	CGLPixelFormatObj pixelFormatObj;
	GLint numPixelFormats;
	CGLPixelFormatAttribute attribs[] = {
		kCGLPFAFullScreen,
		kCGLPFADisplayMask,
		0,
		0
	};

	if (macosx_no_opengl) {
		return;
	}

	attribs[2] = CGDisplayIDToOpenGLDisplayMask(displayID);

	CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
	if (pixelFormatObj == NULL) {
		rfbLog("macosx_opengl_init: CGLChoosePixelFormat failed. Not using OpenGL.\n");
		return;
	}

	CGLCreateContext(pixelFormatObj, NULL, &glContextObj);
	CGLDestroyPixelFormat(pixelFormatObj);

	if (glContextObj == NULL) {
		rfbLog("macosx_opengl_init: CGLCreateContext failed. Not using OpenGL.\n");
		return;
	}

	CGLSetCurrentContext(glContextObj);
	CGLSetFullScreen(glContextObj);

	macosx_opengl_width  = macosx_opengl_get_width();
	macosx_opengl_height = macosx_opengl_get_height();

	macosx_opengl_bpp = macosx_opengl_get_bpp();

	glFinish();

	glPixelStorei(GL_PACK_ALIGNMENT, 4);
	glPixelStorei(GL_PACK_ROW_LENGTH, 0);
	glPixelStorei(GL_PACK_SKIP_ROWS, 0);
	glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

	rfbLog("macosx_opengl_init: Using OpenGL for screen capture.\n");
	macosx_read_opengl = 1;
}
Beispiel #6
0
//-------------------------------------------------------------------------------------------------//
void OSXWindow::createCGLFullscreen(unsigned int width, unsigned int height, unsigned int depth, unsigned int fsaa, CGLContextObj sharedContext)
{
    // Find the best match to what was requested
    boolean_t exactMatch = 0;
    int reqWidth, reqHeight, reqDepth;
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
    
    // Get a copy of the current display mode
    CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);

    // Loop through all display modes to determine the closest match.
    // CGDisplayBestModeForParameters is deprecated on 10.6 so we will emulate it's behavior
    // Try to find a mode with the requested depth and equal or greater dimensions first.
    // If no match is found, try to find a mode with greater depth and same or greater dimensions.
    // If still no match is found, just use the current mode.
    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(kCGDirectMainDisplay, NULL);
    for(int i = 0; i < CFArrayGetCount(allModes); i++)
    {
        CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
        String modeString = StringConverter::toString(CGDisplayModeGetWidth(mode)) + String(" x ") +
            StringConverter::toString(CGDisplayModeGetHeight(mode)) + String(" @ ") +
            StringConverter::toString(bitDepthFromDisplayMode(mode)) + "bpp.";

        LogManager::getSingleton().logMessage(modeString);
        if(bitDepthFromDisplayMode(mode) != depth)
            continue;

        if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height))
        {
            displayMode = mode;
            exactMatch = 1;
            break;
        }
    }

    // No depth match was found
    if(!exactMatch)
    {
        for(int i = 0; i < CFArrayGetCount(allModes); i++)
        {
            CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
            if(bitDepthFromDisplayMode(mode) >= depth)
                continue;

            if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height))
            {
                displayMode = mode;
                exactMatch = 1;
                break;
            }
        }
    }
    
    reqWidth = CGDisplayModeGetWidth(displayMode);
    reqHeight = CGDisplayModeGetHeight(displayMode);
    reqDepth = bitDepthFromDisplayMode(displayMode);
#else
    CFDictionaryRef displayMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, depth, width, height, &exactMatch);
    const void *value = NULL;

    value = CFDictionaryGetValue(displayMode, kCGDisplayWidth);
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqWidth);
    
    value = CFDictionaryGetValue(displayMode, kCGDisplayHeight);
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqHeight);
    
    value = CFDictionaryGetValue(displayMode, kCGDisplayBitsPerPixel);
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqDepth);
#endif

    if(!exactMatch)
    {
        // TODO: Report the size difference
        // That mode is not available, using the closest match
        String request = StringConverter::toString(width) + String(" x ") + StringConverter::toString(height) + String(" @ ") + 
            StringConverter::toString(depth) + "bpp. ";

        String received = StringConverter::toString(reqWidth) + String(" x ") +
            StringConverter::toString(reqHeight) + String(" @ ") + 
            StringConverter::toString(reqDepth) + "bpp. "; 
            
        LogManager::getSingleton().logMessage(String("RenderSystem Warning:  You requested a fullscreen mode of ") + request +
            String(" This mode is not available and you will receive the closest match.  The best display mode for the parameters requested is: ")
            + received);
    }
    
    // Do the fancy display fading
    CGDisplayFadeReservationToken reservationToken;
    CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval,
                                        &reservationToken);
    CGDisplayFade(reservationToken,
                  0.5,
                  kCGDisplayBlendNormal,
                  kCGDisplayBlendSolidColor,
                  0.0, 0.0, 0.0,
                  true);
    
    // Grab the main display and save it for later.
    // You could render to any display, but picking what display
    // to render to could be interesting.
    CGDisplayCapture(kCGDirectMainDisplay);
    
    // Switch to the correct resolution
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
    CGDisplaySetDisplayMode(kCGDirectMainDisplay, displayMode, NULL);
#else
    CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
#endif
    
    // Get a pixel format that best matches what we are looking for
    CGLPixelFormatAttribute attribs[] = { 
        kCGLPFADoubleBuffer,
        kCGLPFAAlphaSize,     (CGLPixelFormatAttribute)8,
        kCGLPFADepthSize,     (CGLPixelFormatAttribute)reqDepth,
        kCGLPFAStencilSize,   (CGLPixelFormatAttribute)8,
        kCGLPFASampleBuffers, (CGLPixelFormatAttribute)0,
        kCGLPFASamples,       (CGLPixelFormatAttribute)0,
        kCGLPFAFullScreen,
        kCGLPFASingleRenderer,
        kCGLPFAAccelerated,
        kCGLPFADisplayMask,   (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
        (CGLPixelFormatAttribute)0
    };
    
    // Set up FSAA if it was requested
    if(fsaa > 1)
    {
            // turn on kCGLPFASampleBuffers
            attribs[8] = (CGLPixelFormatAttribute)1;
            // set the samples for kCGLPFASamples
            attribs[10] = (CGLPixelFormatAttribute)fsaa;
    }
    
    
    CGLError err;
    CGLPixelFormatObj pixelFormatObj;
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
    GLint numPixelFormats = 0;
    err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
#else
    long numPixelFormats = 0;
    err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
#endif
    if(err != 0)
    {
        CGReleaseAllDisplays();
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen");
    }

    // Create the CGLcontext from our pixel format, share it with the sharedContext passed in
    err = CGLCreateContext(pixelFormatObj, sharedContext, &mCGLContext);
    if(err != 0)
    {
        CGReleaseAllDisplays();
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen");
    }
            
    // Once we have the context we can destroy the pixel format
    // In order to share contexts you must keep a pointer to the context object around
    // Our context class will now manage the life of the pixelFormatObj
    //CGLDestroyPixelFormat(pixelFormatObj); 
            
    // Set the context to full screen
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
    CGLSetFullScreenOnDisplay(mCGLContext, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay));
#else
    CGLSetFullScreen(mCGLContext);
#endif
    
    // Set the context as current
    CGLSetCurrentContext(mCGLContext);
    
    // This synchronizes CGL with the vertical retrace
    // Apple docs suggest that OpenGL blocks rendering calls when waiting for
    // a vertical retrace anyhow.
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
    GLint swapInterval = 1;
    CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval);
#else
    long swapInterval = 1;
    CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval);
#endif
    
    // Give a copy of our context to the rendersystem
    mContext = new OSXCGLContext(mCGLContext, pixelFormatObj);
    
    // Let everyone know we are fullscreen now
    mIsFullScreen = true;

    // Set some other variables.  Just in case we got a different value from CGDisplayBestModeForParameters than we requested
    mWidth = reqWidth;
    mHeight = reqHeight;
    mColourDepth = reqDepth;

    CGDisplayFade(reservationToken,
              2.0,
              kCGDisplayBlendSolidColor,
              kCGDisplayBlendNormal,
              0.0, 0.0, 0.0,
              false);
    CGReleaseDisplayFadeReservation(reservationToken);
}
Beispiel #7
0
unsigned char HaveOpenGLCapsChanged (GLCaps aDisplayCaps[], 
                                     CGDisplayCount dspyCnt)
{
  CGDisplayCount maxDisplays = 32;
  CGDirectDisplayID activeDspys[32];
  CGDisplayErr theError;
  short i;
  CGDisplayCount newDspyCnt = 0;
  
  if (NULL == aDisplayCaps) return 1;

  theError = CGGetActiveDisplayList(maxDisplays, activeDspys, &newDspyCnt);
  // if theError getting list mark as changed
  if (theError) return 1; 
  // if number of displays not equal
  if (dspyCnt != newDspyCnt) return 1;
  
  for (i = 0; i < dspyCnt; i++) {
    // get device ids
    if (aDisplayCaps[i].cgDisplayID != activeDspys[i]) return 1;
    if (aDisplayCaps[i].cglDisplayMask !=  
        CGDisplayIDToOpenGLDisplayMask(activeDspys[i])) return 1;
 
    // get current geometry
    {
      CGRect displayRect = CGDisplayBounds (activeDspys[i]);
      // get mode dictionary
      CFDictionaryRef dispMode = CGDisplayCurrentMode (activeDspys[i]);
      // check for all geometry matches 
      if (aDisplayCaps[i].deviceWidth != (long) displayRect.size.width)
        return 1;   
      if (aDisplayCaps[i].deviceHeight != (long) displayRect.size.height) 
        return 1;   
      if (aDisplayCaps[i].deviceOriginX != (long) displayRect.origin.x) 
        return 1;   
      if (aDisplayCaps[i].deviceOriginY != (long) displayRect.origin.y) 
        return 1;   
      if (aDisplayCaps[i].deviceDepth != 
                 (short) _getDictLong (dispMode,  kCGDisplayBitsPerPixel)) 
        return 1;    
      if (aDisplayCaps[i].deviceRefresh != 
          (short)(_getDictDouble (dispMode, kCGDisplayRefreshRate) + 0.5)) 
        return 1; // round to GLint
    }

    // get renderer info based on gDevice
    {
      CGLRendererInfoObj info;
        long j;
      GLint numRenderers = 0, rv = 0;
      CGLError theErr = 0;
      GLint deviceVRAM; // video memory in bytes
      unsigned long rendererID; // renderer ID
      
      theErr = CGLQueryRendererInfo (aDisplayCaps[i].cglDisplayMask, 
                                  &info, &numRenderers);
      if(0 == theErr) {
        CGLDescribeRenderer (info, 0, kCGLRPRendererCount, &numRenderers);
        for (j = 0; j < numRenderers; j++) {
          // find accelerated renderer (assume only one)
          CGLDescribeRenderer (info, j, kCGLRPAccelerated, &rv); 
          if (true == rv) { // if accelerated
            // what is the renderer ID
            CGLDescribeRenderer (info, j, kCGLRPRendererID, (GLint *)&rendererID); 
            if (rendererID != aDisplayCaps[i].rendererID) // check match
              return 1;
            // what is the VRAM
            CGLDescribeRenderer (info, j, kCGLRPVideoMemory, &deviceVRAM); 
            if (deviceVRAM != aDisplayCaps[i].deviceVRAM) // check match
              return 1;
            break; // done
          }
        }
      }
      CGLDestroyRendererInfo (info);
    }
  }
  return 0;
}
Beispiel #8
0
void CheckOpenGLCaps (CGDisplayCount maxDspys, 
                      GLCaps dCaps[], 
                      CGDisplayCount * dCnt)
{
  CGLContextObj curr_ctx = 0;
  CGDirectDisplayID dspys[32];
  CGDisplayErr theErr;
  short i;
  short size = sizeof (GLCaps);
  
  // no devices
  *dCnt = 0;
  
  if (maxDspys == 0) { // find number of displays
    *dCnt = 0;
    theErr = CGGetActiveDisplayList (32, dspys, dCnt);
    if (theErr) // theErr getting list
      *dCnt = 0; // 0 displays since can't correctly find any
    // zero list to ensure the routines are used correctly
    memset (dspys, 0, sizeof (CGDirectDisplayID) * *dCnt);
    return; // return dCnt
  }
  if (NULL == dCaps) return;

  theErr = CGGetActiveDisplayList(maxDspys, dspys, dCnt);
  if (theErr) return; // theErr getting list
  if (0 == *dCnt) return; // no displays
  
  memset (dCaps, 0, size * *dCnt); // zero memory
  
  for (i = 0; i < *dCnt; i++) {
    // get device ids
    dCaps[i].cgDisplayID = dspys[i];
    dCaps[i].cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(dspys[i]);
    
    { // get current geometry
      CGRect displayRect = CGDisplayBounds (dspys[i]);
      // get mode dictionary
      CFDictionaryRef dispMode = CGDisplayCurrentMode (dspys[i]); 
      dCaps[i].deviceWidth = (long) displayRect.size.width;   
      dCaps[i].deviceHeight = (long) displayRect.size.height;   
      dCaps[i].deviceOriginX = (long) displayRect.origin.x;   
      dCaps[i].deviceOriginY = (long) displayRect.origin.y;   
      dCaps[i].deviceDepth = (short) _getDictLong (dispMode,  
                                              kCGDisplayBitsPerPixel);    
      dCaps[i].deviceRefresh = (short) (_getDictDouble (dispMode,
                                        kCGDisplayRefreshRate) + 0.5); 
    }    

    { // get renderer info based on gDevice
      CGLRendererInfoObj info;
        long j;
        GLint numRenderers = 0;
        GLint rv = 0;
      CGLError theErr2 = 0;
      
      theErr2 = CGLQueryRendererInfo (dCaps[i].cglDisplayMask, 
                                  &info, 
                                  &numRenderers);
      if(0 == theErr2) {
        CGLDescribeRenderer (info, 0, kCGLRPRendererCount, &numRenderers);
        for (j = 0; j < numRenderers; j++) {
          // find accelerated renderer (assume only one)
          CGLDescribeRenderer (info, j, kCGLRPAccelerated, &rv); 
          if (true == rv) { // if accelerated
            // what is the renderer ID
            CGLDescribeRenderer (info, j, kCGLRPRendererID,
                                 &dCaps[i].rendererID);
            // can we do full screen?
            CGLDescribeRenderer (info, j, kCGLRPFullScreen, &rv); 
            dCaps[i].fullScreenCapable = (bool) rv;
            // what is the VRAM?
            CGLDescribeRenderer (info, j, kCGLRPVideoMemory,
                                 &dCaps[i].deviceVRAM);
            // what is the current texture memory? 
            CGLDescribeRenderer (info, j, kCGLRPTextureMemory,
                                 &dCaps[i].deviceTextureRAM);
            break; // done
          }
        }
      }
      CGLDestroyRendererInfo (info);
    }

    { // build context and context specific info
      CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask,
                                            dCaps[i].cglDisplayMask, 
                                            (CGLPixelFormatAttribute)0 };
      CGLPixelFormatObj pixelFormat = NULL;
      GLint numPixelFormats = 0;
      CGLContextObj cglContext;
      
      curr_ctx = CGLGetCurrentContext (); // get current CGL context
      CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats);
      if (pixelFormat) {
        CGLCreateContext(pixelFormat, NULL, &cglContext);
        CGLDestroyPixelFormat (pixelFormat);
        CGLSetCurrentContext (cglContext);
        if (cglContext) {
          const GLubyte * strExt;
          const GLubyte * strRend;
          const GLubyte * strVers;
          const GLubyte * strVend;

          // get renderer strings
          strRend = glGetString (GL_RENDERER);
          strncpy (dCaps[i].strRendererName, (char *) strRend, 255);
          strVend = glGetString (GL_VENDOR);
          strncpy (dCaps[i].strRendererVendor, (char *) strVend, 255);
          strVers = glGetString (GL_VERSION);
          strncpy (dCaps[i].strRendererVersion, (char *) strVers, 255);
          { // get BCD version
            short j = 0;
            short shiftVal = 8;
            while (((strVers[j] <= '9') && (strVers[j] >= '0')) ||
                                            (strVers[j] == '.')) { 
            // get only basic version info (until first non-digit or non-.)
              if ((strVers[j] <= '9') && (strVers[j] >= '0')) {
                dCaps[i].glVersion += (strVers[j] - '0') << shiftVal;
                shiftVal -= 4;
              }
              j++;
            }
          }
          strExt = glGetString (GL_EXTENSIONS);

          // get caps
          glGetIntegerv (GL_MAX_TEXTURE_UNITS, 
                         &dCaps[i].textureUnits);
          glGetIntegerv (GL_MAX_TEXTURE_SIZE,
                         &dCaps[i].maxTextureSize); 
          glGetIntegerv (GL_MAX_3D_TEXTURE_SIZE, 
                         &dCaps[i].max3DTextureSize);
          glGetIntegerv (GL_MAX_CUBE_MAP_TEXTURE_SIZE, 
                         &dCaps[i].maxCubeMapTextureSize);

          // get functionality info
		  dCaps[i].fSpecularVector = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_specular_vector", strExt);
          dCaps[i].fTransformHint = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_transform_hint", strExt);
          dCaps[i].fPackedPixels = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_packed_pixels", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_packed_pixel", strExt)  || 
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fClientStorage = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_client_storage", strExt);
          dCaps[i].fYCbCr = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_ycbcr_422", strExt);
          dCaps[i].fTextureRange = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_texture_range", strExt);
          dCaps[i].fFence = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_fence", strExt);
          dCaps[i].fVAR = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_vertex_array_range", strExt);
          dCaps[i].fVAO = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_vertex_array_object", strExt);
          dCaps[i].fElementArray = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_element_array", strExt);
          dCaps[i].fVPEvals = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_vertex_program_evaluators",strExt);
          dCaps[i].fFloatPixels = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_float_pixels", strExt);
          dCaps[i].fFlushRenderer = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_flush_render", strExt);
          dCaps[i].fPixelBuffer = 
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_pixel_buffer", strExt);
          dCaps[i].fImaging = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fTransposeMatrix = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_transpose_matrix", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fMultitexture = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_multitexture", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexEnvAdd = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_env_add", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_env_add", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexEnvCombine = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_env_combine", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexEnvDot3 = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_env_dot3", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexEnvCrossbar = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_env_crossbar", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fTexCubeMap = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_cube_map", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexCompress = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_compression", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fMultisample = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_multisample", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fTexBorderClamp = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_border_clamp", strExt) ||
			  (dCaps[i].glVersion >= 0x0130);
          dCaps[i].fPointParam = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_point_parameters", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fVertexProg = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_vertex_program", strExt);
          dCaps[i].fFragmentProg = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_fragment_program", strExt);
          dCaps[i].fTexMirrorRepeat = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_mirrored_repeat", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fDepthTex = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_depth_texture", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fShadow = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_shadow", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fShadowAmbient = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_shadow_ambient", strExt);
          dCaps[i].fVertexBlend = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_vertex_blend", strExt);
          dCaps[i].fWindowPos = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_window_pos", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fTex3D = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture3D", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fClipVolHint = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_clip_volume_hint", strExt);
          dCaps[i].fRescaleNorm = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_rescale_normal", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fBlendColor = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_blend_color", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fBlendMinMax = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_blend_minmax", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fBlendSub = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_blend_subtract", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fCVA = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_compiled_vertex_array", strExt);
          dCaps[i].fTexLODBias = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_lod_bias", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fABGR = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_abgr", strExt);
          dCaps[i].fBGRA = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_bgra", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fTexFilterAniso = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_filter_anisotropic",strExt);
          dCaps[i].fPaletteTex = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_paletted_texture", strExt);
          dCaps[i].fShareTexPalette = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_shared_texture_palette", strExt);
          dCaps[i].fSecColor = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_secondary_color", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fTexCompressS3TC = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_compression_s3tc", strExt);
          dCaps[i].fTexRect = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_rectangle", strExt);
          dCaps[i].fFogCoord = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_fog_coord", strExt);
          dCaps[i].fDrawRangeElements = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_draw_range_elements", strExt);
          dCaps[i].fStencilWrap = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_stencil_wrap", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fBlendFuncSep = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_blend_func_separate", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fMultiDrawArrays = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_multi_draw_arrays", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fShadowFunc = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_shadow_funcs", strExt);
          dCaps[i].fStencil2Side = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_stencil_two_side", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fColorSubtable = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_color_subtable", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fConvolution = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_convolution", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fHistogram = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_histogram", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fColorTable = 
			  gluCheckExtension ((const GLubyte *) "GL_SGI_color_table", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fColorMatrix = 
			  gluCheckExtension ((const GLubyte *) "GL_SGI_color_matrix", strExt) || 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
          dCaps[i].fTexEdgeClamp = 
			  gluCheckExtension ((const GLubyte *) "GL_SGIS_texture_edge_clamp", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fGenMipmap = 
			  gluCheckExtension ((const GLubyte *) "GL_SGIS_generate_mipmap", strExt);
          dCaps[i].fTexLOD = 
			  gluCheckExtension ((const GLubyte *) "GL_SGIS_texture_lod", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
          dCaps[i].fPointCull = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_point_cull_mode", strExt);
          dCaps[i].fTexMirrorOnce = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_texture_mirror_once", strExt);
          dCaps[i].fPNtriangles = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_pn_triangles", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_ATIX_pn_triangles", strExt);
          dCaps[i].fTextFragShader = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_text_fragment_shader", strExt);
          dCaps[i].fATIBlendEqSep = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_blend_equation_separate", strExt);
          dCaps[i].fBlendWeightMinMax = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_blend_weighted_minmax", strExt);
          dCaps[i].fCombine3 = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_texture_env_combine3", strExt);
          dCaps[i].fSepStencil = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_separate_stencil", strExt);
          dCaps[i].fArrayRevComps4Byte = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_array_rev_comps_in_4_bytes",strExt);
          dCaps[i].fNVPointSprite = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_point_sprite", strExt);
          dCaps[i].fRegCombiners = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_register_combiners", strExt);
          dCaps[i].fRegCombiners2 = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_register_combiners2", strExt);
          dCaps[i].fTexEnvCombine4 = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_texture_env_combine4", strExt);
          dCaps[i].fBlendSquare = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_blend_square", strExt) ||
			  (dCaps[i].glVersion >= 0x0140);
          dCaps[i].fFogDist = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_fog_distance", strExt);
          dCaps[i].fMultisampleFilterHint = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_multisample_filter_hint", strExt);
          dCaps[i].fTexGenReflect = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_texgen_reflection", strExt);
          dCaps[i].fTexShader = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_texture_shader", strExt);
          dCaps[i].fTexShader2 = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_texture_shader2", strExt);
          dCaps[i].fTexShader3 = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_texture_shader3", strExt);
          dCaps[i].fDepthClamp = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_depth_clamp", strExt);
          dCaps[i].fLightMaxExp = 
			  gluCheckExtension ((const GLubyte *) "GL_NV_light_max_exponent", strExt);
          dCaps[i].fRasterPosClip = 
			  gluCheckExtension ((const GLubyte *) "GL_IBM_rasterpos_clip", strExt);
          dCaps[i].fConvBorderModes = 
			  gluCheckExtension ((const GLubyte *) "GL_HP_convolution_border_modes", strExt) ||
			  gluCheckExtension ((const GLubyte *) "GL_ARB_imaging", strExt);
		  dCaps[i].fAuxDeptStencil =
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_aux_depth_stencil", strExt);
		  dCaps[i].fFlushBufferRange =
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_flush_buffer_range", strExt);
		  dCaps[i].fObjectPurgeable =
			  gluCheckExtension ((const GLubyte *) "GL_APPLE_object_purgeable", strExt);
		  dCaps[i].fDrawBuffers =
			  gluCheckExtension ((const GLubyte *) "GL_ARB_draw_buffers", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fFragmentProgShadow =
			  gluCheckExtension ((const GLubyte *) "GL_ARB_fragment_program_shadow", strExt);
		  dCaps[i].fFragmentShader = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_fragment_shader", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fHalfFloatPixel = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_half_float_pixel", strExt);
		  dCaps[i].fOcclusionQuery = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_occlusion_query", strExt) ||
			  (dCaps[i].glVersion >= 0x0150);
		  dCaps[i].fPBO = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_pixel_buffer_object", strExt) ||
			  (dCaps[i].glVersion >= 0x0210);
		  dCaps[i].fPointSprite = 			
			  gluCheckExtension ((const GLubyte *) "GL_ARB_point_sprite", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fShaderObjects = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_shader_objects", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fShaderTextureLOD = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_shader_texture_lod", strExt);
		  dCaps[i].fShadingLanguage100 =
			  gluCheckExtension ((const GLubyte *) "GL_ARB_shading_language_100", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fTexFloat =
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_float", strExt);
		  dCaps[i].fTexNPOT = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_texture_non_power_of_two", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fVBO = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_vertex_buffer_object", strExt) ||
			  (dCaps[i].glVersion >= 0x0150);
		  dCaps[i].fVertexShader = 
			  gluCheckExtension ((const GLubyte *) "GL_ARB_vertex_shader", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fTexComp3dc = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_texture_compression_3dc", strExt);
		  dCaps[i].fTexATIfloat = 
			  gluCheckExtension ((const GLubyte *) "GL_ATI_texture_float", strExt);
		  dCaps[i].fBlendEqSep = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_blend_equation_separate", strExt) ||
			  (dCaps[i].glVersion >= 0x0200);
		  dCaps[i].fDepthBounds = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_depth_bounds_test", strExt);
		  dCaps[i].fFBOblit =
			  gluCheckExtension ((const GLubyte *) "GL_EXT_framebuffer_blit", strExt);
		  dCaps[i].fFBO = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_framebuffer_object", strExt);
		  dCaps[i].fGeometryShader4 = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_geometry_shader4", strExt);
		  dCaps[i].fGPUProgParams = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_gpu_program_parameters", strExt);
		  dCaps[i].fGPUShader4 = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_gpu_shader4", strExt);
		  dCaps[i].fDepthStencil = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_packed_depth_stencil", strExt);
		  dCaps[i].fSepSpecColor = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_separate_specular_color", strExt) ||
			  (dCaps[i].glVersion >= 0x0120);
		  dCaps[i].fTexCompDXT1 =
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_compression_dxt1", strExt);
		  dCaps[i].fTexMirrorClamp = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_mirror_clamp", strExt);
		  dCaps[i].fTexSRGB = 
			  gluCheckExtension ((const GLubyte *) "GL_EXT_texture_sRGB", strExt) ||
			  (dCaps[i].glVersion >= 0x0210);		  
		  
		  if (dCaps[i].fTexRect) // only check if extension supported
				glGetIntegerv (GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT,
							   &dCaps[i].maxRectTextureSize);
			else
				dCaps[i].maxRectTextureSize = 0;
			
          CGLDestroyContext (cglContext);
        }
      }
      CGLSetCurrentContext (curr_ctx); // reset current CGL context
    }
  }
}
Beispiel #9
0
AGLPixelFormat Window::chooseAGLPixelFormat()
{
    Global::enterCarbon();

    CGOpenGLDisplayMask glDisplayMask =
        CGDisplayIDToOpenGLDisplayMask( _impl->cgDisplayID );

    // build attribute list
    std::vector<GLint> attributes;

    attributes.push_back( AGL_RGBA );
    attributes.push_back( GL_TRUE );
    attributes.push_back( AGL_ACCELERATED );
    attributes.push_back( GL_TRUE );

    if( getIAttribute( WindowSettings::IATTR_HINT_FULLSCREEN ) == ON )
        attributes.push_back( AGL_FULLSCREEN );

    attributes.push_back( AGL_DISPLAY_MASK );
    attributes.push_back( glDisplayMask );

    GLint colorSize = getIAttribute( WindowSettings::IATTR_PLANES_COLOR );
    if( colorSize != OFF )
    {
        switch( colorSize )
        {
        case RGBA16F:
            attributes.push_back( AGL_COLOR_FLOAT );
            colorSize = 16;
            break;
        case RGBA32F:
            attributes.push_back( AGL_COLOR_FLOAT );
            colorSize = 32;
            break;
        case AUTO:
            colorSize = 8;
            break;
        default:
            break;
        }

        attributes.push_back( AGL_RED_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( AGL_GREEN_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( AGL_BLUE_SIZE );
        attributes.push_back( colorSize );

        const int alphaSize = getIAttribute( WindowSettings::IATTR_PLANES_ALPHA );
        if( alphaSize > 0 || alphaSize == AUTO )
        {
            attributes.push_back( AGL_ALPHA_SIZE );
            attributes.push_back( alphaSize > 0 ? alphaSize : colorSize );
        }
    }

    const int depthSize = getIAttribute( WindowSettings::IATTR_PLANES_DEPTH );
    if( depthSize > 0 || depthSize == AUTO )
    {
        attributes.push_back( AGL_DEPTH_SIZE );
        attributes.push_back( depthSize>0 ? depthSize : 24 );
    }
    const int stencilSize = getIAttribute( WindowSettings::IATTR_PLANES_STENCIL );
    if( stencilSize > 0 || stencilSize == AUTO )
    {
        attributes.push_back( AGL_STENCIL_SIZE );
        attributes.push_back( stencilSize>0 ? stencilSize : 1 );
    }
    const int accumSize  = getIAttribute( WindowSettings::IATTR_PLANES_ACCUM );
    const int accumAlpha = getIAttribute( WindowSettings::IATTR_PLANES_ACCUM_ALPHA );
    if( accumSize >= 0 )
    {
        attributes.push_back( AGL_ACCUM_RED_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_GREEN_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_BLUE_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha >= 0 ? accumAlpha : accumSize );
    }
    else if( accumAlpha >= 0 )
    {
        attributes.push_back( AGL_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha );
    }

    const int samplesSize  = getIAttribute( WindowSettings::IATTR_PLANES_SAMPLES );
    if( samplesSize >= 0 )
    {
        attributes.push_back( AGL_SAMPLE_BUFFERS_ARB );
        attributes.push_back( 1 );
        attributes.push_back( AGL_SAMPLES_ARB );
        attributes.push_back( samplesSize );
    }

    if( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == ON ||
            ( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
              getIAttribute( WindowSettings::IATTR_HINT_DRAWABLE )     == WINDOW ))
    {
        attributes.push_back( AGL_DOUBLEBUFFER );
        attributes.push_back( GL_TRUE );
    }
    if( getIAttribute( WindowSettings::IATTR_HINT_STEREO ) == ON )
    {
        attributes.push_back( AGL_STEREO );
        attributes.push_back( GL_TRUE );
    }

    attributes.push_back( AGL_NONE );

    // build backoff list, least important attribute last
    std::vector<int> backoffAttributes;
    if( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
            getIAttribute( WindowSettings::IATTR_HINT_DRAWABLE )     == WINDOW  )

        backoffAttributes.push_back( AGL_DOUBLEBUFFER );

    if( stencilSize == AUTO )
        backoffAttributes.push_back( AGL_STENCIL_SIZE );

    // choose pixel format
    AGLPixelFormat pixelFormat = 0;
    while( true )
    {
        pixelFormat = aglCreatePixelFormat( &attributes.front( ));

        if( pixelFormat ||              // found one or
                backoffAttributes.empty( )) // nothing else to try

            break;

        // Gradually remove backoff attributes
        const GLint attribute = backoffAttributes.back();
        backoffAttributes.pop_back();

        std::vector<GLint>::iterator iter = find( attributes.begin(),
                                            attributes.end(), attribute );
        LBASSERT( iter != attributes.end( ));

        attributes.erase( iter, iter+2 ); // remove two item (attr, value)
    }

    if( !pixelFormat )
        sendError( ERROR_SYSTEMWINDOW_PIXELFORMAT_NOTFOUND );

    Global::leaveCarbon();
    return pixelFormat;
}
Beispiel #10
0
screenshot* capture() {
    CGContextRef bitmap;
    CGImageRef image;
    void * data;
    long bytewidth;
    GLint width, height;
    long bytes;
    CGColorSpaceRef cSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);

	    CGLContextObj    glContextObj;
    CGLPixelFormatObj pixelFormatObj ;
    long numPixelFormats ;
	
    CGLPixelFormatAttribute attribs[] =
    {
        kCGLPFAFullScreen,
        kCGLPFADisplayMask,
        0,    /* Display mask bit goes here */
        0
    } ;


    if ( display == kCGNullDirectDisplay )
        display = CGMainDisplayID();
    attribs[2] = CGDisplayIDToOpenGLDisplayMask(display);


    /* Build a full-screen GL context */
    CGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats );
    if ( pixelFormatObj == NULL )    // No full screen context support
        return NULL;
    CGLCreateContext( pixelFormatObj, NULL, &glContextObj ) ;
    CGLDestroyPixelFormat( pixelFormatObj ) ;
    if ( glContextObj == NULL )
        return NULL;


    CGLSetCurrentContext( glContextObj ) ;
    CGLSetFullScreen( glContextObj ) ;


    glReadBuffer(GL_FRONT);


    width = srcRect.size.width;
    height = srcRect.size.height;


    bytewidth = width * 4; // Assume 4 bytes/pixel for now
    bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
    bytes = bytewidth * height; // width * height

    /* Build bitmap context */
    data = malloc(height * bytewidth);
    if ( data == NULL )
    {
        CGLSetCurrentContext( NULL );
        CGLClearDrawable( glContextObj ); // disassociate from full screen
        CGLDestroyContext( glContextObj ); // and destroy the context
        return NULL;
    }
    bitmap = CGBitmapContextCreate(data, width, height, 8, bytewidth,
                                   cSpace, kCGImageAlphaNoneSkipFirst /* XRGB */);
    CFRelease(cSpace);


    /* Read framebuffer into our bitmap */
    glFinish(); /* Finish all OpenGL commands */
    glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

    /*
     * Fetch the data in XRGB format, matching the bitmap context.
     */
    glReadPixels(
			(GLint) srcRect.origin.x,
			(GLint)srcRect.origin.y,
			width,
			height,
			GL_BGRA,
			#ifdef __BIG_ENDIAN__
            GL_UNSIGNED_INT_8_8_8_8_REV, // for PPC
			#else
            GL_UNSIGNED_INT_8_8_8_8, // for Intel! http://lists.apple.com/archives/quartz-dev/2006/May/msg00100.html
			#endif
            data);
    /*
     * glReadPixels generates a quadrant I raster, with origin in the lower left
     * This isn't a problem for signal processing routines such as compressors,
     * as they can simply use a negative 'advance' to move between scanlines.
     * CGImageRef and CGBitmapContext assume a quadrant III raster, though, so we need to
     * invert it. Pixel reformatting can also be done here.
     */
    swizzleBitmap(data, bytewidth, height);


    /* Make an image out of our bitmap; does a cheap vm_copy of the bitmap */
    image = CGBitmapContextCreateImage(bitmap);

    /* Get rid of bitmap */
    CFRelease(bitmap);
    free(data);


    /* Get rid of GL context */
    CGLSetCurrentContext( NULL );
    CGLClearDrawable( glContextObj ); // disassociate from full screen
    CGLDestroyContext( glContextObj ); // and destroy the context

    /* Returned image has a reference count of 1 */
    return image;
}
Beispiel #11
0
bool RTCALL VBoxOglIs3DAccelerationSupported()
{
    if (RTEnvExist("VBOX_CROGL_FORCE_SUPPORTED"))
    {
        LogRel(("VBOX_CROGL_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n"));
        return true;
    }

    CGDirectDisplayID   display = CGMainDisplayID ();
    CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask (display);
    CGLPixelFormatObj   pixelFormat = NULL;
    GLint numPixelFormats = 0;
    CGLError            rcCgl;

    CGLPixelFormatAttribute attribs[] = {
        kCGLPFADisplayMask,
        (CGLPixelFormatAttribute)cglDisplayMask,
        kCGLPFAAccelerated,
        kCGLPFADoubleBuffer,
        VBoxOglIsOfflineRenderingAppropriate() ? kCGLPFAAllowOfflineRenderers : (CGLPixelFormatAttribute)NULL,
        (CGLPixelFormatAttribute)NULL
    };

    display = CGMainDisplayID();
    cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(display);
    rcCgl = CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats);
    if (rcCgl != kCGLNoError)
    {
        LogRel(("OpenGL Info: 3D test unable to choose pixel format (rcCgl=0x%X)\n", rcCgl));
        return false;
    }

    if (pixelFormat)
    {
        CGLContextObj cglContext = 0;
        rcCgl = CGLCreateContext(pixelFormat, NULL, &cglContext);
        CGLDestroyPixelFormat(pixelFormat);

        if (rcCgl != kCGLNoError)
        {
            LogRel(("OpenGL Info: 3D test unable to create context (rcCgl=0x%X)\n", rcCgl));
            return false;
        }

        if (cglContext)
        {
            GLboolean isSupported = GL_TRUE;
#ifdef VBOX_WITH_COCOA_QT
            /* On the Cocoa port we depend on the GL_EXT_framebuffer_object &
             * the GL_EXT_texture_rectangle extension. If they are not
             * available, disable 3D support. */
            CGLSetCurrentContext(cglContext);
            const GLubyte* strExt;
            strExt = glGetString(GL_EXTENSIONS);
            isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_framebuffer_object", strExt);
            if (isSupported)
            {
                isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_texture_rectangle", strExt);
                if (!isSupported)
                    LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported\n"));
            }
            else
                LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported\n"));
#endif /* VBOX_WITH_COCOA_QT */
            CGLDestroyContext(cglContext);
            LogRel(("OpenGL Info: 3D test %spassed\n", isSupported == GL_TRUE ? "" : "not "));
            return isSupported == GL_TRUE ? true : false;
        }
        else
            LogRel(("OpenGL Info: 3D test unable to create context (internal error)\n"));
    }
    else
        LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error)\n"));

    return false;
}
Beispiel #12
0
static int RLXAPI CreateSurface(int numberOfSparePages)
{
    CGOpenGLDisplayMask displayMask = CGDisplayIDToOpenGLDisplayMask( g_cgDisplayID ) ;
    static CGLPixelFormatAttribute attribs[32];
	CGLPixelFormatAttribute	*pAttrib =  attribs;
    CGLPixelFormatObj pixelFormatObj ;
    long numPixelFormats = 0;

	*pAttrib = kCGLPFAFullScreen; pAttrib++;
	*pAttrib = kCGLPFASingleRenderer; pAttrib++;

	*pAttrib = kCGLPFADisplayMask; pAttrib++;
	*pAttrib = (CGLPixelFormatAttribute)displayMask; pAttrib++;

	*pAttrib = kCGLPFADoubleBuffer; pAttrib++;
	*pAttrib = kCGLPFAColorSize; pAttrib++;
	*pAttrib = (CGLPixelFormatAttribute)gl_bpp; pAttrib++;

	 if ((g_pRLX->pGX->View.Flags & GX_CAPS_MULTISAMPLING))
	{
		*pAttrib = kCGLPFASampleBuffers; pAttrib++;
		*pAttrib = (CGLPixelFormatAttribute)1;  pAttrib++;

		*pAttrib = kCGLPFASamples;  pAttrib++;
		*pAttrib = (CGLPixelFormatAttribute)g_pRLX->pGX->View.Multisampling; pAttrib++;
	}

	if (SYS_CGLTRACE(CGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats )))
		return -1;

    if (!numPixelFormats)
        return -2;

	DEBUG_PIXEL_FORMAT(pixelFormatObj);

    if (SYS_CGLTRACE(CGLCreateContext( pixelFormatObj, NULL, &g_pCGLC )))
       return -3;

    CGLDestroyPixelFormat( pixelFormatObj ) ;

    long swapInterval = !!(g_pRLX->pGX->View.Flags & GX_CAPS_VSYNC);
    SYS_CGLTRACE(CGLSetParameter( g_pCGLC, kCGLCPSwapInterval, &swapInterval));
    SYS_CGLTRACE(CGLSetCurrentContext( g_pCGLC ));
    if (SYS_CGLTRACE(CGLSetFullScreen( g_pCGLC )))
	{
		CGDisplaySwitchToMode(g_cgDisplayID, g_cgPrevDisplayMode);
		CGReleaseAllDisplays();

		return -5;
	}

	HideMenuBar();

    // Reset engine
    GL_InstallExtensions();
	GL_ResetViewport();

	g_pRLX->pGX->Surfaces.maxSurface = numberOfSparePages;;

	if (g_pRLX->pGX->View.Flags & GX_CAPS_MULTISAMPLING)
	{
		glEnable(GL_MULTISAMPLE_ARB);
	}

    return 0;
}
Beispiel #13
0
int  _glfwPlatformOpenWindow( int width, int height,
                              const _GLFWwndconfig *wndconfig,
                              const _GLFWfbconfig *fbconfig )
{
    OSStatus error;
    unsigned int windowAttributes;
    ProcessSerialNumber psn;

    // TODO: Break up this function!

    _glfwWin.windowUPP      = NULL;
    _glfwWin.mouseUPP       = NULL;
    _glfwWin.keyboardUPP    = NULL;
    _glfwWin.commandUPP     = NULL;
    _glfwWin.window         = NULL;
    _glfwWin.aglContext     = NULL;
    _glfwWin.aglPixelFormat = NULL;
    _glfwWin.cglContext     = NULL;
    _glfwWin.cglPixelFormat = NULL;

    _glfwWin.refreshRate = wndconfig->refreshRate;

    // Fail if OpenGL 3.0 or above was requested
    if( wndconfig->glMajor > 2 )
    {
        fprintf( stderr, "OpenGL 3.0+ is not yet supported on Mac OS X\n" );

        _glfwPlatformCloseWindow();
        return GL_FALSE;
    }

    if( _glfwLibrary.Unbundled )
    {
        if( GetCurrentProcess( &psn ) != noErr )
        {
            fprintf( stderr, "Failed to get the process serial number\n" );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        if( TransformProcessType( &psn, kProcessTransformToForegroundApplication ) != noErr )
        {
            fprintf( stderr, "Failed to become a foreground application\n" );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        if( wndconfig->mode == GLFW_FULLSCREEN )
        {
            if( SetFrontProcess( &psn ) != noErr )
            {
                fprintf( stderr, "Failed to become the front process\n" );

                _glfwPlatformCloseWindow();
                return GL_FALSE;
            }
        }
    }

    if( !installEventHandlers() )
    {
        fprintf( stderr,
                 "Failed to install Carbon application event handlers\n" );

        _glfwPlatformTerminate();
        return GL_FALSE;
    }

    // Windowed or fullscreen; AGL or CGL? Quite the mess...
    // AGL appears to be the only choice for attaching OpenGL contexts to
    // Carbon windows, but it leaves the user no control over fullscreen
    // mode stretching. Solution: AGL for windowed, CGL for fullscreen.
    if( wndconfig->mode == GLFW_WINDOW )
    {
        // create AGL pixel format attribute list
        GLint AGLpixelFormatAttributes[256];
        int numAGLAttrs = 0;

        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_RGBA;
        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_DOUBLEBUFFER;
        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_CLOSEST_POLICY;

        if( fbconfig->stereo )
        {
            AGLpixelFormatAttributes[numAGLAttrs++] = AGL_STEREO;
        }

        _setAGLAttribute( AGL_AUX_BUFFERS,      fbconfig->auxBuffers);
        _setAGLAttribute( AGL_RED_SIZE,         fbconfig->redBits );
        _setAGLAttribute( AGL_GREEN_SIZE,       fbconfig->greenBits );
        _setAGLAttribute( AGL_BLUE_SIZE,        fbconfig->blueBits );
        _setAGLAttribute( AGL_ALPHA_SIZE,       fbconfig->alphaBits );
        _setAGLAttribute( AGL_DEPTH_SIZE,       fbconfig->depthBits );
        _setAGLAttribute( AGL_STENCIL_SIZE,     fbconfig->stencilBits );
        _setAGLAttribute( AGL_ACCUM_RED_SIZE,   fbconfig->accumRedBits );
        _setAGLAttribute( AGL_ACCUM_GREEN_SIZE, fbconfig->accumGreenBits );
        _setAGLAttribute( AGL_ACCUM_BLUE_SIZE,  fbconfig->accumBlueBits );
        _setAGLAttribute( AGL_ACCUM_ALPHA_SIZE, fbconfig->accumAlphaBits );

        if( fbconfig->samples > 1 )
        {
            _setAGLAttribute( AGL_SAMPLE_BUFFERS_ARB, 1 );
            _setAGLAttribute( AGL_SAMPLES_ARB, fbconfig->samples );
            AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NO_RECOVERY;
        }

        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NONE;

        // create pixel format descriptor
        AGLDevice mainMonitor = GetMainDevice();
        _glfwWin.aglPixelFormat = aglChoosePixelFormat( &mainMonitor,
                                                        1,
                                                        AGLpixelFormatAttributes );
        if( _glfwWin.aglPixelFormat == NULL )
        {
            fprintf( stderr,
                     "Failed to choose AGL pixel format: %s\n",
                     aglErrorString( aglGetError() ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // create AGL context
        _glfwWin.aglContext = aglCreateContext( _glfwWin.aglPixelFormat, NULL );

        if( _glfwWin.aglContext == NULL )
        {
            fprintf( stderr,
                     "Failed to create AGL context: %s\n",
                     aglErrorString( aglGetError() ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // create window
        Rect windowContentBounds;
        windowContentBounds.left = 0;
        windowContentBounds.top = 0;
        windowContentBounds.right = width;
        windowContentBounds.bottom = height;

        windowAttributes = ( kWindowCloseBoxAttribute |
                             kWindowCollapseBoxAttribute |
                             kWindowStandardHandlerAttribute );

        if( wndconfig->windowNoResize )
        {
            windowAttributes |= kWindowLiveResizeAttribute;
        }
        else
        {
            windowAttributes |= ( kWindowFullZoomAttribute |
                                  kWindowResizableAttribute );
        }

        error = CreateNewWindow( kDocumentWindowClass,
                                 windowAttributes,
                                 &windowContentBounds,
                                 &( _glfwWin.window ) );
        if( ( error != noErr ) || ( _glfwWin.window == NULL ) )
        {
            fprintf( stderr, "Failed to create Carbon window\n" );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        _glfwWin.windowUPP = NewEventHandlerUPP( windowEventHandler );

        error = InstallWindowEventHandler( _glfwWin.window,
                                           _glfwWin.windowUPP,
                                           GetEventTypeCount( GLFW_WINDOW_EVENT_TYPES ),
                                           GLFW_WINDOW_EVENT_TYPES,
                                           NULL,
                                           NULL );
        if( error != noErr )
        {
            fprintf( stderr, "Failed to install Carbon window event handler\n" );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // Don't care if we fail here
        (void)SetWindowTitleWithCFString( _glfwWin.window, CFSTR( "GLFW Window" ) );
        (void)RepositionWindow( _glfwWin.window,
                                NULL,
                                kWindowCenterOnMainScreen );

        if( !aglSetDrawable( _glfwWin.aglContext,
                             GetWindowPort( _glfwWin.window ) ) )
        {
            fprintf( stderr,
                     "Failed to set the AGL context as the Carbon window drawable: %s\n",
                     aglErrorString( aglGetError() ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // Make OpenGL context current
        if( !aglSetCurrentContext( _glfwWin.aglContext ) )
        {
            fprintf( stderr,
                     "Failed to make AGL context current: %s\n",
                     aglErrorString( aglGetError() ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        ShowWindow( _glfwWin.window );
    }
    else
    {
        CGDisplayErr cgErr;
        CGLError cglErr;

        CFDictionaryRef optimalMode;

        GLint numCGLvs = 0;

        CGLPixelFormatAttribute CGLpixelFormatAttributes[64];
        int numCGLAttrs = 0;

        // variables for enumerating color depths
        GLint rgbColorDepth;

        // CGL pixel format attributes
        _setCGLAttribute( kCGLPFADisplayMask,
                          CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ) );

        if( fbconfig->stereo )
        {
            CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAStereo;
        }

        if( fbconfig->samples > 1 )
        {
            _setCGLAttribute( kCGLPFASamples,       (CGLPixelFormatAttribute)fbconfig->samples );
            _setCGLAttribute( kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1 );
            CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
        }

        CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAFullScreen;
        CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFADoubleBuffer;
        CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAAccelerated;
        CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
        CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAMinimumPolicy;

        _setCGLAttribute( kCGLPFAAccumSize,
                          (CGLPixelFormatAttribute)( fbconfig->accumRedBits \
                                                   + fbconfig->accumGreenBits \
                                                   + fbconfig->accumBlueBits \
                                                   + fbconfig->accumAlphaBits ) );

        _setCGLAttribute( kCGLPFAAlphaSize,   (CGLPixelFormatAttribute)fbconfig->alphaBits );
        _setCGLAttribute( kCGLPFADepthSize,   (CGLPixelFormatAttribute)fbconfig->depthBits );
        _setCGLAttribute( kCGLPFAStencilSize, (CGLPixelFormatAttribute)fbconfig->stencilBits );
        _setCGLAttribute( kCGLPFAAuxBuffers,  (CGLPixelFormatAttribute)fbconfig->auxBuffers );

        CGLpixelFormatAttributes[ numCGLAttrs++ ] = (CGLPixelFormatAttribute)NULL;

        // create a suitable pixel format with above attributes..
        cglErr = CGLChoosePixelFormat( CGLpixelFormatAttributes,
                                       &_glfwWin.cglPixelFormat,
                                       &numCGLvs );
        if( cglErr != kCGLNoError )
        {
            fprintf( stderr,
                     "Failed to choose CGL pixel format: %s\n",
                     CGLErrorString( cglErr ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // ..and create a rendering context using that pixel format
        cglErr = CGLCreateContext( _glfwWin.cglPixelFormat, NULL, &_glfwWin.cglContext );
        if( cglErr != kCGLNoError )
        {
            fprintf( stderr,
                     "Failed to create CGL context: %s\n",
                     CGLErrorString( cglErr ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // enumerate depth of RGB channels - unlike AGL, CGL works with
        // a single parameter reflecting the full depth of the frame buffer
        (void)CGLDescribePixelFormat( _glfwWin.cglPixelFormat,
                                      0,
                                      kCGLPFAColorSize,
                                      &rgbColorDepth );

        // capture the display for our application
        cgErr = CGCaptureAllDisplays();
        if( cgErr != kCGErrorSuccess )
        {
            fprintf( stderr,
                     "Failed to capture Core Graphics displays\n");

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // find closest matching NON-STRETCHED display mode..
        optimalMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty(
                            kCGDirectMainDisplay,
                            rgbColorDepth,
                            width,
                            height,
                            wndconfig->refreshRate,
                            NULL,
                            NULL );
        if( optimalMode == NULL )
        {
            fprintf( stderr,
                     "Failed to retrieve Core Graphics display mode\n");

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // ..and switch to that mode
        cgErr = CGDisplaySwitchToMode( kCGDirectMainDisplay, optimalMode );
        if( cgErr != kCGErrorSuccess )
        {
            fprintf( stderr,
                     "Failed to switch to Core Graphics display mode\n");

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // switch to our OpenGL context, and bring it up fullscreen
        cglErr = CGLSetCurrentContext( _glfwWin.cglContext );
        if( cglErr != kCGLNoError )
        {
            fprintf( stderr,
                     "Failed to make CGL context current: %s\n",
                     CGLErrorString( cglErr ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        cglErr = CGLSetFullScreen( _glfwWin.cglContext );
        if( cglErr != kCGLNoError )
        {
            fprintf( stderr,
                     "Failed to set CGL fullscreen mode: %s\n",
                     CGLErrorString( cglErr ) );

            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }
    }

    return GL_TRUE;
}
Beispiel #14
0
i_img *
imss_darwin(i_img_dim left, i_img_dim top, i_img_dim right, i_img_dim bottom) {
  CGDisplayCount count;
  CGDisplayErr err;
  CGRect rect;
  CGLPixelFormatObj pix;
  GLint npix;
  CGLContextObj ctx;
  i_img *im;
  CGDirectDisplayID disp;
  i_img_dim screen_width, screen_height;
  i_img_dim width, height;

  CGLPixelFormatAttribute pix_attrs[] =
    {
      kCGLPFADisplayMask, 0, /* filled in later */
      kCGLPFAColorSize, 24,
      kCGLPFAAlphaSize, 0,
      kCGLPFAFullScreen,
      0
    };

  i_clear_error();

  disp = CGMainDisplayID();
  if (!disp) {
    i_push_error(0, "No main display");
    return NULL;
  }
  
  /* for now, only interested in the first display */
  rect = CGDisplayBounds(disp);
  screen_width = rect.size.width;
  screen_height = rect.size.height;

  /* adjust negative/zero values to window size */
  if (left < 0)
    left += screen_width;
  if (top < 0)
    top += screen_height;
  if (right <= 0)
    right += screen_width;
  if (bottom <= 0)
    bottom += screen_height;
  
  /* clamp */
  if (left < 0)
    left = 0;
  if (right > screen_width)
    right = screen_width;
  if (top < 0)
    top = 0;
  if (bottom > screen_height)
    bottom = screen_height;

  /* validate */
  if (right <= left || bottom <= top) {
    i_push_error(0, "image would be empty");
    return NULL;
  }

  width = right - left;
  height = bottom - top;

  /* select a pixel format */
  pix_attrs[1] = CGDisplayIDToOpenGLDisplayMask(disp);
  err = CGLChoosePixelFormat(pix_attrs, &pix, &npix);
  if (err) {
    i_push_errorf(err, "CGLChoosePixelFormat: %d", (int)err);
    return NULL;
  }
  if (!npix) {
    i_push_error(0, "No pixel format found - hidden display?");
    return NULL;
  }

  /* make ourselves a context */
  err = CGLCreateContext(pix, NULL, &ctx);
  CGLDestroyPixelFormat(pix);
  if (err) {
    i_push_errorf(err, "CGLCreateContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetCurrentContext(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetCurrentContext: %d", (int)err);
    return NULL;
  }

  err = CGLSetFullScreen(ctx);
  if (err) {
    i_push_errorf(err, "CGLSetFullScreen: %d", (int)err);
    return NULL;
  }

  /* capture */
  im = i_img_8_new(width, height, 3);
  if (im) {
    size_t line_size = width * 4; 
    size_t buf_size = line_size * height;
    unsigned char *buf = malloc(buf_size);
    i_img_dim y = height - 1;
    i_color *bufp = (i_color *)buf; /* hackish */

    /* GL has the vertical axis going from bottom to top, so translate it */

    glReadBuffer(GL_FRONT);
    glReadPixels(left, screen_height - top - height, width, height,
		 GL_RGBA, GL_UNSIGNED_BYTE, buf);

    /* transfer */
    while (y >= 0) {
      i_plin(im, 0, width, y, bufp);
      bufp += width;
      --y;
    }
    
    free(buf);

    i_tags_setn(&im->tags, "ss_window_width", width);
    i_tags_setn(&im->tags, "ss_window_height", height);
    i_tags_set(&im->tags, "ss_type", "Darwin", 6);
    i_tags_set(&im->tags, "ss_variant", "<11", 3);
    i_tags_setn(&im->tags, "ss_left", left);
    i_tags_setn(&im->tags, "ss_top", top);
  }

  /* clean up */
  CGLSetCurrentContext(NULL);
  CGLDestroyContext(ctx);

  return im;
}
int doMain (int argc, char **argv)
{
    int dummy;

    // OSG init

    OSG::osgInit(argc, argv);

    // create the graph

    // beacon for camera and light
    OSG::NodeUnrecPtr b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1 = OSG::Group::create();
    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1 = OSG::Transform::create();
    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light

    OSG::NodeUnrecPtr dlight = OSG::Node::create();
    OSG::DirectionalLightUnrecPtr dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );

    dl->setAmbient( .3, .3, .3, 1 );
    dl->setDiffuse( 1, 1, 1, 1 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();
    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file

    OSG::NodeUnrecPtr file = NULL;

    if ( argc > 1 )
        file = OSG::SceneFileHandler::the()->read(argv[1]);

    if ( file == NULL )
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;
        file = OSG::makeTorus( .5, 2, 16, 16 );
    }

    OSG::Thread::getCurrentChangeList()->commitChanges();
    file->updateVolume();

    OSG::Vec3f min,max;
    file->getVolume().getBounds( min, max );

    std::cout << "Volume: from " << min << " to " << max << std::endl;

    dlight->addChild( file );

    std::cerr << "Tree: " << std::endl;
    //root->dump();

    // Camera
    cam = OSG::PerspectiveCamera::create();

    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 90 ) );
    cam->setNear( 0.1 );
    cam->setFar( 100000 );

    // Background
    OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();

    bkgnd->setColor(OSG::Color3f(0,0,1));

    // Viewport

    vp = OSG::Viewport::create();
    vp->setCamera( cam );
    vp->setBackground( bkgnd );
    vp->setRoot( root );
    vp->setSize( 0,0, 1,1 );

    // Action

    ract = OSG::RenderAction::create();

    // tball

    OSG::Vec3f pos;
    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                       min[1] + (max[1] - min[1]) / 2,
                       min[2] + (max[2] - min[2]) / 2);
    
    tball.setMode( OSG::Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( OSG::Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(tCenter);

    // CoreGL init

    // Install event handler
    EventHandlerUPP eventHandlerUPP = NewEventHandlerUPP(eventHandler);
    EventTypeSpec eventList[] =
    {
        { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
        { kEventClassMouse, kEventMouseDown },
        { kEventClassMouse, kEventMouseUp },
        { kEventClassMouse, kEventMouseDragged }
    };
    InstallApplicationEventHandler(eventHandlerUPP, GetEventTypeCount(eventList), eventList, 0, 0);

    CGDisplayCapture(kCGDirectMainDisplay);
    CGLPixelFormatAttribute attribs[] =
    {
        kCGLPFADoubleBuffer,
        kCGLPFAFullScreen,
        kCGLPFADepthSize,
        (CGLPixelFormatAttribute)16,
        kCGLPFADisplayMask,
        (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
        (CGLPixelFormatAttribute)0
    };
    CGLPixelFormatObj pixelFormatObj;
    GLint numPixelFormats;
    CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); 

    CGLContextObj contextObj;
    CGLCreateContext(pixelFormatObj, 0, &contextObj);

    CGLDestroyPixelFormat(pixelFormatObj);

    CGLSetCurrentContext(contextObj);
    CGLSetFullScreen(contextObj);

    // Create OpenSG window
    win = OSG::CoreGLWindow::create();
    win->addPort( vp );             
    win->setContext ( contextObj );
    win->init();
    win->resize( CGDisplayPixelsWide(kCGDirectMainDisplay), CGDisplayPixelsHigh(kCGDirectMainDisplay) );

    win->activate();

    // do some OpenGL init. Will move into State Chunks later.

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    redraw();

    // Main loop ( event dispatching )
    RunApplicationEventLoop();

    // Cleanup
    CGLSetCurrentContext(0);
    CGLClearDrawable(contextObj);
    CGLDestroyContext(contextObj);
    CGReleaseAllDisplays();
    DisposeEventHandlerUPP(eventHandlerUPP);

    ract      = NULL;
    win       = NULL;
    root      = NULL;
    file      = NULL;
    vp        = NULL;
    cam_trans = NULL;
    cam       = NULL;

    return 0;
}
Beispiel #16
0
int screen_InitCapture( demux_t *p_demux )
{
    demux_sys_t   *p_sys = p_demux->p_sys;
    screen_data_t *p_data;
    CGLPixelFormatAttribute attribs[4];
    CGLPixelFormatObj pix;
    GLint npix;
    GLint viewport[4];
    GLuint displayMask;
    CGLError returnedError;

    p_sys->p_data = p_data =
        ( screen_data_t * )malloc( sizeof( screen_data_t ) );

    attribs[0] = kCGLPFAFullScreen;
    attribs[1] = kCGLPFADisplayMask;
    attribs[2] = CGDisplayIDToOpenGLDisplayMask( CGMainDisplayID() );
    attribs[3] = 0;

    returnedError = CGLChoosePixelFormat( attribs, &pix, &npix );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLCreateContext( pix, NULL, &( p_data->screen ) );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLDestroyPixelFormat( pix );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLSetCurrentContext( p_data->screen );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLSetFullScreen( p_data->screen );
    if (returnedError)
        goto errorHandling;

    glGetIntegerv( GL_VIEWPORT, viewport );

    p_data->screen_width = viewport[2];
    p_data->screen_height = viewport[3];

    p_data->left = p_sys->i_left;
    p_data->top = p_sys->i_top;
    p_data->src_width = var_CreateGetInteger( p_demux, "screen-width" );
    p_data->src_height = var_CreateGetInteger( p_demux, "screen-height" );
    if (p_data->src_width <= 0 || p_data->src_height <= 0) {
      p_data->src_width = p_data->screen_width;
      p_data->src_height = p_data->screen_height;
    }
    p_data->dest_width = p_data->src_width;
    p_data->dest_height = p_data->src_height;

    attribs [0] = kCGLPFAOffScreen;
    attribs [1] = kCGLPFAColorSize;
    attribs [2] = 32;
    attribs [3] = 0;

    returnedError = CGLChoosePixelFormat( attribs, &pix, &npix );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLCreateContext( pix, NULL, &( p_data->scaled ) );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLDestroyPixelFormat( pix );
    if (returnedError)
        goto errorHandling;

    returnedError = CGLSetCurrentContext( p_data->scaled );
    if (returnedError)
        goto errorHandling;

    p_data->scaled_image = ( char * )malloc( p_data->dest_width
                                          * p_data->dest_height * 4 );
#warning FIXME: CGLSetOffScreen is no longer supported in the future!
    returnedError = CGLSetOffScreen( p_data->scaled, p_data->dest_width, p_data->dest_height, p_data->dest_width * 4, p_data->scaled_image );
    if (returnedError)
        goto errorHandling;

    es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_RGB32 );

    /* p_sys->fmt.video.i_* must set to screen size, not subscreen size */
    p_sys->fmt.video.i_width = p_data->screen_width;
    p_sys->fmt.video.i_visible_width = p_data->screen_width;
    p_sys->fmt.video.i_height = p_data->screen_height;
    p_sys->fmt.video.i_bits_per_pixel = 32;

    glGenTextures( 1, &( p_data->texture ) );
    glBindTexture( GL_TEXTURE_2D, p_data->texture );

    p_data->texture_image
      = ( char * )malloc( p_data->src_width * p_data->src_height * 4 );

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

    glGenTextures( 1, &( p_data->cursor_texture ) );
    glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture );

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

    CGSNewConnection( NULL, &( p_data->connection ) );

    return VLC_SUCCESS;

    errorHandling:
    msg_Err( p_demux, "Core OpenGL failure: %s", CGLErrorString( returnedError ) );
    return VLC_EGENERIC;
}
Beispiel #17
0
void CocoaVideoDriver::loop(Card* initial) {
    CGLPixelFormatAttribute attrs[] = {
        kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
        kCGLPFADisplayMask, static_cast<CGLPixelFormatAttribute>(
                CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay)),
        kCGLPFAColorSize, static_cast<CGLPixelFormatAttribute>(24),
        kCGLPFADoubleBuffer,
        kCGLPFAAccelerated,
        static_cast<CGLPixelFormatAttribute>(0),
    };

    cgl::PixelFormat pixel_format(attrs);
    cgl::Context context(pixel_format.c_obj(), NULL);
    unique_ptr<CocoaFullscreen> fullscreen;
    unique_ptr<CocoaWindowed> windowed;
    if (_fullscreen) {
        fullscreen.reset(new CocoaFullscreen(pixel_format, context, _screen_size));
        antares_event_translator_set_window(_translator.c_obj(), fullscreen->window());
        _viewport_size = fullscreen->viewport_size();
    } else {
        windowed.reset(new CocoaWindowed(pixel_format, context, _screen_size, false, true));
        antares_event_translator_set_window(_translator.c_obj(), windowed->window());
        _viewport_size = windowed->viewport_size();
    }
    GLint swap_interval = 1;
    CGLSetParameter(context.c_obj(), kCGLCPSwapInterval, &swap_interval);
    CGLSetCurrentContext(context.c_obj());

    MainLoop main_loop(*this, initial);
    main_loop.draw();
    CGLFlushDrawable(context.c_obj());
    EventBridge bridge = {_event_tracker, main_loop, context, _translator};

    antares_event_translator_set_mouse_down_callback(
            _translator.c_obj(), EventBridge::mouse_down, &bridge);
    antares_event_translator_set_mouse_up_callback(
            _translator.c_obj(), EventBridge::mouse_up, &bridge);
    antares_event_translator_set_mouse_move_callback(
            _translator.c_obj(), EventBridge::mouse_move, &bridge);
    antares_event_translator_set_caps_lock_callback(
            _translator.c_obj(), EventBridge::caps_lock, &bridge);
    antares_event_translator_set_caps_unlock_callback(
            _translator.c_obj(), EventBridge::caps_unlock, &bridge);

    cf::MutableDictionary keyboard(CFDictionaryCreateMutable(
                NULL, 0,
                &kCFCopyStringDictionaryKeyCallBacks,
                &kCFTypeDictionaryValueCallBacks));
    keyboard.set(CFSTR(kIOHIDDeviceUsagePageKey), cf::wrap(kHIDPage_GenericDesktop).c_obj());
    keyboard.set(CFSTR(kIOHIDDeviceUsageKey), cf::wrap(kHIDUsage_GD_Keyboard).c_obj());
    cf::MutableDictionary gamepad(CFDictionaryCreateMutable(
                NULL, 0,
                &kCFCopyStringDictionaryKeyCallBacks,
                &kCFTypeDictionaryValueCallBacks));
    gamepad.set(CFSTR(kIOHIDDeviceUsagePageKey), cf::wrap(kHIDPage_GenericDesktop).c_obj());
    gamepad.set(CFSTR(kIOHIDDeviceUsageKey), cf::wrap(kHIDUsage_GD_GamePad).c_obj());
    cf::MutableArray criteria(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
    criteria.append(keyboard.c_obj());
    criteria.append(gamepad.c_obj());

    auto hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
    IOHIDManagerSetDeviceMatchingMultiple(hid_manager, criteria.c_obj());
    IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    IOReturn r = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
    if (r != 0) {
        throw Exception("IOHIDManagerOpen");
    }
    IOHIDManagerRegisterInputValueCallback(hid_manager, EventBridge::hid_event, &bridge);

    while (!main_loop.done()) {
        int64_t at;
        if (main_loop.top()->next_timer(at)) {
            at += _start_time;
            if (antares_event_translator_next(_translator.c_obj(), at)) {
                bridge.send_all();
            } else {
                main_loop.top()->fire_timer();
                main_loop.draw();
                CGLFlushDrawable(context.c_obj());
            }
        } else {
            at = std::numeric_limits<int64_t>::max();
            antares_event_translator_next(_translator.c_obj(), at);
            bridge.send_all();
        }
    }
}
Beispiel #18
0
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect)
{
#if defined(IS_MACOSX)
	/* The following is a very modified version of the glGrab code example
	 * given by Apple (as are some of the convenience functions called). */
	size_t bytewidth;
	uint8_t bitsPerPixel, bytesPerPixel;
	uint8_t *buffer;

	/* Build OpenGL context of entire screen */
	CGDirectDisplayID displayID = CGMainDisplayID();
	CGOpenGLDisplayMask mask = CGDisplayIDToOpenGLDisplayMask(displayID);
	CGLContextObj glContext = createFullScreenCGLContext(mask);
	if (glContext == NULL) return NULL;

	/* TODO: CGDisplayBitsPerPixel() is deprecated in Snow Leopard; I'm not
	 * sure of the replacement function. */
	bitsPerPixel = (uint8_t)CGDisplayBitsPerPixel(displayID);
	bytesPerPixel = bitsPerPixel / 8;

	/* Align width to padding. */
	bytewidth = ADD_PADDING(rect.size.width * bytesPerPixel);

	/* Convert Quartz point to postscript point. */
	rect.origin.y = CGDisplayPixelsHigh(displayID) - rect.origin.y - rect.size.height;

	/* Extract buffer from context */
	buffer = createBufferFromCurrentCGLContext((GLint)rect.origin.x,
	                                           (GLint)rect.origin.y,
	                                           (GLsizei)rect.size.width,
	                                           (GLsizei)rect.size.height,
	                                           bytewidth);
	/* Reset and release GL context */
	destroyFullScreenCGLContext(glContext);
	if (buffer == NULL) return NULL;

	/* Convert from OpenGL (origin at bottom left) to Quartz (origin at top
	 * left) coordinate system. */
	flipBitmapData(buffer, rect.size.width, rect.size.height, bytewidth);

	return createMMBitmap(buffer, rect.size.width, rect.size.height, bytewidth,
	                      bitsPerPixel, bytesPerPixel);
#elif defined(USE_X11)
	MMBitmapRef bitmap;

	Display *display = XOpenDisplay(NULL);
	XImage *image = XGetImage(display,
	                          XDefaultRootWindow(display),
	                          (int)rect.origin.x,
	                          (int)rect.origin.y,
	                          (unsigned int)rect.size.width,
	                          (unsigned int)rect.size.height,
	                          AllPlanes, ZPixmap);
	XCloseDisplay(display);
	if (image == NULL) return NULL;

	bitmap = createMMBitmap((uint8_t *)image->data,
	                        rect.size.width,
	                        rect.size.height,
	                        (size_t)image->bytes_per_line,
	                        (uint8_t)image->bits_per_pixel,
	                        (uint8_t)image->bits_per_pixel / 8);
	image->data = NULL; /* Steal ownership of bitmap data so we don't have to
	                     * copy it. */
	XDestroyImage(image);

	return bitmap;
#elif defined(IS_WINDOWS)
	MMBitmapRef bitmap;
	void *data;
	HDC screen = NULL, screenMem = NULL;
	HBITMAP dib;
	BITMAPINFO bi;

	/* Initialize bitmap info. */
	bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
   	bi.bmiHeader.biWidth = (long)rect.size.width;
   	bi.bmiHeader.biHeight = -(long)rect.size.height; /* Non-cartesian, please */
   	bi.bmiHeader.biPlanes = 1;
   	bi.bmiHeader.biBitCount = 32;
   	bi.bmiHeader.biCompression = BI_RGB;
   	bi.bmiHeader.biSizeImage = (DWORD)(4 * rect.size.width * rect.size.height);
	bi.bmiHeader.biXPelsPerMeter = 0;
	bi.bmiHeader.biYPelsPerMeter = 0;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;

	screen = GetDC(NULL); /* Get entire screen */
	if (screen == NULL) return NULL;

	/* Get screen data in display device context. */
   	dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0);

	/* Copy the data into a bitmap struct. */
	if ((screenMem = CreateCompatibleDC(screen)) == NULL ||
	    SelectObject(screenMem, dib) == NULL ||
	    !BitBlt(screenMem, 
	            (int)rect.origin.x, 
	            (int)rect.origin.y, 
	            (int)rect.size.width,
	            (int)rect.size.height, screen, 0, 0, SRCCOPY)) {
		/* Error copying data. */
		ReleaseDC(NULL, screen);
		DeleteObject(dib);
		if (screenMem != NULL) DeleteDC(screenMem);

		return NULL;
	}

	bitmap = createMMBitmap(NULL,
	                        rect.size.width,
	                        rect.size.height,
	                        4 * rect.size.width,
	                        (uint8_t)bi.bmiHeader.biBitCount, 
	                        4);

	/* Copy the data to our pixel buffer. */
	if (bitmap != NULL) {
		bitmap->imageBuffer = malloc(bitmap->bytewidth * bitmap->height);
		memcpy(bitmap->imageBuffer, data, bitmap->bytewidth * bitmap->height);
	}

	ReleaseDC(NULL, screen);
	DeleteObject(dib);
	DeleteDC(screenMem);

	return bitmap;
#endif
}
Beispiel #19
0
int screen_InitCapture( demux_t *p_demux )
{
    demux_sys_t   *p_sys = p_demux->p_sys;
    screen_data_t *p_data;
    CGLError returnedError;
    unsigned int i;

    p_sys->p_data = p_data =
        ( screen_data_t * )calloc( 1, sizeof( screen_data_t ) );

    p_data->display_id = kCGDirectMainDisplay;

    unsigned int displayCount;
    displayCount = 0;
    returnedError = CGGetOnlineDisplayList( 0, NULL, &displayCount );
    if( !returnedError )
    {
        CGDirectDisplayID *ids;
        ids = ( CGDirectDisplayID * )malloc( displayCount * sizeof( CGDirectDisplayID ) );
        returnedError = CGGetOnlineDisplayList( displayCount, ids, &displayCount );
        if( !returnedError )
        {
            if ( p_sys->i_display_id > 0 )
            {
                for( i = 0; i < displayCount; i ++ )
                {
                    if( p_sys->i_display_id == ids[i] )
                    {
                        p_data->display_id = ids[i];
                        break;
                    }
                }
            }
            else if ( p_sys->i_screen_index > 0 && p_sys->i_screen_index <= displayCount )
            {
                p_data->display_id = ids[p_sys->i_screen_index - 1];
            }
        }
        free( ids );
    }

    /* CGImage Function
     *   CGDisplayCreateImageForRect is available in Mac OS X v10.6 and later */

    p_data->myCGDisplayCreateImageForRect = NULL;

    CFURLRef frameworkURL = NULL;
    CFStringRef path = CFSTR( "file://localhost/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework" );
    frameworkURL = CFURLCreateWithString( kCFAllocatorDefault, path, NULL );
    if( frameworkURL != NULL )
    {
        p_data->bundle = CFBundleCreate( kCFAllocatorDefault, frameworkURL );
        if( p_data->bundle != NULL )
        {
            p_data->myCGDisplayCreateImageForRect =
                ( typeofCGDisplayCreateImageForRect )CFBundleGetFunctionPointerForName
                ( p_data->bundle, CFSTR( "CGDisplayCreateImageForRect" ) );
        }

        CFRelease( frameworkURL );
    }

    /* Screen Size */

    CGRect rect = CGDisplayBounds( p_data->display_id );
    p_data->screen_left = rect.origin.x;
    p_data->screen_top = rect.origin.y;
    p_data->screen_width = rect.size.width;
    p_data->screen_height = rect.size.height;

    p_data->width = p_sys->i_width;
    p_data->height = p_sys->i_height;
    if( p_data->width <= 0 || p_data->height <= 0 )
    {
        p_data->width = p_data->screen_width;
        p_data->height = p_data->screen_height;
    }

    /* Screen Context */

    if( p_data->myCGDisplayCreateImageForRect == NULL )
    {
        returnedError =
            screen_CreateContext( &p_data->screen,
                                  kCGLPFAFullScreen,
                                  kCGLPFADisplayMask,
                                  ( CGLPixelFormatAttribute )CGDisplayIDToOpenGLDisplayMask( p_data->display_id ),
                                  ( CGLPixelFormatAttribute )0 );
        if( returnedError )
            goto errorHandling;

        returnedError = CGLSetCurrentContext( p_data->screen );
        if( returnedError )
            goto errorHandling;

        returnedError = CGLSetFullScreen( p_data->screen );
        if( returnedError )
            goto errorHandling;
    }

    /* Clipped Context */

    returnedError =
        screen_CreateContext( &p_data->clipped,
                              kCGLPFAOffScreen,
                              kCGLPFAColorSize,
                              ( CGLPixelFormatAttribute )32,
                              ( CGLPixelFormatAttribute )0 );
    if( returnedError )
        goto errorHandling;

    returnedError = CGLSetCurrentContext( p_data->clipped );
    if( returnedError )
        goto errorHandling;

    /* Clipped Image */

    p_data->clipped_image =
        ( char * )malloc( p_data->width * p_data->height * 4 );

    returnedError = CGLSetOffScreen( p_data->clipped, p_data->width, p_data->height, p_data->width * 4, p_data->clipped_image );
    if( returnedError )
        goto errorHandling;

    /* Screen Image */

    if( p_data->myCGDisplayCreateImageForRect != NULL )
    {
        p_data->screen_image =
            ( char * )malloc( p_data->screen_width * p_data->screen_height * 4 );
    }
    else
    {
        p_data->screen_image =
            ( char * )malloc( p_data->width * p_data->height * 4 );
    }

    /* Cursor */

    CGSNewConnection( NULL, &( p_data->connection ) );

    p_data->cursor_need_update = 1;
    p_data->cursor_seed = 0;

    glGenTextures( 1, &( p_data->cursor_texture ) );
    glBindTexture( GL_TEXTURE_2D, p_data->cursor_texture );

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

    /* System */

    es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_RGB32 );

    /* p_sys->fmt.video.i_* must set to screen size, not subscreen size */
    p_sys->fmt.video.i_width = p_data->screen_width;
    p_sys->fmt.video.i_visible_width = p_data->screen_width;
    p_sys->fmt.video.i_height = p_data->screen_height;
    p_sys->fmt.video.i_bits_per_pixel = 32;

    return VLC_SUCCESS;

    errorHandling:
    msg_Err( p_demux, "Core OpenGL failure: %s", CGLErrorString( returnedError ) );
    return VLC_EGENERIC;
}
Beispiel #20
0
int  _glfwPlatformOpenWindow( int width,
                              int height,
                              int redbits,
                              int greenbits,
                              int bluebits,
                              int alphabits,
                              int depthbits,
                              int stencilbits,
                              int mode,
                              _GLFWhints* hints )
{
    OSStatus error;
    ProcessSerialNumber psn;

    unsigned int windowAttributes;

    // TO DO: Refactor this function!
    _glfwWin.WindowFunctions = ( _glfwWin.Fullscreen ?
                               &_glfwMacFSWindowFunctions :
                               &_glfwMacDWWindowFunctions );

    // Windowed or fullscreen; AGL or CGL? Quite the mess...
    // AGL appears to be the only choice for attaching OpenGL contexts to
    // Carbon windows, but it leaves the user no control over fullscreen
    // mode stretching. Solution: AGL for windowed, CGL for fullscreen.
    if( !_glfwWin.Fullscreen )
    {
        // create AGL pixel format attribute list
        GLint AGLpixelFormatAttributes[256];
        int numAGLAttrs = 0;

        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_RGBA;
        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_DOUBLEBUFFER;

        if( hints->Stereo )
        {
            AGLpixelFormatAttributes[numAGLAttrs++] = AGL_STEREO;
        }

        _setAGLAttribute( AGL_AUX_BUFFERS,      hints->AuxBuffers);
        _setAGLAttribute( AGL_RED_SIZE,         redbits );
        _setAGLAttribute( AGL_GREEN_SIZE,       greenbits );
        _setAGLAttribute( AGL_BLUE_SIZE,        bluebits );
        _setAGLAttribute( AGL_ALPHA_SIZE,       alphabits );
        _setAGLAttribute( AGL_DEPTH_SIZE,       depthbits );
        _setAGLAttribute( AGL_STENCIL_SIZE,     stencilbits );
        _setAGLAttribute( AGL_ACCUM_RED_SIZE,   hints->AccumRedBits );
        _setAGLAttribute( AGL_ACCUM_GREEN_SIZE, hints->AccumGreenBits );
        _setAGLAttribute( AGL_ACCUM_BLUE_SIZE,  hints->AccumBlueBits );
        _setAGLAttribute( AGL_ACCUM_ALPHA_SIZE, hints->AccumAlphaBits );

	if( hints->Samples > 1 )
	{
	    _setAGLAttribute( AGL_SAMPLE_BUFFERS_ARB, 1 );
	    _setAGLAttribute( AGL_SAMPLES_ARB, hints->Samples );
	    AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NO_RECOVERY;
	}

        AGLpixelFormatAttributes[numAGLAttrs++] = AGL_NONE;

        // create pixel format descriptor
        AGLDevice mainMonitor = GetMainDevice();
        AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor,
                                                           1,
                                                           AGLpixelFormatAttributes );
        if( pixelFormat == NULL )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't create a pixel format\n" );
            return GL_FALSE;
        }

        // store pixel format's values for _glfwPlatformGetWindowParam's use
        _getAGLAttribute( AGL_ACCELERATED,      _glfwWin.Accelerated );
        _getAGLAttribute( AGL_RED_SIZE,         _glfwWin.RedBits );
        _getAGLAttribute( AGL_GREEN_SIZE,       _glfwWin.GreenBits );
        _getAGLAttribute( AGL_BLUE_SIZE,        _glfwWin.BlueBits );
        _getAGLAttribute( AGL_ALPHA_SIZE,       _glfwWin.AlphaBits );
        _getAGLAttribute( AGL_DEPTH_SIZE,       _glfwWin.DepthBits );
        _getAGLAttribute( AGL_STENCIL_SIZE,     _glfwWin.StencilBits );
        _getAGLAttribute( AGL_ACCUM_RED_SIZE,   _glfwWin.AccumRedBits );
        _getAGLAttribute( AGL_ACCUM_GREEN_SIZE, _glfwWin.AccumGreenBits );
        _getAGLAttribute( AGL_ACCUM_BLUE_SIZE,  _glfwWin.AccumBlueBits );
        _getAGLAttribute( AGL_ACCUM_ALPHA_SIZE, _glfwWin.AccumAlphaBits );
        _getAGLAttribute( AGL_AUX_BUFFERS,      _glfwWin.AuxBuffers );
        _getAGLAttribute( AGL_STEREO,           _glfwWin.Stereo );
        _getAGLAttribute( AGL_SAMPLES_ARB,      _glfwWin.Samples );
        _glfwWin.RefreshRate = hints->RefreshRate;

        // create AGL context
        _glfwWin.AGLContext = aglCreateContext( pixelFormat, NULL );

        aglDestroyPixelFormat( pixelFormat );

        if( _glfwWin.AGLContext == NULL )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't create an OpenGL context\n" );
            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        if (_glfwLibrary.Unbundled)
        {
            if( GetCurrentProcess( &psn ) != noErr )
            {
                fprintf( stderr, "glfwOpenWindow failing because it can't get its PSN\n" );
                _glfwPlatformCloseWindow();
                return GL_FALSE;
            }

    	    if( TransformProcessType( &psn, kProcessTransformToForegroundApplication ) != noErr )
            {
                fprintf( stderr, "glfwOpenWindow failing because it can't become a foreground application\n" );
                _glfwPlatformCloseWindow();
                return GL_FALSE;
            }
            
            /* Keith Bauer 2007-07-12 - I don't believe this is desirable
    	    if( SetFrontProcess( &psn ) != noErr )
            {
                fprintf( stderr, "glfwOpenWindow failing because it can't become the front process\n" );
                _glfwPlatformCloseWindow();
                return GL_FALSE;
            }
            */
        }
	    
        // create window
        Rect windowContentBounds;
        windowContentBounds.left = 0;
        windowContentBounds.top = 0;
        windowContentBounds.right = width;
        windowContentBounds.bottom = height;

        windowAttributes = ( kWindowCloseBoxAttribute        \
                           | kWindowCollapseBoxAttribute     \
                           | kWindowStandardHandlerAttribute );

        if( hints->WindowNoResize )
        {
            windowAttributes |= kWindowLiveResizeAttribute;
        }
        else
        {
            windowAttributes |= ( kWindowFullZoomAttribute | kWindowResizableAttribute );
        }

        error = CreateNewWindow( kDocumentWindowClass,
                                 windowAttributes,
                                 &windowContentBounds,
                                 &( _glfwWin.MacWindow ) );
        if( ( error != noErr ) || ( _glfwWin.MacWindow == NULL ) )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't create a window\n" );
            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        _glfwWin.WindowUPP = NewEventHandlerUPP( _glfwWindowEventHandler );

        error = InstallWindowEventHandler( _glfwWin.MacWindow,
                                           _glfwWin.WindowUPP,
                                           GetEventTypeCount( GLFW_WINDOW_EVENT_TYPES ),
                                           GLFW_WINDOW_EVENT_TYPES,
                                           NULL,
                                           NULL );
        if( error != noErr )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't install window event handlers\n" );
            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // Don't care if we fail here
        (void)SetWindowTitleWithCFString( _glfwWin.MacWindow, CFSTR( "GLFW Window" ) );
        (void)RepositionWindow( _glfwWin.MacWindow,
                                NULL,
                                kWindowCenterOnMainScreen );

        if( !aglSetDrawable( _glfwWin.AGLContext,
                             GetWindowPort( _glfwWin.MacWindow ) ) )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't draw to the window\n" );
            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // Make OpenGL context current
        if( !aglSetCurrentContext( _glfwWin.AGLContext ) )
        {
            fprintf( stderr, "glfwOpenWindow failing because it can't make the OpenGL context current\n" );
            _glfwPlatformCloseWindow();
            return GL_FALSE;
        }

        // show window
        ShowWindow( _glfwWin.MacWindow );

        return GL_TRUE;
    }
    else
    {
        CGDisplayErr cgErr;
        CGLError cglErr;

        CFDictionaryRef optimalMode;

        CGLPixelFormatObj CGLpfObj;
        long numCGLvs = 0;

        CGLPixelFormatAttribute CGLpixelFormatAttributes[64];
        int numCGLAttrs = 0;

        // variables for enumerating color depths
        GLint rgbColorDepth;
        GLint rgbaAccumDepth = 0;
        int rgbChannelDepth = 0;

        // CGL pixel format attributes
        _setCGLAttribute( kCGLPFADisplayMask,
                          CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ) );

        if( hints->Stereo )
        {
            CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFAStereo;
        }

	if( hints->Samples > 1 )
	{
	    _setCGLAttribute( kCGLPFASamples,       (CGLPixelFormatAttribute)hints->Samples );
	    _setCGLAttribute( kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1 );
	    CGLpixelFormatAttributes[ numCGLAttrs++ ] = kCGLPFANoRecovery;
	}

        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAFullScreen;
        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFADoubleBuffer;
        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAAccelerated;
        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFANoRecovery;
        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = kCGLPFAMinimumPolicy;

        _setCGLAttribute( kCGLPFAAccumSize,
                          (CGLPixelFormatAttribute)( hints->AccumRedBits \
                                                   + hints->AccumGreenBits \
                                                   + hints->AccumBlueBits \
                                                   + hints->AccumAlphaBits ) );

        _setCGLAttribute( kCGLPFAAlphaSize,   (CGLPixelFormatAttribute)alphabits );
        _setCGLAttribute( kCGLPFADepthSize,   (CGLPixelFormatAttribute)depthbits );
        _setCGLAttribute( kCGLPFAStencilSize, (CGLPixelFormatAttribute)stencilbits );
        _setCGLAttribute( kCGLPFAAuxBuffers,  (CGLPixelFormatAttribute)hints->AuxBuffers );

        CGLpixelFormatAttributes[ numCGLAttrs++ ]     = (CGLPixelFormatAttribute)NULL;

        // create a suitable pixel format with above attributes..
        cglErr = CGLChoosePixelFormat( CGLpixelFormatAttributes,
                                       &CGLpfObj,
                                       &numCGLvs );
        if( cglErr != kCGLNoError )
	{
	    return GL_FALSE;
	}

        // ..and create a rendering context using that pixel format
        cglErr = CGLCreateContext( CGLpfObj, NULL, &_glfwWin.CGLContext );
        if( cglErr != kCGLNoError )
	{
	    return GL_FALSE;
	}

        // enumerate depth of RGB channels - unlike AGL, CGL works with
        // a single parameter reflecting the full depth of the frame buffer
        (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAColorSize, &rgbColorDepth );
        if( rgbColorDepth == 24 || rgbColorDepth == 32 )
	{
	    rgbChannelDepth = 8;
	}
        if( rgbColorDepth == 16 )
	{
	    rgbChannelDepth = 5;
	}

        // get pixel depth of accumulator - I haven't got the slightest idea
        // how this number conforms to any other channel depth than 8 bits,
        // so this might end up giving completely knackered results...
        (void)CGLDescribePixelFormat( CGLpfObj, 0, kCGLPFAAccumSize, &rgbaAccumDepth );
        if( rgbaAccumDepth == 32 )
	{
	    rgbaAccumDepth = 8;
	}

        // store values of pixel format for _glfwPlatformGetWindowParam's use
        _getCGLAttribute( kCGLPFAAccelerated, _glfwWin.Accelerated );
        _getCGLAttribute( rgbChannelDepth,    _glfwWin.RedBits );
        _getCGLAttribute( rgbChannelDepth,    _glfwWin.GreenBits );
        _getCGLAttribute( rgbChannelDepth,    _glfwWin.BlueBits );
        _getCGLAttribute( kCGLPFAAlphaSize,   _glfwWin.AlphaBits );
        _getCGLAttribute( kCGLPFADepthSize,   _glfwWin.DepthBits );
        _getCGLAttribute( kCGLPFAStencilSize, _glfwWin.StencilBits );
        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumRedBits );
        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumGreenBits );
        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumBlueBits );
        _getCGLAttribute( rgbaAccumDepth,     _glfwWin.AccumAlphaBits );
        _getCGLAttribute( kCGLPFAAuxBuffers,  _glfwWin.AuxBuffers );
        _getCGLAttribute( kCGLPFAStereo,      _glfwWin.Stereo );
        _glfwWin.RefreshRate = hints->RefreshRate;

        // destroy our pixel format
        (void)CGLDestroyPixelFormat( CGLpfObj );

        // capture the display for our application
        cgErr = CGCaptureAllDisplays();
        if( cgErr != kCGErrorSuccess )
	{
	    return GL_FALSE;
	}

        // find closest matching NON-STRETCHED display mode..
        optimalMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty( kCGDirectMainDisplay,
	                                                                            rgbColorDepth,
	                                                                            width,
	/* Check further to the right -> */                                         height,
	                                                                            hints->RefreshRate,
	                                                                            NULL,
	                                                                            NULL );
        if( optimalMode == NULL )
	{
	    return GL_FALSE;
	}

        // ..and switch to that mode
        cgErr = CGDisplaySwitchToMode( kCGDirectMainDisplay, optimalMode );
        if( cgErr != kCGErrorSuccess )
	{
	    return GL_FALSE;
	}

        // switch to our OpenGL context, and bring it up fullscreen
        cglErr = CGLSetCurrentContext( _glfwWin.CGLContext );
        if( cglErr != kCGLNoError )
	{
	    return GL_FALSE;
	}

        cglErr = CGLSetFullScreen( _glfwWin.CGLContext );
        if( cglErr != kCGLNoError )
	{
	    return GL_FALSE;
	}

        return GL_TRUE;
    }
}
/*
    PsychOSOpenOnscreenWindow()
    
    Creates the CGL pixel format and the CGL context objects and then instantiates the context onto the screen.
    
    -The pixel format and the context are stored in the target specific field of the window recored.  Close
    should clean up by destroying both the pixel format and the context.
    
    -We mantain the context because it must be be made the current context by drawing functions to draw into 
    the specified window.
    
    -We maintain the pixel format object because there seems to be now way to retrieve that from the context.
    
    -To tell the caller to clean up PsychOSOpenOnscreenWindow returns FALSE if we fail to open the window. It 
    would be better to just issue an PsychErrorExit() and have that clean up everything allocated outside of
    PsychOpenOnscreenWindow().
    
    MK: The new option 'stereomode' allows selection of stereo display instead of mono display:
    0 (default) ==  Old behaviour -> Monoscopic rendering context.
    >0          ==  Stereo display, where the number defines the type of stereo algorithm to use.
    =1          ==  Use OpenGL built-in stereo by creating a context/window with left- and right backbuffer. This is
                    the only mode of interest here, as it requires use of a stereo capable OpenGL pixelformat. All other
                    stereo modes are implemented by PTB itself in a platform independent manner on top of a standard mono
                    context.
*/
psych_bool PsychOSOpenOnscreenWindow(PsychScreenSettingsType *screenSettings, PsychWindowRecordType *windowRecord, int numBuffers, int stereomode, int conserveVRAM)
{
    CGOpenGLDisplayMask             displayMask;
    CGLError                        error;
    CGDirectDisplayID               cgDisplayID;
    CGLPixelFormatAttribute         attribs[40];
    int                             attribcount;
    GLint                           numVirtualScreens;
    GLenum                          glerr;
    PsychRectType                   screenrect;
    int                             i;
    int                             windowLevel;
    long                            scw, sch;
    void*                           cocoaWindow = NULL;

    // Map screen number to physical display handle cgDisplayID:
    PsychGetCGDisplayIDFromScreenNumber(&cgDisplayID, screenSettings->screenNumber);
    displayMask = CGDisplayIDToOpenGLDisplayMask(cgDisplayID);

    // NULL-out Cocoa window handle, so this is well-defined in case of error:
    windowRecord->targetSpecific.windowHandle = NULL;

    // Retrieve windowLevel, an indicator of where non-CGL / non-fullscreen windows should
    // be located wrt. to other windows. -2 = Allow regular window manager control of stacking
    // order, visibility etc., -1 = Invisible/hidden, 0 = Behind everything else, occluded by
    // everything else. 1 - 999 = At layer 'windowLevel' -> Occludes stuff on layers "below" it.
    // 1000 - 1999 = At highest level, but partially translucent / alpha channel allows to make
    // regions transparent. Range 1000 - 1499 = transparent for mouse and keyboard, alpha 0-99.99%,
    // 1500-1599 = opaque for mouse and keyboard, alpha 0-99.99%, 2000 or higher: Above everything,
    // fully opaque, occludes everything, a typical fullscreen onscreen window. 2000 is the default.
    windowLevel = PsychPrefStateGet_WindowShieldingLevel();

    // Window rect provided which has same size as screen?
    // We do not use windowed mode if the provided window rectangle either
    // matches the target screens rectangle (and therefore its exact size)
    // or its screens global rectangle. In such cases we use CGL for better
    // low level control and to exclude the desktop compositor from interfering:
    PsychGetScreenRect(screenSettings->screenNumber, screenrect);
    if (PsychMatchRect(screenrect, windowRecord->rect)) windowRecord->specialflags |= kPsychIsFullscreenWindow;

    PsychGetGlobalScreenRect(screenSettings->screenNumber, screenrect);
    if (PsychMatchRect(screenrect, windowRecord->rect)) windowRecord->specialflags |= kPsychIsFullscreenWindow;

    if ((windowRecord->specialflags & kPsychIsFullscreenWindow) && (PsychPrefStateGet_Verbosity() > 3)) {
        printf("PTB-INFO: Always using Cocoa for fullscreen windows to work around graphics driver bugs in OSX.\n");
        printf("PTB-INFO: Presentation timing precision is not yet known for this configuration on most machines. Check your results.\n");
    }

    // Display for fullscreen window not captured? Timing precision is unclear in this mode. In theory the compositor should disable
    // itself for fullscreen windows on modern OSX versions. If it really does that, who knows?
    if ((windowRecord->specialflags & kPsychIsFullscreenWindow) && (PsychPrefStateGet_ConserveVRAM() & kPsychUseAGLCompositorForFullscreenWindows)) {
        // Force a window rectangle that matches the global screen rectangle for that windows screen:
        PsychCopyRect(windowRecord->rect, screenrect);

        // Warn user about what's going on:
        if (PsychPrefStateGet_Verbosity()>1) printf("PTB-INFO: No display capture / compositor lockout for fullscreen window. Timing precision is unknown.\n");
    }

    if ((windowRecord->specialflags & kPsychGUIWindow) && (PsychPrefStateGet_Verbosity() > 3)) {
        printf("PTB-INFO: Onscreen window is configured as regular GUI window.\n");
    }

    // Create onscreen Cocoa window of requested position and size:
    if (PsychCocoaCreateWindow(windowRecord, windowLevel, &cocoaWindow)) {
        printf("\nPTB-ERROR[CreateNewWindow failed]: Failed to open Cocoa onscreen window\n\n");
        return(FALSE);
    }

    // Transparent window requested?
    if ((windowLevel >= 1000) && (windowLevel < 2000)) {
        // Setup of global window alpha value for transparency. This is premultiplied to
        // the individual per-pixel alpha values if transparency is enabled by Cocoa code.
        //
        // Levels 1000 - 1499 and 1500 to 1999 map to a master opacity level of 0.0 - 1.0:
        PsychCocoaSetWindowAlpha(cocoaWindow, ((float) (windowLevel % 500)) / 499.0);
    }

    // Show it! Unless a windowLevel of -1 requests hiding the window:
    if (windowLevel != -1) PsychCocoaShowWindow(cocoaWindow);

    // If usercode wants a black startup screen then we add a pause of 0.5 seconds here
    // before proceeding. This will avoid a white flash at window open time, which might
    // be something the user wanted to avoid. Why does this help or is needed at all?
    // Nobody knows, but this is Apples ridiculous toy OS, so why even ask such questions?
    if (PsychPrefStateGet_VisualDebugLevel() < 4)
        PsychYieldIntervalSeconds(0.5);

    // Level zero means: Place behind all other windows:
    if (windowLevel == 0) PsychCocoaSendBehind(cocoaWindow);

    // Levels 1 to 999 define window levels for the group of the window.
    // A level of -2 would leave this to the system:
    if (windowLevel > 0 && windowLevel < 1000) PsychCocoaSetWindowLevel(cocoaWindow, windowLevel);

    // Is the target display captured for a fullscreen window?
    if (PsychIsScreenCaptured(screenSettings->screenNumber)) {
        // Yes. Make sure our window is above the shielding window level:
        PsychCocoaSetWindowLevel(cocoaWindow, (int) CGShieldingWindowLevel());
    }

    // Store window handle in windowRecord:
    windowRecord->targetSpecific.windowHandle = cocoaWindow;

    // Store vblank startline aka true height of physical display screen in pixels:
    PsychGetScreenPixelSize(screenSettings->screenNumber, &scw, &sch);
    windowRecord->VBL_Startline = (int) sch;

    // Define pixelformat attributes for OpenGL contexts:

    // No pixelformat attribs to start with:
    attribcount = 0;

    attribs[attribcount++]=kCGLPFADisplayMask;
    attribs[attribcount++]=displayMask;

    // 10 bit per component integer framebuffer requested (10-10-10-2)?
    if (windowRecord->depth == 30) {
        // Request a 10 bit per color component framebuffer with 2 bit alpha channel:
        printf("PTB-INFO: Trying to enable 10 bpc, 30 bit integer framebuffer...\n");
        attribs[attribcount++]=kCGLPFANoRecovery;
        attribs[attribcount++]=kCGLPFAMinimumPolicy;
        attribs[attribcount++]=kCGLPFAColorSize;
        attribs[attribcount++]=10*3;
        attribs[attribcount++]=kCGLPFAAlphaSize;
        attribs[attribcount++]=2;
    }

    // 11 bit per component integer framebuffer requested (11-11-10-0)?
    if (windowRecord->depth == 33) {
        // Request a ~ 11 bit per color component framebuffer without alpha channel:
        printf("PTB-INFO: Trying to enable 11 bpc, 32 bit integer framebuffer...\n");
        attribs[attribcount++]=kCGLPFANoRecovery;
        attribs[attribcount++]=kCGLPFAMinimumPolicy;
        attribs[attribcount++]=kCGLPFAColorSize;
        attribs[attribcount++]=32;
        attribs[attribcount++]=kCGLPFAAlphaSize;
        attribs[attribcount++]=0;
    }

    // 16 bit per component integer framebuffer requested (16-16-16-16)?
    if (windowRecord->depth == 48) {
        // Request a 16 bit per color component framebuffer:
        printf("PTB-INFO: Trying to enable 16 bpc, 64 bit integer framebuffer...\n");
        attribs[attribcount++]=kCGLPFANoRecovery;
        attribs[attribcount++]=kCGLPFAMinimumPolicy;
        attribs[attribcount++]=kCGLPFAColorSize;
        attribs[attribcount++]=16*3;
        attribs[attribcount++]=kCGLPFAAlphaSize;
        attribs[attribcount++]=16;
    }

    // 16 bit per component, 64 bit framebuffer requested (16-16-16-16)?
    if (windowRecord->depth == 64) {
        // Request a floating point framebuffer in 16-bit half-float format, i.e., RGBA = 16 bits per component.
        printf("PTB-INFO: Trying to enable 16 bpc float framebuffer...\n");
        attribs[attribcount++]=kCGLPFAColorFloat;
        attribs[attribcount++]=kCGLPFAMinimumPolicy;
        attribs[attribcount++]=kCGLPFAColorSize;
        attribs[attribcount++]=16*3;
        attribs[attribcount++]=kCGLPFAAlphaSize;
        attribs[attribcount++]=16;
    }

    // 32 bit per component, 128 bit framebuffer requested (32-32-32-32)?
    if (windowRecord->depth == 128) {
        // Request a floating point framebuffer in 32-bit float format, i.e., RGBA = 32 bits per component.
        printf("PTB-INFO: Trying to enable 32 bpc float framebuffer...\n");
        attribs[attribcount++]=kCGLPFAColorFloat;
        attribs[attribcount++]=kCGLPFAMinimumPolicy;
        attribs[attribcount++]=kCGLPFAColorSize;
        attribs[attribcount++]=32*3;
        attribs[attribcount++]=kCGLPFAAlphaSize;
        attribs[attribcount++]=32;
    }

    // Possible to request use of the Apple floating point software renderer:
    if (conserveVRAM & kPsychUseSoftwareRenderer) {
        #ifndef kCGLRendererGenericFloatID
        #define kCGLRendererGenericFloatID    0x00020400
        #endif

        attribs[attribcount++]=AGL_RENDERER_ID;
        attribs[attribcount++]=kCGLRendererGenericFloatID;
    }

    // Support for 3D rendering requested?
    if (PsychPrefStateGet_3DGfx()) {
        // Yes. Allocate a 24-Bit depth and 8-Bit stencilbuffer for this purpose:
        attribs[attribcount++]=kCGLPFADepthSize;
        attribs[attribcount++]=24;
        attribs[attribcount++]=kCGLPFAStencilSize;
        attribs[attribcount++]=8;
        // Alloc an accumulation buffer as well?
        if (PsychPrefStateGet_3DGfx() & 2) {
            // Yes: Alloc accum buffer, request 64 bpp, aka 16 bits integer per color component if possible:
            attribs[attribcount++]=kCGLPFAAccumSize;
            attribs[attribcount++]=64;
        }
    }

    if(numBuffers>=2){
        // Enable double-buffering:
        attribs[attribcount++]=kCGLPFADoubleBuffer;
        if ((conserveVRAM & kPsychDisableAUXBuffers) == 0) {
            // Allocate one or two (for mono vs. stereo display) AUX buffers for "don't clear" mode of Screen('Flip'):
            // Not clearing the framebuffer after "Flip" is implemented by storing a backup-copy of
            // the backbuffer to AUXs before flip and restoring the content from AUXs after flip.
            // Unless the imaging pipeline is active, which doesn't need AUX buffers due to internal
            // storage of fb content in its drawbufferFBO's:
            attribs[attribcount++]=kCGLPFAAuxBuffers;
            attribs[attribcount++]=(stereomode==kPsychOpenGLStereo || stereomode==kPsychCompressedTLBRStereo || stereomode==kPsychCompressedTRBLStereo) ? 2 : 1;
        }
    }

    // If stereo display output is requested with OpenGL native stereo, request a stereo-enabled rendering context.
    // This is deprecated since 10.11 El Capitan, and in fact does no longer work - OpenGL quad buffered stereo is
    // dead on 10.11 on all tested GPU's from Intel, NVidia, AMD.
    if(stereomode==kPsychOpenGLStereo) {
        attribs[attribcount++] = kCGLPFAStereo;
    }

    // Multisampled Anti-Aliasing requested?
    if (windowRecord->multiSample > 0) {
        // Request a multisample buffer:
        attribs[attribcount++]= kCGLPFASampleBuffers;
        attribs[attribcount++]= 1;
        // Request at least multiSample samples per pixel:
        attribs[attribcount++]= kCGLPFASamples;
        attribs[attribcount++]= windowRecord->multiSample;
    }

    // Finalize attribute array with NULL.
    attribs[attribcount++]=(CGLPixelFormatAttribute)NULL;

    // Init to zero:
    windowRecord->targetSpecific.pixelFormatObject = NULL;
    windowRecord->targetSpecific.glusercontextObject = NULL;
    windowRecord->targetSpecific.glswapcontextObject = NULL;

    // Try to find matching pixelformat:
    error = CGLChoosePixelFormat(attribs, &(windowRecord->targetSpecific.pixelFormatObject), &numVirtualScreens);

    // No valid pixelformat found and stereo format requested?
    if ((error || (windowRecord->targetSpecific.pixelFormatObject == NULL)) && (stereomode == kPsychOpenGLStereo)) {
        // Yep: Stereo may be the culprit. Remove the stereo attribute by overwriting it with something
        // that is essentially a no-op, specifically kCGLPFAAccelerated which is supported by all real
        // renderers that might end up in this code-path:
        for (i = 0; i < attribcount && attribs[i] != kCGLPFAStereo; i++);
        attribs[i] = kCGLPFAAccelerated;
        
        // Retry query of pixelformat without request for native OpenGL quad-buffered stereo. If we succeed, we're
        // sort of ok, as the higher-level code will fallback to stereomode kPsychFrameSequentialStereo - our own
        // homegrown frame-sequential stereo support, which may be good enough.
        error = CGLChoosePixelFormat(attribs, &(windowRecord->targetSpecific.pixelFormatObject), &numVirtualScreens);
        if (error || (windowRecord->targetSpecific.pixelFormatObject == NULL)) {
            windowRecord->targetSpecific.pixelFormatObject = NULL;
            printf("\nPTB-ERROR[ChoosePixelFormat failed: %s]: Disabling OpenGL native quad-buffered stereo did not help. Moving on...\n\n", CGLErrorString(error));
        }
    }

    // Now try if choosing a matching format for a lower multisample mode helps to get unstuck:
    if (windowRecord->multiSample > 0) {
        if (windowRecord->targetSpecific.pixelFormatObject==NULL && windowRecord->multiSample > 0) {
            // Failed. Probably due to too demanding multisample requirements: Lets lower them...
            for (i = 0; i < attribcount && attribs[i] != kCGLPFASamples; i++);
            while (windowRecord->targetSpecific.pixelFormatObject == NULL && windowRecord->multiSample > 0) {
                attribs[i+1]--;
                windowRecord->multiSample--;
                error = CGLChoosePixelFormat(attribs, &(windowRecord->targetSpecific.pixelFormatObject), &numVirtualScreens);
            }

            if (windowRecord->multiSample == 0 && windowRecord->targetSpecific.pixelFormatObject == NULL) {
                // Ok, multisampling is now at zero and we still don't succeed. Disable multisampling completely:
                for (i=0; i<attribcount && attribs[i]!=kCGLPFASampleBuffers; i++);
                attribs[i+1] = 0;
                printf("\nPTB-ERROR[ChoosePixelFormat failed: %s]: Disabling multisample anti-aliasing did not help. Moving on...\n\n", CGLErrorString(error));
            }
        }
    }

    // Try choosing a matching display configuration again and create the window and rendering context:
    // If one of these two fails, then the installed gfx hardware is not good enough to satisfy our
    // requirements, or we have massive ressource shortage in the system. -> Screwed up anyway, so we abort.
    if (windowRecord->targetSpecific.pixelFormatObject == NULL) error = CGLChoosePixelFormat(attribs, &(windowRecord->targetSpecific.pixelFormatObject), &numVirtualScreens);
    if (error) {
        printf("\nPTB-ERROR[ChoosePixelFormat failed: %s]: Reason unknown. There could be insufficient video memory or a driver malfunction. Giving up.\n\n", CGLErrorString(error));
        return(FALSE);
    }

    // Create an OpenGL rendering context with the selected pixelformat: Share its ressources with 'slaveWindow's context, if slaveWindow is non-NULL.
    // If slaveWindow is non-NULL here, then slaveWindow is typically another onscreen window. Therefore this establishes OpenGL resource sharing across
    // different onscreen windows in a session, e.g., for multi-display operation:
    error=CGLCreateContext(windowRecord->targetSpecific.pixelFormatObject, ((windowRecord->slaveWindow) ? windowRecord->slaveWindow->targetSpecific.contextObject : NULL),
                           &(windowRecord->targetSpecific.contextObject));
    if (error) {
        printf("\nPTB-ERROR[ContextCreation failed: %s]: Could not create master OpenGL context for new onscreen window. Insufficient video memory?\n\n", CGLErrorString(error));
        return(FALSE);
    }

    // Enable the OpenGL rendering context associated with our window:
    error=CGLSetCurrentContext(windowRecord->targetSpecific.contextObject);
    if (error) {
        printf("\nPTB-ERROR[SetCurrentContext failed: %s]: Insufficient video memory\n\n", CGLErrorString(error));
        return(FALSE);
    }

    // NULL-out the AGL context field, just for safety...
    windowRecord->targetSpecific.deviceContext = NULL;

    // Ok, the master OpenGL rendering context for this new onscreen window is up and running.
    // Auto-detect and bind all available OpenGL extensions via GLEW:
    glerr = glewInit();
    if (GLEW_OK != glerr)
    {
        /* Problem: glewInit failed, something is seriously wrong. */
        printf("\nPTB-ERROR[GLEW init failed: %s]: Please report this to the forum. Will try to continue, but may crash soon!\n\n", glewGetErrorString(glerr));
        fflush(NULL);
    }
    else {
        if (PsychPrefStateGet_Verbosity()>3) printf("PTB-INFO: Using GLEW version %s for automatic detection of OpenGL extensions...\n", glewGetString(GLEW_VERSION));
    }

    // Enable multisampling if it was requested:
    if (windowRecord->multiSample > 0) glEnable(GL_MULTISAMPLE);

    // External 3D graphics support enabled?
    if (PsychPrefStateGet_3DGfx()) {
        // Yes. We need to create an extra OpenGL rendering context for the external
        // OpenGL code to provide optimal state-isolation. The context shares all
        // heavyweight ressources likes textures, FBOs, VBOs, PBOs, shader, display lists and
        // starts off as an identical copy of PTB's context as of here.
        error=CGLCreateContext(windowRecord->targetSpecific.pixelFormatObject, windowRecord->targetSpecific.contextObject, &(windowRecord->targetSpecific.glusercontextObject));
        if (error) {
            printf("\nPTB-ERROR[UserContextCreation failed: %s]: Creating a private OpenGL context for userspace OpenGL failed.\n\n", CGLErrorString(error));
            return(FALSE);
        }
    }

    // Create glswapcontextObject - An OpenGL context for exclusive use by parallel background threads,
    // e.g., our thread for async flip operations and self-made frame-sequential stereo:
    error=CGLCreateContext(windowRecord->targetSpecific.pixelFormatObject, windowRecord->targetSpecific.contextObject, &(windowRecord->targetSpecific.glswapcontextObject));
    if (error) {
        printf("\nPTB-ERROR[SwapContextCreation failed: %s]: Creating a private OpenGL context for async-bufferswaps failed.\n\n", CGLErrorString(error));
        CGLSetCurrentContext(NULL);
        return(FALSE);
    }

    // Store Cocoa onscreen window handle:
    windowRecord->targetSpecific.windowHandle = cocoaWindow;

    // Objective-C setup path, using Cocoa + NSOpenGLContext wrapped around already
    // existing and setup CGLContext:
    if (PsychCocoaSetupAndAssignOpenGLContextsFromCGLContexts(cocoaWindow, windowRecord)) {
        printf("\nPTB-ERROR[Cocoa OpenGL setup failed]: Setup failed for unknown reasons.\n\n");
        PsychCocoaDisposeWindow(windowRecord);
        return(FALSE);
    }

    // Check for output display rotation enabled. Will impair timing/timestamping because
    // it uses the desktop compositor for a rotated copy blit, instead of via rotated crtc
    // scanout, as most crtc's don't support this in hardware:
    if ((((int) CGDisplayRotation(cgDisplayID)) != 0) && (PsychPrefStateGet_Verbosity() > 1)) {
        printf("PTB-WARNING: Your onscreen windows output display has rotation enabled. It is not displaying in upright orientation.\n");
        printf("PTB-WARNING: On most graphics cards this will cause unreliable stimulus presentation timing and timestamping.\n");
        printf("PTB-WARNING: If you want non-upright stimulus presentation, look at 'help PsychImaging' on how to achieve this in\n");
        printf("PTB-WARNING: a way that doesn't impair timing. The subfunctions 'FlipHorizontal' and 'FlipVertical' are what you probably need.\n");
    }

    // First reference to this screen by a window?
    if (screenRefCount[screenSettings->screenNumber] == 0) {
        // High precision timestamping enabled? If so, we need to setup the fallback
        // timestamping methods in case beamposition timestamping doesn't work:
        if (PsychPrefStateGet_VBLTimestampingMode() > 0) {
            // Use of CoreVideo is needed on 10.7 and later due to brokeness of the old method (thanks Apple!):
            if (PsychPrefStateGet_Verbosity() > 2) {
                printf("PTB-INFO: Will use fragile CoreVideo timestamping as fallback if beamposition timestamping doesn't work.\n");
                // Recommend use of kernel driver if it isn't installed already for all but Intel GPU's:
                if (!PsychOSIsKernelDriverAvailable(screenSettings->screenNumber) && !strstr((char*) glGetString(GL_VENDOR), "Intel")) {
                    printf("PTB-INFO: Installation of the PsychtoolboxKernelDriver is strongly recommended if you care about precise visual\n");
                    printf("PTB-INFO: onset timestamping or timing. See 'help PsychtoolboxKernelDriver' for installation instructions.\n");
                }
            }

            if (NULL == cvDisplayLink[screenSettings->screenNumber]) {
                // CoreVideo timestamping:
                //
                // Create and start a CVDisplayLink for this screen.
                if (kCVReturnSuccess != CVDisplayLinkCreateWithCGDisplay(cgDisplayID, &cvDisplayLink[screenSettings->screenNumber])) {
                    if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to create CVDisplayLink for screenId %i. This may impair VBL timestamping.\n", screenSettings->screenNumber);
                } else {
                    // Assign dummy output callback, as this is mandatory to get the link up and running:
                    CVDisplayLinkSetOutputCallback(cvDisplayLink[screenSettings->screenNumber], &PsychCVDisplayLinkOutputCallback, (void*) (long int) screenSettings->screenNumber);

                    // Setup shared data structure and mutex:
                    memset(&cvDisplayLinkData[screenSettings->screenNumber], 0, sizeof(cvDisplayLinkData[screenSettings->screenNumber]));
                    PsychInitMutex(&(cvDisplayLinkData[screenSettings->screenNumber].mutex));

                    // Start the link:
                    if (kCVReturnSuccess != CVDisplayLinkStart(cvDisplayLink[screenSettings->screenNumber])) {
                        // Failed to start: Release it again and report error:
                        CVDisplayLinkRelease(cvDisplayLink[screenSettings->screenNumber]);
                        cvDisplayLink[screenSettings->screenNumber] = NULL;

                        // Teardown shared data structure and mutex:
                        PsychDestroyMutex(&(cvDisplayLinkData[screenSettings->screenNumber].mutex));
                        if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to start CVDisplayLink for screenId %i. This may impair VBL timestamping.\n", screenSettings->screenNumber);
                    }
                    else {
                        // Display link started: Report some stuff for the fun of it...
                        if (PsychPrefStateGet_Verbosity() > 3) {
                            // Wait for 50 msecs before query of video refresh from display link to give it a chance to start up:
                            PsychWaitIntervalSeconds(0.050);

                            printf("PTB-INFO: CVDisplayLink for screen %i created to work around the brokenness of Apple Mac OS/X 10.7 and later:\n", screenSettings->screenNumber);
                            printf("PTB-INFO: Video refresh interval as measured by CoreVideo display link: %f msecs.\n", (float) CVDisplayLinkGetActualOutputVideoRefreshPeriod(cvDisplayLink[screenSettings->screenNumber]) * 1000.0);
                            CVTime outLatency = CVDisplayLinkGetOutputVideoLatency(cvDisplayLink[screenSettings->screenNumber]);
                            printf("PTB-INFO: Video display output delay as reported by CoreVideo display link: %f msecs.\n", screenSettings->screenNumber, (float) (((double) outLatency.timeValue / (double) outLatency.timeScale) * 1000.0));
                        }
                    }
                }
            }
        }
        else {
            // VBLtimestampingmode 0 or -1 -- No CoreVideo fallback for timestamping if beamposition timestamping is unavailable:
            // This is the new default as of Psychtoolbox 3.0.12 to avoid the buggy, crashy, unreliably CoreVideo fallback.

            // Recommend use of kernel driver if it isn't installed already for all but Intel GPU's:
            if (!PsychOSIsKernelDriverAvailable(screenSettings->screenNumber) && !strstr((char*) glGetString(GL_VENDOR), "Intel")) {
                printf("PTB-INFO: Installation of the PsychtoolboxKernelDriver is strongly recommended if you care about precise visual\n");
                printf("PTB-INFO: onset timestamping or timing. See 'help PsychtoolboxKernelDriver' for installation instructions.\n");
            }
        }
    }

    // Retain reference of this window to its screen:
    screenRefCount[screenSettings->screenNumber]++;

    // Done.
    return(TRUE);
}