1c041511dScube 2c041511dScube/* Copyright (c) Nate Robins, 1997. */ 3c041511dScube 4c041511dScube/* This program is freely distributable without licensing fees 5c041511dScube and is provided without guarantee or warrantee expressed or 6c041511dScube implied. This program is -not- in the public domain. */ 7c041511dScube 8c041511dScube#include <stdio.h> 9c041511dScube#include "glutint.h" 10c041511dScube#include "win32_glx.h" 11c041511dScube 12c041511dScube/* global current HDC */ 13c041511dScubeextern HDC XHDC; 14c041511dScube 15c041511dScubeGLXContext 16c041511dScubeglXCreateContext(Display * display, XVisualInfo * visinfo, 17c041511dScube GLXContext share, Bool direct) 18c041511dScube{ 19c041511dScube /* KLUDGE: GLX really expects a display pointer to be passed 20c041511dScube in as the first parameter, but Win32 needs an HDC instead, 21c041511dScube so BE SURE that the global XHDC is set before calling this 22c041511dScube routine. */ 23c041511dScube HGLRC context; 24c041511dScube 252590f9beSmrg context = wglCreateContext(XHDC); 26c041511dScube 27c041511dScube#if 0 28c041511dScube /* XXX GLUT doesn't support it now, so don't worry about display list 29c041511dScube and texture object sharing. */ 30c041511dScube if (share) { 31c041511dScube wglShareLists(share, context); 32c041511dScube } 33c041511dScube#endif 34c041511dScube 35c041511dScube /* Since direct rendering is implicit, the direct flag is 36c041511dScube ignored. */ 37c041511dScube 38c041511dScube return context; 39c041511dScube} 40c041511dScube 41c041511dScubeint 42c041511dScubeglXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value) 43c041511dScube{ 44c041511dScube if (!visual) 45c041511dScube return GLX_BAD_VISUAL; 46c041511dScube 47c041511dScube switch (attrib) { 48c041511dScube case GLX_USE_GL: 49c041511dScube if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) { 50c041511dScube /* XXX Brad's Matrix Millenium II has problems creating 51c041511dScube color index windows in 24-bit mode (lead to GDI crash) 52c041511dScube and 32-bit mode (lead to black window). The cColorBits 53c041511dScube filed of the PIXELFORMATDESCRIPTOR returned claims to 54c041511dScube have 24 and 32 bits respectively of color indices. 2^24 55c041511dScube and 2^32 are ridiculously huge writable colormaps. 56c041511dScube Assume that if we get back a color index 57c041511dScube PIXELFORMATDESCRIPTOR with 24 or more bits, the 58c041511dScube PIXELFORMATDESCRIPTOR doesn't really work and skip it. 59c041511dScube -mjk */ 60c041511dScube if (visual->iPixelType == PFD_TYPE_COLORINDEX 61c041511dScube && visual->cColorBits >= 24) { 62c041511dScube *value = 0; 63c041511dScube } else { 64c041511dScube *value = 1; 65c041511dScube } 66c041511dScube } else { 67c041511dScube *value = 0; 68c041511dScube } 69c041511dScube break; 70c041511dScube case GLX_BUFFER_SIZE: 71c041511dScube /* KLUDGE: if we're RGBA, return the number of bits/pixel, 72c041511dScube otherwise, return 8 (we guessed at 256 colors in CI 73c041511dScube mode). */ 74c041511dScube if (visual->iPixelType == PFD_TYPE_RGBA) 75c041511dScube *value = visual->cColorBits; 76c041511dScube else 77c041511dScube *value = 8; 78c041511dScube break; 79c041511dScube case GLX_LEVEL: 80c041511dScube /* The bReserved flag of the pfd contains the 81c041511dScube overlay/underlay info. */ 82c041511dScube *value = visual->bReserved; 83c041511dScube break; 84c041511dScube case GLX_RGBA: 85c041511dScube *value = visual->iPixelType == PFD_TYPE_RGBA; 86c041511dScube break; 87c041511dScube case GLX_DOUBLEBUFFER: 88c041511dScube *value = visual->dwFlags & PFD_DOUBLEBUFFER; 89c041511dScube break; 90c041511dScube case GLX_STEREO: 91c041511dScube *value = visual->dwFlags & PFD_STEREO; 92c041511dScube break; 93c041511dScube case GLX_AUX_BUFFERS: 94c041511dScube *value = visual->cAuxBuffers; 95c041511dScube break; 96c041511dScube case GLX_RED_SIZE: 97c041511dScube *value = visual->cRedBits; 98c041511dScube break; 99c041511dScube case GLX_GREEN_SIZE: 100c041511dScube *value = visual->cGreenBits; 101c041511dScube break; 102c041511dScube case GLX_BLUE_SIZE: 103c041511dScube *value = visual->cBlueBits; 104c041511dScube break; 105c041511dScube case GLX_ALPHA_SIZE: 106c041511dScube *value = visual->cAlphaBits; 107c041511dScube break; 108c041511dScube case GLX_DEPTH_SIZE: 109c041511dScube *value = visual->cDepthBits; 110c041511dScube break; 111c041511dScube case GLX_STENCIL_SIZE: 112c041511dScube *value = visual->cStencilBits; 113c041511dScube break; 114c041511dScube case GLX_ACCUM_RED_SIZE: 115c041511dScube *value = visual->cAccumRedBits; 116c041511dScube break; 117c041511dScube case GLX_ACCUM_GREEN_SIZE: 118c041511dScube *value = visual->cAccumGreenBits; 119c041511dScube break; 120c041511dScube case GLX_ACCUM_BLUE_SIZE: 121c041511dScube *value = visual->cAccumBlueBits; 122c041511dScube break; 123c041511dScube case GLX_ACCUM_ALPHA_SIZE: 124c041511dScube *value = visual->cAccumAlphaBits; 125c041511dScube break; 126c041511dScube default: 127c041511dScube return GLX_BAD_ATTRIB; 128c041511dScube } 129c041511dScube return 0; 130c041511dScube} 131c041511dScube 132c041511dScubeXVisualInfo * 133c041511dScubeglXChooseVisual(Display * display, int screen, int *attribList) 134c041511dScube{ 135c041511dScube /* KLUDGE: since we need the HDC, MAKE SURE to set XHDC 136c041511dScube before calling this routine. */ 137c041511dScube 138c041511dScube int *p = attribList; 139c041511dScube int pf; 140c041511dScube PIXELFORMATDESCRIPTOR pfd; 141c041511dScube PIXELFORMATDESCRIPTOR *match = NULL; 142c041511dScube int stereo = 0; 143c041511dScube 144c041511dScube /* Avoid seg-faults. */ 145c041511dScube if (!p) 146c041511dScube return NULL; 147c041511dScube 148c041511dScube memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 149c041511dScube pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR)); 150c041511dScube pfd.nVersion = 1; 151c041511dScube 152c041511dScube /* Defaults. */ 153c041511dScube pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; 154c041511dScube pfd.iPixelType = PFD_TYPE_COLORINDEX; 155c041511dScube pfd.cColorBits = 32; 156c041511dScube pfd.cDepthBits = 0; 157c041511dScube 158c041511dScube while (*p) { 159c041511dScube switch (*p) { 160c041511dScube case GLX_USE_GL: 161c041511dScube pfd.dwFlags |= PFD_SUPPORT_OPENGL; 162c041511dScube break; 163c041511dScube case GLX_BUFFER_SIZE: 164c041511dScube pfd.cColorBits = *(++p); 165c041511dScube break; 166c041511dScube case GLX_LEVEL: 167c041511dScube /* the bReserved flag of the pfd contains the 168c041511dScube overlay/underlay info. */ 169c041511dScube pfd.bReserved = *(++p); 170c041511dScube break; 171c041511dScube case GLX_RGBA: 172c041511dScube pfd.iPixelType = PFD_TYPE_RGBA; 173c041511dScube break; 174c041511dScube case GLX_DOUBLEBUFFER: 175c041511dScube pfd.dwFlags |= PFD_DOUBLEBUFFER; 176c041511dScube break; 177c041511dScube case GLX_STEREO: 178c041511dScube stereo = 1; 179c041511dScube pfd.dwFlags |= PFD_STEREO; 180c041511dScube break; 181c041511dScube case GLX_AUX_BUFFERS: 182c041511dScube pfd.cAuxBuffers = *(++p); 183c041511dScube break; 184c041511dScube case GLX_RED_SIZE: 185c041511dScube pfd.cRedBits = 8; /* Try to get the maximum. */ 186c041511dScube ++p; 187c041511dScube break; 188c041511dScube case GLX_GREEN_SIZE: 189c041511dScube pfd.cGreenBits = 8; 190c041511dScube ++p; 191c041511dScube break; 192c041511dScube case GLX_BLUE_SIZE: 193c041511dScube pfd.cBlueBits = 8; 194c041511dScube ++p; 195c041511dScube break; 196c041511dScube case GLX_ALPHA_SIZE: 197c041511dScube pfd.cAlphaBits = 8; 198c041511dScube ++p; 199c041511dScube break; 200c041511dScube case GLX_DEPTH_SIZE: 201c041511dScube pfd.cDepthBits = 32; 202c041511dScube ++p; 203c041511dScube break; 204c041511dScube case GLX_STENCIL_SIZE: 205c041511dScube pfd.cStencilBits = *(++p); 206c041511dScube break; 207c041511dScube case GLX_ACCUM_RED_SIZE: 208c041511dScube case GLX_ACCUM_GREEN_SIZE: 209c041511dScube case GLX_ACCUM_BLUE_SIZE: 210c041511dScube case GLX_ACCUM_ALPHA_SIZE: 211c041511dScube /* I believe that WGL only used the cAccumRedBits, 212c041511dScube cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields 213c041511dScube when returning info about the accumulation buffer precision. 214c041511dScube Only cAccumBits is used for requesting an accumulation 215c041511dScube buffer. */ 216c041511dScube pfd.cAccumBits = 1; 217c041511dScube ++p; 218c041511dScube break; 219c041511dScube } 220c041511dScube ++p; 221c041511dScube } 222c041511dScube 223c041511dScube /* Let Win32 choose one for us. */ 224c041511dScube pf = ChoosePixelFormat(XHDC, &pfd); 225c041511dScube if (pf > 0) { 226c041511dScube match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR)); 227c041511dScube DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match); 228c041511dScube 229c041511dScube /* ChoosePixelFormat is dumb in that it will return a pixel 230c041511dScube format that doesn't have stereo even if it was requested 231c041511dScube so we need to make sure that if stereo was selected, we 232c041511dScube got it. */ 233c041511dScube if (stereo) { 234c041511dScube if (!(match->dwFlags & PFD_STEREO)) { 235c041511dScube free(match); 236c041511dScube return NULL; 237c041511dScube } 238c041511dScube } 239c041511dScube /* XXX Brad's Matrix Millenium II has problems creating 240c041511dScube color index windows in 24-bit mode (lead to GDI crash) 241c041511dScube and 32-bit mode (lead to black window). The cColorBits 242c041511dScube filed of the PIXELFORMATDESCRIPTOR returned claims to 243c041511dScube have 24 and 32 bits respectively of color indices. 2^24 244c041511dScube and 2^32 are ridiculously huge writable colormaps. 245c041511dScube Assume that if we get back a color index 246c041511dScube PIXELFORMATDESCRIPTOR with 24 or more bits, the 247c041511dScube PIXELFORMATDESCRIPTOR doesn't really work and skip it. 248c041511dScube -mjk */ 249c041511dScube if (match->iPixelType == PFD_TYPE_COLORINDEX 250c041511dScube && match->cColorBits >= 24) { 251c041511dScube free(match); 252c041511dScube return NULL; 253c041511dScube } 254c041511dScube } 255c041511dScube return match; 256c041511dScube} 257