diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/opengl/opengl_windows.c | |
Add the files
Diffstat (limited to 'src/detection/opengl/opengl_windows.c')
| -rw-r--r-- | src/detection/opengl/opengl_windows.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/detection/opengl/opengl_windows.c b/src/detection/opengl/opengl_windows.c new file mode 100644 index 0000000..01bd986 --- /dev/null +++ b/src/detection/opengl/opengl_windows.c @@ -0,0 +1,120 @@ +#include "opengl.h" +#include "common/library.h" +#include "common/printing.h" +#include "common/windows/nt.h" + +#include <windows.h> +#include <GL/gl.h> + +typedef struct WGLData { + FF_LIBRARY_SYMBOL(glGetString) + FF_LIBRARY_SYMBOL(wglMakeCurrent) + FF_LIBRARY_SYMBOL(wglCreateContext) + FF_LIBRARY_SYMBOL(wglDeleteContext) +} WGLData; + +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString); + +static const char* wglHandleContext(WGLData* wglData, FFOpenGLResult* result, HDC hdc, HGLRC context) { + if (wglData->ffwglMakeCurrent(hdc, context) == FALSE) { + return "wglMakeCurrent() failed"; + } + ffOpenGLHandleResult(result, wglData->ffglGetString); + ffStrbufSetStatic(&result->library, "WGL 1.0"); + if (wglData->ffwglMakeCurrent(NULL, NULL) == FALSE) { + return "wglMakeCurrent(NULL, NULL) failed"; + } + return NULL; +} + +static const char* wglHandlePixelFormat(WGLData* wglData, FFOpenGLResult* result, HWND hWnd) { + HDC hdc = GetDC(hWnd); + + if (hdc == NULL) { + return "GetDC() failed"; + } + + PIXELFORMATDESCRIPTOR pfd = { + .nSize = sizeof(PIXELFORMATDESCRIPTOR), + .nVersion = 1, + .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + .iPixelType = PFD_TYPE_RGBA, + .cColorBits = 32, + .cDepthBits = 24, + .iLayerType = PFD_MAIN_PLANE + }; + int pixelFormat = ChoosePixelFormat(hdc, &pfd); + if (pixelFormat == 0) { + ReleaseDC(hWnd, hdc); + return "ChoosePixelFormat() failed"; + } + + if (SetPixelFormat(hdc, pixelFormat, &pfd) == FALSE) { + ReleaseDC(hWnd, hdc); + return "SetPixelFormat() failed"; + } + + HGLRC context = wglData->ffwglCreateContext(hdc); + if (context == NULL) { + ReleaseDC(hWnd, hdc); + return "wglCreateContext() failed"; + } + + const char* error = wglHandleContext(wglData, result, hdc, context); + wglData->ffwglDeleteContext(context); + + ReleaseDC(hWnd, hdc); + + return error; +} + +static const char* wglDetectOpenGL(FFOpenGLResult* result) { + FF_LIBRARY_LOAD_MESSAGE(opengl32, "opengl32" FF_LIBRARY_EXTENSION, 1); + + WGLData data = {}; + + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglMakeCurrent); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglCreateContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglDeleteContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, glGetString); + + HINSTANCE hInstance = ffGetPeb()->ImageBaseAddress; + + WNDCLASSW wc = { + .lpfnWndProc = DefWindowProcW, + .hInstance = hInstance, + .hbrBackground = (HBRUSH) COLOR_BACKGROUND, + .lpszClassName = L"ogl_version_check", + .style = CS_OWNDC, + }; + if (!RegisterClassW(&wc)) { + return "RegisterClassW() failed"; + } + + HWND hWnd = CreateWindowW(wc.lpszClassName, L"ogl_version_check", 0, 0, 0, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT, NULL, NULL, hInstance, NULL); + if (!hWnd) { + return "CreateWindowW() failed"; + } + + const char* error = wglHandlePixelFormat(&data, result, hWnd); + + DestroyWindow(hWnd); + UnregisterClassW(wc.lpszClassName, hInstance); + + return error; +} + +const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) { + if (options->library == FF_OPENGL_LIBRARY_AUTO) { + return wglDetectOpenGL(result); + } else if (options->library == FF_OPENGL_LIBRARY_EGL) { +#if __has_include(<EGL/egl.h>) + const char* ffOpenGLDetectByEGL(FFOpenGLResult * result); + return ffOpenGLDetectByEGL(result); +#else + return "fastfetch was compiled without egl support"; +#endif + } else { + return "Unsupported OpenGL library"; + } +} |