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