aboutsummaryrefslogtreecommitdiff
path: root/src/wglarb.c
diff options
context:
space:
mode:
authorWolfgang Draxinger <Wolfgang.Draxinger@physik.uni-muenchen.de>2015-04-17 22:08:23 +0200
committerWolfgang Draxinger <Wolfgang.Draxinger@physik.uni-muenchen.de>2015-04-17 22:08:23 +0200
commitc3657a01ec8ce2c159978d1ee4d36b5456413ca1 (patch)
tree693deb440fe1f2ef028598ee428f07343b0bad13 /src/wglarb.c
parentb227e5e43414a59014c4882a2ead764ff3abd736 (diff)
downloadwglarb-c3657a01ec8ce2c159978d1ee4d36b5456413ca1.tar.gz
wglarb-c3657a01ec8ce2c159978d1ee4d36b5456413ca1.tar.bz2
changed build system from plain Makefile to CMake
Diffstat (limited to 'src/wglarb.c')
-rw-r--r--src/wglarb.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/wglarb.c b/src/wglarb.c
new file mode 100644
index 0000000..c9ba7d7
--- /dev/null
+++ b/src/wglarb.c
@@ -0,0 +1,238 @@
+/*
+Copyright (c) 2014 Wolfgang 'datenwolf' Draxinger
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include <GL/gl.h>
+#include "wglarb.h"
+
+#define wglarb_BuildAssert(cond) ((void)sizeof(char[1 - 2*!(cond)]))
+
+static HANDLE wglarb_intermediary_mutex = NULL;
+
+static DWORD wglarb_intermediary_lock(void)
+{
+ wglarb_BuildAssert( sizeof(PVOID) == sizeof(HANDLE) );
+
+ if( !wglarb_intermediary_mutex ) {
+ /* Between testing for the validity of the mutex handle,
+ * creating a new mutex handle and using the interlocked
+ * exchange there is a race... */
+
+ /* //// START \\\\ */
+
+ HANDLE const new_mutex =
+ CreateMutex(NULL, TRUE, NULL);
+
+ HANDLE const dst_mutex =
+ InterlockedCompareExchangePointer(
+ &wglarb_intermediary_mutex,
+ new_mutex,
+ NULL );
+
+ /* //// FINISH \\\\ */
+
+ if( !dst_mutex ) {
+ /* mutex created in one time initialization and held
+ * by calling thread. Return signaled status. */
+ return WAIT_OBJECT_0;
+ }
+ /* In this case we lost the race and another thread
+ * beat this thread in creating a mutex object.
+ * Clean up and wait for the proper mutex. */
+ ReleaseMutex(new_mutex);
+ CloseHandle(new_mutex);
+ }
+ return WaitForSingleObject(wglarb_intermediary_mutex, INFINITE);
+}
+
+static BOOL wglarb_intermediary_unlock(void)
+{
+ return ReleaseMutex(wglarb_intermediary_mutex);
+}
+
+#define WGLARB_INTERMEDIARY_CLASS "wglarb intermediary"
+#define WGLARB_INTERMEDIARY_STYLE (WS_CLIPSIBLINGS|WS_CLIPCHILDREN)
+#define WGLARB_INTERMEDIARY_EXSTYLE 0
+
+static HWND wglarb_intermediary_hWnd = 0;
+
+static BOOL wglarb_intermediary_create_Wnd(void)
+{
+ HINSTANCE const hInstance = GetModuleHandle(NULL);
+
+ WNDCLASS wc;
+ memset(&wc,0,sizeof(wc));
+ wc.hInstance = hInstance;
+ wc.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
+ wc.lpfnWndProc = DefWindowProc;
+ wc.lpszClassName = WGLARB_INTERMEDIARY_CLASS;
+ RegisterClass(&wc);
+
+ wglarb_intermediary_hWnd =
+ CreateWindowEx(
+ WGLARB_INTERMEDIARY_EXSTYLE,
+ WGLARB_INTERMEDIARY_CLASS,
+ NULL,
+ WGLARB_INTERMEDIARY_STYLE,
+ 0,0,0,0,
+ NULL,NULL,
+ hInstance,
+ NULL );
+
+ if( !wglarb_intermediary_hWnd ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static HDC wglarb_intermediary_hDC = 0;
+
+static BOOL wglarb_intermediary_create_DC(void)
+{
+ if( !wglarb_intermediary_hWnd
+ && !wglarb_intermediary_create_Wnd() ) {
+ return FALSE;
+ }
+
+ wglarb_intermediary_hDC = GetDC(wglarb_intermediary_hWnd);
+ if( !wglarb_intermediary_hDC ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static HGLRC wglarb_intermediary_hRC = 0;
+
+static BOOL wglarb_intermediary_create_RC(void)
+{
+ if( !wglarb_intermediary_hDC
+ && !wglarb_intermediary_create_DC() ) {
+ return FALSE;
+ }
+
+ PIXELFORMATDESCRIPTOR pfd;
+ memset(&pfd,0,sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL|PFD_GENERIC_ACCELERATED|PFD_DRAW_TO_WINDOW;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ int iPF;
+ if( !(iPF = ChoosePixelFormat(wglarb_intermediary_hDC, &pfd))
+ || !(SetPixelFormat(wglarb_intermediary_hDC, iPF, &pfd))
+ || !(wglarb_intermediary_hRC = wglCreateContext(wglarb_intermediary_hDC))
+ ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL wglarb_intermediary_makecurrent(HDC *hOrigDC, HGLRC *hOrigRC)
+{
+ *hOrigDC = wglGetCurrentDC();
+ *hOrigRC = wglGetCurrentContext();
+
+ if( !wglarb_intermediary_hRC
+ && !wglarb_intermediary_create_RC() ) {
+ return FALSE;
+ }
+
+ return wglMakeCurrent(wglarb_intermediary_hDC, wglarb_intermediary_hRC);
+}
+
+HGLRC WINAPI wglarb_CreateContextAttribsARB(
+ HDC hDC,
+ HGLRC hShareContext,
+ const int *attribList)
+{
+ if( WAIT_OBJECT_0 != wglarb_intermediary_lock() ) {
+ return NULL;
+ }
+
+ HDC hOrigDC;
+ HGLRC hOrigRC;
+ if( !wglarb_intermediary_makecurrent(&hOrigDC, &hOrigRC) ) {
+ wglarb_intermediary_unlock();
+ return NULL;
+ }
+
+ PFNWGLCREATECONTEXTATTRIBSARBPROC impl =
+ (PFNWGLCREATECONTEXTATTRIBSARBPROC)
+ wglGetProcAddress("wglCreateContextAttribsARB");
+
+ HGLRC ret = NULL;
+ if( impl ) {
+ ret = impl(hDC, hShareContext, attribList);
+ }
+
+ wglMakeCurrent(hOrigDC, hOrigRC);
+ wglarb_intermediary_unlock();
+ return ret;
+}
+
+BOOL WINAPI wglarb_ChoosePixelFormatARB(
+ HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats)
+{
+ if( WAIT_OBJECT_0 != wglarb_intermediary_lock() ) {
+ return FALSE;
+ }
+
+ HDC hOrigDC;
+ HGLRC hOrigRC;
+ if( !wglarb_intermediary_makecurrent(&hOrigDC, &hOrigRC) ) {
+ wglarb_intermediary_unlock();
+ return FALSE;
+ }
+
+ PFNWGLCHOOSEPIXELFORMATARBPROC impl = NULL;
+
+ impl = (PFNWGLCHOOSEPIXELFORMATARBPROC)
+ wglGetProcAddress("wglChoosePixelFormatARB");
+ if( !impl ) {
+ /* WGL_EXT_pixel_format uses the same function prototypes
+ * as the WGL_ARB_pixel_format extension */
+ impl = (PFNWGLCHOOSEPIXELFORMATARBPROC)
+ wglGetProcAddress("wglChoosePixelFormatEXT");
+ }
+
+ BOOL ret = FALSE;
+ if( impl ) {
+ ret = impl(
+ hdc,
+ piAttribIList,
+ pfAttribFList,
+ nMaxFormats,
+ piFormats,
+ nNumFormats );
+ }
+
+ wglMakeCurrent(hOrigDC, hOrigRC);
+ wglarb_intermediary_unlock();
+ return ret;
+}