38#include <OpenGL/OpenGL.h>
39#include <OpenGL/CGLTypes.h>
40#include <OpenGL/CGLCurrent.h>
51#if defined(__WGLEW_H__) || defined(__GLEW_H__)
52#error "MUST NOT include GLEW headers from glctx.c"
60 char win_cls_name[32];
75 int minor_ver, bool_t fwd_compat, bool_t debug)
77 typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*,
78 GLXFBConfig, GLXContext, Bool,
const int*);
79 typedef GLXFBConfig *(*glXChooseFBConfigARBProc)(Display *, int,
82 glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL;
83 glXChooseFBConfigARBProc glXChooseFBConfigARB = NULL;
85 static int visual_attribs[] = { None };
86 int context_attribs[] = {
87 GLX_CONTEXT_MAJOR_VERSION_ARB, major_ver,
88 GLX_CONTEXT_MINOR_VERSION_ARB, minor_ver,
89 GLX_CONTEXT_FLAGS_ARB,
90 (fwd_compat ? GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB : 0) |
91 (debug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
95 GLXFBConfig *fbc = NULL;
98 ASSERT(share_ctx == NULL || share_ctx->glc != NULL);
100 ctx->created = B_TRUE;
103 ctx->dpy = XOpenDisplay(win_ptr);
104 if (ctx->dpy == NULL) {
105 logMsg(
"Failed to open display");
109 glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
110 glXGetProcAddressARB((GLubyte *)
"glXCreateContextAttribsARB");
111 glXChooseFBConfigARB = (glXChooseFBConfigARBProc)
112 glXGetProcAddress((GLubyte *)
"glXChooseFBConfig");
113 if (glXCreateContextAttribsARB == NULL ||
114 glXChooseFBConfigARB == NULL) {
115 logMsg(
"Missing support for GLX_ARB_create_context");
122 fbc = glXChooseFBConfigARB(ctx->dpy, DefaultScreen(ctx->dpy),
123 visual_attribs, &fbcount);
125 logMsg(
"Failed to get FBConfig");
129 ctx->glc = glXCreateContextAttribsARB(ctx->dpy, fbc[0],
130 share_ctx != NULL ? share_ctx->glc : NULL, True, context_attribs);
131 if (ctx->glc == NULL) {
132 logMsg(
"Failed to create opengl context");
150 return (getenv(
"DISPLAY"));
155#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
156#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
157#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
158#define WGL_CONTEXT_FLAGS_ARB 0x2094
159#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
161#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
162#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
171glctx_create_priv_window(glctx_t *ctx)
173 const PIXELFORMATDESCRIPTOR pfd = {
174 .nSize =
sizeof(pfd),
176 .iPixelType = PFD_TYPE_RGBA,
177 .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
181 .iLayerType = PFD_MAIN_PLANE,
186 .style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
187 .lpfnWndProc = DefWindowProcA,
188 .hInstance = GetModuleHandle(NULL)
200 snprintf(ctx->win_cls_name, sizeof (ctx->win_cls_name),
202 wc.lpszClassName = ctx->win_cls_name;
203 if (!RegisterClassA(&wc)) {
204 win_perror(GetLastError(),
"Failed to register window class");
205 memset(ctx->win_cls_name, 0, sizeof (ctx->win_cls_name));
208 ctx->win = CreateWindowA(ctx->win_cls_name, ctx->win_cls_name,
209 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
210 0, 0, 32, 32, NULL, NULL, GetModuleHandle(NULL), NULL);
211 if (ctx->win == NULL) {
212 win_perror(GetLastError(),
"Failed to create window");
215 ctx->dc = GetDC(ctx->win);
216 if (ctx->dc == NULL) {
217 win_perror(GetLastError(),
218 "Failed to get window device context");
221 ctx->release_dc = B_TRUE;
222 pixel_format = ChoosePixelFormat(ctx->dc, &pfd);
223 if (pixel_format == 0) {
224 logMsg(
"Couldn't find a suitable pixel format");
227 if (!SetPixelFormat(ctx->dc, pixel_format, &pfd)) {
228 win_perror(GetLastError(),
"Couldn't set pixel format");
237 int minor_ver, bool_t fwd_compat, bool_t debug)
239 typedef HGLRC (*wglCreateContextAttribsProc)(HDC, HGLRC,
const int *);
240 wglCreateContextAttribsProc wglCreateContextAttribsARB;
241 const int attrs[] = {
242 WGL_CONTEXT_MAJOR_VERSION_ARB, major_ver,
243 WGL_CONTEXT_MINOR_VERSION_ARB, minor_ver,
244 WGL_CONTEXT_FLAGS_ARB,
245 (fwd_compat ? WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB : 0) |
246 (debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
251 ASSERT(share_ctx == NULL || share_ctx->hgl != NULL);
252 LACF_UNUSED(win_ptr);
255 wglCreateContextAttribsARB = (wglCreateContextAttribsProc)
256 wglGetProcAddress(
"wglCreateContextAttribsARB");
257 if (wglCreateContextAttribsARB == NULL) {
258 logMsg(
"Missing support for WGL_ARB_create_context");
262 ctx->created = B_TRUE;
268 if (!glctx_create_priv_window(ctx))
271 ctx->hgl = wglCreateContextAttribsARB(ctx->dc,
272 share_ctx != NULL ? share_ctx->hgl : NULL, attrs);
273 if (ctx->hgl == NULL) {
274 win_perror(GetLastError(),
275 "Failed to create invisible OpenGL context");
289 unsigned int win_i[2];
292 fdr_find(&win_dr,
"sim/operation/windows/system_window_64");
295 xp_window = (HWND)((uintptr_t)win_i[1] << 32 | (uintptr_t)win_i[0]);
296 VERIFY(xp_window != INVALID_HANDLE_VALUE);
303static CGLOpenGLProfile
304get_gl_profile(
int major_ver)
307 return (kCGLOGLPVersion_Legacy);
309 return (kCGLOGLPVersion_GL3_Core);
310 return (kCGLOGLPVersion_GL4_Core);
315 int minor_ver, bool_t fwd_compat, bool_t debug)
317 CGLOpenGLProfile profile = get_gl_profile(major_ver);
318 const CGLPixelFormatAttribute attrs[] = {
321 kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)profile,
324 CGLPixelFormatObj pix;
328 LACF_UNUSED(win_ptr);
329 LACF_UNUSED(minor_ver);
330 LACF_UNUSED(fwd_compat);
332 ASSERT(share_ctx == NULL || share_ctx->cgl != NULL);
334 ctx->created = B_TRUE;
335 if (share_ctx != NULL) {
336 pix = CGLGetPixelFormat(share_ctx->cgl);
337 error = CGLCreateContext(pix, share_ctx->cgl, &ctx->cgl);
340 error = CGLChoosePixelFormat(attrs, &pix, &num);
341 if (error != kCGLNoError) {
342 logMsg(
"CGLChoosePixelFormat failed with error %d",
346 error = CGLCreateContext(pix, NULL, &ctx->cgl);
347 CGLDestroyPixelFormat(pix);
349 if (error != kCGLNoError) {
350 logMsg(
"CGLCreateContext failed with error %d", error);
376 ctx->dpy = XOpenDisplay(0);
377 if (ctx->dpy == NULL) {
378 logMsg(
"Failed to open display");
381 ctx->glc = glXGetCurrentContext();
382 if (ctx->glc == NULL) {
392 ctx->hgl = wglGetCurrentContext();
397 ctx->dc = wglGetCurrentDC();
398 if (ctx->dc == NULL) {
399 logMsg(
"Current context had no DC?!");
405 ctx->cgl = CGLGetCurrentContext();
406 if (ctx->cgl == NULL) {
419 return (ctx->glc == glXGetCurrentContext());
421 return (ctx->hgl == wglGetCurrentContext());
423 return (ctx->cgl == CGLGetCurrentContext());
443 typedef Bool (*glXMakeContextCurrentARBProc)(Display*,
444 GLXDrawable, GLXDrawable, GLXContext);
445 static glXMakeContextCurrentARBProc glXMakeContextCurrentARB = NULL;
447 if (glXMakeContextCurrentARB == NULL) {
448 glXMakeContextCurrentARB = (glXMakeContextCurrentARBProc)
449 glXGetProcAddressARB((GLubyte *)
"glXMakeContextCurrent");
454 VERIFY(glXMakeContextCurrentARB != NULL);
458 DefaultRootWindow(ctx->dpy));
461 if (!glXMakeContextCurrentARB(ctx->dpy, tgt, tgt, ctx->glc)) {
462 logMsg(
"Failed to make context current");
466 glXMakeContextCurrentARB(NULL, None, None, NULL);
472 if (!wglMakeCurrent(ctx->dc, ctx->hgl)) {
473 win_perror(GetLastError(),
474 "Failed to make context current");
478 wglMakeCurrent(NULL, NULL);
485 error = CGLSetCurrentContext(ctx->cgl);
486 if (error != kCGLNoError) {
487 logMsg(
"CGLSetCurrentContext failed with error %d",
492 CGLSetCurrentContext(NULL);
520 if (ctx->glc != NULL)
521 glXDestroyContext(ctx->dpy, ctx->glc);
523 if (ctx->dpy != NULL)
524 XCloseDisplay(ctx->dpy);
537 if (!wglDeleteContext(ctx->hgl))
538 win_perror(GetLastError(),
"wglDeleteContext failed");
539 if (cur_ctx != NULL) {
549 if (ctx->dc != NULL && ctx->release_dc) {
551 ReleaseDC(ctx->win, ctx->dc);
553 if (ctx->win != NULL)
554 DestroyWindow(ctx->win);
555 if (ctx->win_cls_name[0] !=
'\0') {
556 UnregisterClassA(ctx->win_cls_name,
557 GetModuleHandle(NULL));
562 CGLDestroyContext(ctx->cgl);
565 memset(ctx, 0,
sizeof (*ctx));
#define VERIFY3U(x, op, y)
#define dr_getvi(__dr, __i, __off, __num)
API_EXPORT void * glctx_get_window_system_handle(glctx_t *ctx)
API_EXPORT void * glctx_get_handle(const glctx_t *ctx)
API_EXPORT glctx_t * glctx_get_current(void)
API_EXPORT void glctx_destroy(glctx_t *ctx)
API_EXPORT void * glctx_get_xplane_win_ptr(void)
API_EXPORT bool_t glctx_is_current(glctx_t *ctx)
API_EXPORT glctx_t * glctx_create_invisible(void *win_ptr, glctx_t *share_ctx, int major_ver, int minor_ver, bool_t fwd_compat, bool_t debug)
API_EXPORT bool_t glctx_make_current(glctx_t *ctx)
bool_t glutils_in_zink_mode(void)
static void * safe_calloc(size_t nmemb, size_t size)