OSErr SetupPickMonitorPane(ControlRef inPane, DisplayIDType inDefaultMonitor) { GDHandle dev = GetDeviceList(); OSErr err = noErr; // make the default monitor the selected device if (inDefaultMonitor) DMGetGDeviceByDisplayID(inDefaultMonitor, &sSelectedDevice, true); else sSelectedDevice = GetMainDevice(); // build the list of monitors sNumMonitors = 0; while (dev && sNumMonitors < kMaxMonitors) { if (TestDeviceAttribute(dev, screenDevice) && TestDeviceAttribute(dev, screenActive)) { sMonitors[sNumMonitors].device = dev; sMonitors[sNumMonitors].origRect = (**dev).gdRect; sMonitors[sNumMonitors].isMain = (dev == GetMainDevice()); sNumMonitors++; } dev = GetNextDevice(dev); } // calculate scaled rects if (sNumMonitors) { Rect origPaneRect, paneRect; Rect origGrayRect, grayRect, scaledGrayRect; float srcAspect, dstAspect, scale; int i; GetControlBounds(inPane, &origPaneRect); paneRect = origPaneRect; OffsetRect(&paneRect, -paneRect.left, -paneRect.top); GetRegionBounds(GetGrayRgn(), &origGrayRect); grayRect = origGrayRect; OffsetRect(&grayRect, -grayRect.left, -grayRect.top); srcAspect = (float)grayRect.right / (float)grayRect.bottom; dstAspect = (float)paneRect.right / (float)paneRect.bottom; scaledGrayRect = paneRect; if (srcAspect < dstAspect) { scaledGrayRect.right = (float)paneRect.bottom * srcAspect; scale = (float)scaledGrayRect.right / grayRect.right; } else { scaledGrayRect.bottom = (float)paneRect.right / srcAspect; scale = (float)scaledGrayRect.bottom / grayRect.bottom; } for (i = 0; i < sNumMonitors; i++) { Rect r = sMonitors[i].origRect; Rect r2 = r; // normalize rect and scale OffsetRect(&r, -r.left, -r.top); r.bottom = (float)r.bottom * scale; r.right = (float)r.right * scale; // offset rect wrt gray region OffsetRect(&r, (float)(r2.left - origGrayRect.left) * scale, (float)(r2.top - origGrayRect.top) * scale); sMonitors[i].scaledRect = r; } // center scaledGrayRect in the pane OffsetRect(&scaledGrayRect, (paneRect.right - scaledGrayRect.right) / 2, (paneRect.bottom - scaledGrayRect.bottom) / 2); // offset monitors to match for (i = 0; i < sNumMonitors; i++) OffsetRect(&sMonitors[i].scaledRect, scaledGrayRect.left, scaledGrayRect.top); } else return paramErr; // setup the procs for the pick monitor user pane err = SetupUserPaneProcs(inPane, drawProc, hitTestProc, trackingProc); return err; }
void CL_DisplayWindow_OpenGL::create_window(const CL_DisplayWindowDescription &desc) { OSStatus result; const CL_OpenGLWindowDescription_Generic *gl_desc = 0; gl_desc = dynamic_cast<const CL_OpenGLWindowDescription_Generic*>(desc.impl.get()); fullscreen_width = desc.get_size().width; fullscreen_height = desc.get_size().height; disp_ref_count++; GLint gl_attribs_single[] = { AGL_RGBA, AGL_RED_SIZE, 4, AGL_GREEN_SIZE, 4, AGL_BLUE_SIZE, 4, AGL_DEPTH_SIZE, 16, AGL_NONE }; GLint gl_attribs[32]; int i = 0; if( gl_desc ) { if( gl_desc->rgba ) gl_attribs[i++] = AGL_RGBA; if( gl_desc->doublebuffer ) gl_attribs[i++] = AGL_DOUBLEBUFFER; //if( gl_desc->stereo ) gl_attribs[i++] = AGL_STEREO; gl_attribs[i++] = AGL_BUFFER_SIZE; gl_attribs[i++] = gl_desc->buffer_size; gl_attribs[i++] = AGL_LEVEL; gl_attribs[i++] = gl_desc->level; gl_attribs[i++] = AGL_AUX_BUFFERS; gl_attribs[i++] = gl_desc->aux_buffers; gl_attribs[i++] = AGL_RED_SIZE; gl_attribs[i++] = gl_desc->red_size; gl_attribs[i++] = AGL_GREEN_SIZE; gl_attribs[i++] = gl_desc->green_size; gl_attribs[i++] = AGL_BLUE_SIZE; gl_attribs[i++] = gl_desc->blue_size; gl_attribs[i++] = AGL_DEPTH_SIZE; gl_attribs[i++] = gl_desc->depth_size; gl_attribs[i++] = AGL_STENCIL_SIZE; gl_attribs[i++] = gl_desc->stencil_size; gl_attribs[i++] = AGL_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; gl_attribs[i++] = AGL_ACCUM_GREEN_SIZE; gl_attribs[i++] = gl_desc->accum_green_size; gl_attribs[i++] = AGL_ACCUM_BLUE_SIZE; gl_attribs[i++] = gl_desc->accum_blue_size; gl_attribs[i++] = AGL_ACCUM_ALPHA_SIZE; gl_attribs[i++] = gl_desc->accum_alpha_size; gl_attribs[i++] = AGL_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; // gl_attribs[i++] = AGL_FULLSCREEN; } else { gl_attribs[i++] = AGL_RGBA; gl_attribs[i++] = AGL_NO_RECOVERY; gl_attribs[i++] = AGL_DOUBLEBUFFER; gl_attribs[i++] = AGL_DEPTH_SIZE; gl_attribs[i++] = 16; } /* else { gl_attribs[i++] = AGL_RGBA; gl_attribs[i++] = AGL_DOUBLEBUFFER; gl_attribs[i++] = AGL_RED_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = AGL_GREEN_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = AGL_BLUE_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = AGL_DEPTH_SIZE; gl_attribs[i++] = 16; // gl_attribs[i++] = AGL_FULLSCREEN; } */ gl_attribs[i] = AGL_NONE; CGDirectDisplayID display = CGMainDisplayID(); GDHandle gdhDisplay, *pgdhDisplay; int numDisplay; pgdhDisplay = &gdhDisplay; if (noErr == DMGetGDeviceByDisplayID ((DisplayIDType)display, pgdhDisplay, false)) numDisplay = 1; else { pgdhDisplay = 0; numDisplay = 0; } AGLPixelFormat pixelformat; pixelformat = aglChoosePixelFormat(pgdhDisplay, numDisplay, gl_attribs); win_context = aglCreateContext(pixelformat, share_context); if (!share_context) share_context = win_context; aglDestroyPixelFormat(pixelformat); gl_attribs[i++] = AGL_FULLSCREEN; gl_attribs[i] = AGL_NONE; pixelformat = aglChoosePixelFormat(pgdhDisplay, numDisplay, gl_attribs); fs_context = aglCreateContext(pixelformat, win_context); aglDestroyPixelFormat(pixelformat); if (!(win_context && fs_context)) { printf("Requested visual not supported by your OpenGL implementation. Falling back on singlebuffered Visual!\n"); pixelformat = aglChoosePixelFormat(0, 0, gl_attribs_single); win_context = aglCreateContext(pixelformat, share_context); aglDestroyPixelFormat(pixelformat); fs_context = 0; } WindowAttributes style = kWindowCloseBoxAttribute | kWindowStandardHandlerAttribute; if (desc.get_allow_resize()) style |= kWindowResizableAttribute | kWindowFullZoomAttribute; Rect window_rect; SetRect(&window_rect, 50, 50, 50+desc.get_size().width, 50+desc.get_size().height); result = CreateNewWindow(kDocumentWindowClass, style, &window_rect, &window_ref); if (result != noErr) printf("Could not create window, due to error %d\n", (int)result); // set title of window: set_title(desc.get_title()); // Set standard arrow cursor: InitCursor(); // do we need to do this? -- iMBN, 13. may 2004 // Create input devices for window: keyboard = CL_InputDevice(new CL_InputDevice_MacKeyboard(this)); mouse = CL_InputDevice(new CL_InputDevice_MacMouse(this)); get_ic()->clear(); get_ic()->add_keyboard(keyboard); get_ic()->add_mouse(mouse); // buffer_front = CL_PixelBuffer(new CL_PixelBuffer_OpenGL_Frame(CL_FRONT, gc)); // buffer_back = CL_PixelBuffer(new CL_PixelBuffer_OpenGL_Frame(CL_BACK, gc)); if (!aglSetDrawable(win_context, GetWindowPort(window_ref))) { printf("Unable to set drawable"); } if (desc.is_fullscreen()) set_fullscreen(desc.get_size().width, desc.get_size().height, desc.get_bpp(), desc.get_refresh_rate()); else { fullscreen = true; // not really, but need to fool set_windowed set_windowed(); } ShowWindow(window_ref); }
qboolean VID_InitMode(viddef_mode_t *mode) { const EventTypeSpec winEvents[] = { { kEventClassWindow, kEventWindowClosed }, { kEventClassWindow, kEventWindowCollapsing }, { kEventClassWindow, kEventWindowExpanded }, }; OSStatus carbonError; Rect windowBounds; CFStringRef windowTitle; AGLPixelFormat pixelFormat; GLint attributes [32]; GLenum error; if (!GL_OpenLibrary()) { Con_Printf("Unable to load GL driver\n"); return false; } if ((qaglChoosePixelFormat = (AGLPixelFormat (*) (const AGLDevice *gdevs, GLint ndev, const GLint *attribList))GL_GetProcAddress("aglChoosePixelFormat")) == NULL || (qaglCreateContext = (AGLContext (*) (AGLPixelFormat pix, AGLContext share))GL_GetProcAddress("aglCreateContext")) == NULL || (qaglDestroyContext = (GLboolean (*) (AGLContext ctx))GL_GetProcAddress("aglDestroyContext")) == NULL || (qaglDestroyPixelFormat = (void (*) (AGLPixelFormat pix))GL_GetProcAddress("aglDestroyPixelFormat")) == NULL || (qaglErrorString = (const GLubyte* (*) (GLenum code))GL_GetProcAddress("aglErrorString")) == NULL || (qaglGetError = (GLenum (*) (void))GL_GetProcAddress("aglGetError")) == NULL || (qaglSetCurrentContext = (GLboolean (*) (AGLContext ctx))GL_GetProcAddress("aglSetCurrentContext")) == NULL || (qaglSetDrawable = (GLboolean (*) (AGLContext ctx, AGLDrawable draw))GL_GetProcAddress("aglSetDrawable")) == NULL || (qaglSetFullScreen = (GLboolean (*) (AGLContext ctx, GLsizei width, GLsizei height, GLsizei freq, GLint device))GL_GetProcAddress("aglSetFullScreen")) == NULL || (qaglSetInteger = (GLboolean (*) (AGLContext ctx, GLenum pname, const GLint *params))GL_GetProcAddress("aglSetInteger")) == NULL || (qaglSwapBuffers = (void (*) (AGLContext ctx))GL_GetProcAddress("aglSwapBuffers")) == NULL ) { Con_Printf("AGL functions not found\n"); ReleaseWindow(window); return false; } qCGLEnable = (CGLError (*) (CGLContextObj ctx, CGLContextEnable pname)) CGL_GetProcAddress("CGLEnable"); qCGLDisable = (CGLError (*) (CGLContextObj ctx, CGLContextEnable pname)) CGL_GetProcAddress("CGLDisable"); qCGLGetCurrentContext = (CGLContextObj (*) (void)) CGL_GetProcAddress("CGLGetCurrentContext"); if(!qCGLEnable || !qCGLDisable || !qCGLGetCurrentContext) Con_Printf("CGL functions not found; disabling multithreaded OpenGL\n"); // Ignore the events from the previous window AsyncEvent_Quitting = false; AsyncEvent_Collapsed = false; // Create the window, a bit towards the center of the screen windowBounds.left = 100; windowBounds.top = 100; windowBounds.right = mode->width + 100; windowBounds.bottom = mode->height + 100; carbonError = CreateNewWindow(kDocumentWindowClass, kWindowStandardFloatingAttributes | kWindowStandardHandlerAttribute, &windowBounds, &window); if (carbonError != noErr || window == NULL) { Con_Printf("Unable to create window (error %u)\n", (unsigned)carbonError); return false; } // Set the window title windowTitle = CFSTR("DarkPlaces AGL"); SetWindowTitleWithCFString(window, windowTitle); // Install the callback function for the window events we can't get // through ReceiveNextEvent (i.e. close, collapse, and expand) InstallWindowEventHandler (window, NewEventHandlerUPP (MainWindowEventHandler), GetEventTypeCount(winEvents), winEvents, window, NULL); // Create the desired attribute list VID_BuildAGLAttrib(attributes, mode->bitsperpixel == 32, mode->fullscreen, mode->stereobuffer, mode->samples); if (!mode->fullscreen) { // Output to Window pixelFormat = qaglChoosePixelFormat(NULL, 0, attributes); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglChoosePixelFormat FAILED: %s\n", (char *)qaglErrorString(error)); ReleaseWindow(window); return false; } } else // Output is fullScreen { CGDirectDisplayID mainDisplay; CFDictionaryRef refDisplayMode; GDHandle gdhDisplay; // Get the mainDisplay and set resolution to current mainDisplay = CGMainDisplayID(); CGDisplayCapture(mainDisplay); // TOCHECK: not sure whether or not it's necessary to change the resolution // "by hand", or if aglSetFullscreen does the job anyway refDisplayMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty(mainDisplay, mode->bitsperpixel, mode->width, mode->height, mode->refreshrate, kCGDisplayModeIsSafeForHardware, NULL); CGDisplaySwitchToMode(mainDisplay, refDisplayMode); DMGetGDeviceByDisplayID((DisplayIDType)mainDisplay, &gdhDisplay, false); // Set pixel format with built attribs // Note: specifying a device is *required* for AGL_FullScreen pixelFormat = qaglChoosePixelFormat(&gdhDisplay, 1, attributes); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglChoosePixelFormat FAILED: %s\n", (char *)qaglErrorString(error)); ReleaseWindow(window); return false; } } // Create a context using the pform context = qaglCreateContext(pixelFormat, NULL); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglCreateContext FAILED: %s\n", (char *)qaglErrorString(error)); } // Make the context the current one ('enable' it) qaglSetCurrentContext(context); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglSetCurrentContext FAILED: %s\n", (char *)qaglErrorString(error)); ReleaseWindow(window); return false; } // Discard pform qaglDestroyPixelFormat(pixelFormat); // Attempt fullscreen if requested if (mode->fullscreen) { qaglSetFullScreen (context, mode->width, mode->height, mode->refreshrate, 0); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglSetFullScreen FAILED: %s\n", (char *)qaglErrorString(error)); return false; } } else { // Set Window as Drawable qaglSetDrawable(context, GetWindowPort(window)); error = qaglGetError(); if (error != AGL_NO_ERROR) { Con_Printf("qaglSetDrawable FAILED: %s\n", (char *)qaglErrorString(error)); ReleaseWindow(window); return false; } } if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL) Sys_Error("glGetString not found in %s", gl_driver); gl_platformextensions = ""; gl_platform = "AGL"; multithreadedgl = false; vid_isfullscreen = mode->fullscreen; vid_usingmouse = false; vid_usinghidecursor = false; vid_hidden = false; vid_activewindow = true; sound_active = true; GL_Init(); SelectWindow(window); ShowWindow(window); return true; }
static int RLXAPI CreateSurface(int numberOfSparePages) { static GLint attrib[32]; GLint *pAttrib = attrib; *pAttrib = AGL_RGBA; pAttrib++; *pAttrib = AGL_DOUBLEBUFFER; pAttrib++; *pAttrib = AGL_NONE; pAttrib++; AGLPixelFormat fmt; GLboolean ok; g_pRLX->pGX->View.lpBackBuffer = NULL; /* Choose an rgb pixel format */ GDHandle gdhDisplay; ok = DMGetGDeviceByDisplayID((DisplayIDType)g_cgDisplayID, &gdhDisplay, false); SYS_ASSERT(ok == noErr); fmt = aglChoosePixelFormat(&gdhDisplay, 1, attrib); SYS_AGLTRACE(0); if(fmt == NULL) { ok = SYS_AGLTRACE(aglGetError()); return -1; } /* Create an AGL context */ g_pAGLC = aglCreateContext(fmt, NULL); SYS_AGLTRACE(0); if(g_pAGLC == NULL) return -2; /* Attach the window to the context */ ok = SYS_AGLTRACE(aglSetDrawable(g_pAGLC, GetWindowPort(g_hWnd))); if(!ok) return -3; /* Make the context the current context */ ok = SYS_AGLTRACE(aglSetCurrentContext(g_pAGLC)); if(!ok) return -4; SizeWindow(g_hWnd, gl_lx, gl_ly, true); if ((g_pRLX->Video.Config & RLXVIDEO_Windowed)) CenterWindow(g_hWnd); ShowWindow(g_hWnd); // copy portRect GetPortBounds(GetWindowPort(g_hWnd), g_pRect); /* Pixel format is no more needed */ aglDestroyPixelFormat(fmt); if (!(g_pRLX->Video.Config & RLXVIDEO_Windowed)) { HideMenuBar(); aglSetFullScreen(g_pAGLC, 0, 0, 0, 0); GLint swap = !!(g_pRLX->pGX->View.Flags & GX_CAPS_VSYNC); aglSetInteger(g_pAGLC, AGL_SWAP_INTERVAL, &swap); SYS_AGLTRACE(0); } // 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; }
static AGLContext createContext(WindowRef window) { AGLPixelFormat pf; AGLContext ctx; GDHandle gdh; CFDictionaryRef refMode; GLenum error; CGDirectDisplayID mainDisplay = CGMainDisplayID(); GLint attrs[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_RED_SIZE, 4, AGL_GREEN_SIZE, 4, AGL_BLUE_SIZE, 4, AGL_DEPTH_SIZE, 16, AGL_NONE }; GLint fullscreen_attrs[] = { AGL_FULLSCREEN, AGL_RGBA, AGL_DOUBLEBUFFER, AGL_RED_SIZE, 4, AGL_GREEN_SIZE, 4, AGL_BLUE_SIZE, 4, AGL_DEPTH_SIZE, 16, AGL_NONE }; g_Window.double_buffered = true; if (!g_Window.fs) { pf = aglChoosePixelFormat(NULL, 0, attrs); } else { CGDisplayCapture(mainDisplay); refMode = CGDisplayBestModeForParameters(mainDisplay, 32, g_Window.width, g_Window.height, NULL); CGDisplaySwitchToMode(mainDisplay, refMode); DMGetGDeviceByDisplayID(mainDisplay, &gdh, false); pf = aglChoosePixelFormat(&gdh, 1, fullscreen_attrs); error = aglGetError(); if (error != AGL_NO_ERROR) { printf("%s\n", aglErrorString(error)); return 0; } } if (!pf) { printf("Error choosing pixel format\n"); return 0; } ctx = aglCreateContext(pf, 0); if (!ctx) { printf("%s\n", aglErrorString(aglGetError())); return 0; } aglDestroyPixelFormat(pf); aglSetCurrentContext(ctx); if (g_Window.fs) { aglSetFullScreen(ctx, g_Window.width, g_Window.height, 0, 0); } else { aglSetWindowRef(ctx, window); } return ctx; }