summaryrefslogtreecommitdiffstats
path: root/src/glut/glx/win32_glx.c
blob: 3522e606ec881c4d4efd506b913ed247062ada3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

/* Copyright (c) Nate Robins, 1997. */

/* This program is freely distributable without licensing fees
   and is provided without guarantee or warrantee expressed or
   implied. This program is -not- in the public domain. */

#include <stdio.h>
#include "glutint.h"
#include "win32_glx.h"

/* global current HDC */
extern HDC XHDC;

GLXContext
glXCreateContext(Display * display, XVisualInfo * visinfo,
  GLXContext share, Bool direct)
{
  /* KLUDGE: GLX really expects a display pointer to be passed
     in as the first parameter, but Win32 needs an HDC instead,
     so BE SURE that the global XHDC is set before calling this
     routine. */
  HGLRC context;

  context = wglCreateContext(XHDC);

#if 0
  /* XXX GLUT doesn't support it now, so don't worry about display list
     and texture object sharing. */
  if (share) {
    wglShareLists(share, context);
  }
#endif

  /* Since direct rendering is implicit, the direct flag is
     ignored. */

  return context;
}

int
glXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value)
{
  if (!visual)
    return GLX_BAD_VISUAL;

  switch (attrib) {
  case GLX_USE_GL:
    if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) {
      /* XXX Brad's Matrix Millenium II has problems creating
         color index windows in 24-bit mode (lead to GDI crash)
         and 32-bit mode (lead to black window).  The cColorBits
         filed of the PIXELFORMATDESCRIPTOR returned claims to
         have 24 and 32 bits respectively of color indices. 2^24
         and 2^32 are ridiculously huge writable colormaps.
         Assume that if we get back a color index
         PIXELFORMATDESCRIPTOR with 24 or more bits, the
         PIXELFORMATDESCRIPTOR doesn't really work and skip it.
         -mjk */
      if (visual->iPixelType == PFD_TYPE_COLORINDEX
        && visual->cColorBits >= 24) {
        *value = 0;
      } else {
	*value = 1;
      }
    } else {
      *value = 0;
    }
    break;
  case GLX_BUFFER_SIZE:
    /* KLUDGE: if we're RGBA, return the number of bits/pixel,
       otherwise, return 8 (we guessed at 256 colors in CI
       mode). */
    if (visual->iPixelType == PFD_TYPE_RGBA)
      *value = visual->cColorBits;
    else
      *value = 8;
    break;
  case GLX_LEVEL:
    /* The bReserved flag of the pfd contains the
       overlay/underlay info. */
    *value = visual->bReserved;
    break;
  case GLX_RGBA:
    *value = visual->iPixelType == PFD_TYPE_RGBA;
    break;
  case GLX_DOUBLEBUFFER:
    *value = visual->dwFlags & PFD_DOUBLEBUFFER;
    break;
  case GLX_STEREO:
    *value = visual->dwFlags & PFD_STEREO;
    break;
  case GLX_AUX_BUFFERS:
    *value = visual->cAuxBuffers;
    break;
  case GLX_RED_SIZE:
    *value = visual->cRedBits;
    break;
  case GLX_GREEN_SIZE:
    *value = visual->cGreenBits;
    break;
  case GLX_BLUE_SIZE:
    *value = visual->cBlueBits;
    break;
  case GLX_ALPHA_SIZE:
    *value = visual->cAlphaBits;
    break;
  case GLX_DEPTH_SIZE:
    *value = visual->cDepthBits;
    break;
  case GLX_STENCIL_SIZE:
    *value = visual->cStencilBits;
    break;
  case GLX_ACCUM_RED_SIZE:
    *value = visual->cAccumRedBits;
    break;
  case GLX_ACCUM_GREEN_SIZE:
    *value = visual->cAccumGreenBits;
    break;
  case GLX_ACCUM_BLUE_SIZE:
    *value = visual->cAccumBlueBits;
    break;
  case GLX_ACCUM_ALPHA_SIZE:
    *value = visual->cAccumAlphaBits;
    break;
  default:
    return GLX_BAD_ATTRIB;
  }
  return 0;
}

XVisualInfo *
glXChooseVisual(Display * display, int screen, int *attribList)
{
  /* KLUDGE: since we need the HDC, MAKE SURE to set XHDC
     before calling this routine. */

  int *p = attribList;
  int pf;
  PIXELFORMATDESCRIPTOR pfd;
  PIXELFORMATDESCRIPTOR *match = NULL;
  int stereo = 0;

  /* Avoid seg-faults. */
  if (!p)
    return NULL;

  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
  pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR));
  pfd.nVersion = 1;

  /* Defaults. */
  pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
  pfd.iPixelType = PFD_TYPE_COLORINDEX;
  pfd.cColorBits = 32;
  pfd.cDepthBits = 0;

  while (*p) {
    switch (*p) {
    case GLX_USE_GL:
      pfd.dwFlags |= PFD_SUPPORT_OPENGL;
      break;
    case GLX_BUFFER_SIZE:
      pfd.cColorBits = *(++p);
      break;
    case GLX_LEVEL:
      /* the bReserved flag of the pfd contains the
         overlay/underlay info. */
      pfd.bReserved = *(++p);
      break;
    case GLX_RGBA:
      pfd.iPixelType = PFD_TYPE_RGBA;
      break;
    case GLX_DOUBLEBUFFER:
      pfd.dwFlags |= PFD_DOUBLEBUFFER;
      break;
    case GLX_STEREO:
      stereo = 1;
      pfd.dwFlags |= PFD_STEREO;
      break;
    case GLX_AUX_BUFFERS:
      pfd.cAuxBuffers = *(++p);
      break;
    case GLX_RED_SIZE:
      pfd.cRedBits = 8; /* Try to get the maximum. */
      ++p;
      break;
    case GLX_GREEN_SIZE:
      pfd.cGreenBits = 8;
      ++p;
      break;
    case GLX_BLUE_SIZE:
      pfd.cBlueBits = 8;
      ++p;
      break;
    case GLX_ALPHA_SIZE:
      pfd.cAlphaBits = 8;
      ++p;
      break;
    case GLX_DEPTH_SIZE:
      pfd.cDepthBits = 32;
      ++p;
      break;
    case GLX_STENCIL_SIZE:
      pfd.cStencilBits = *(++p);
      break;
    case GLX_ACCUM_RED_SIZE:
    case GLX_ACCUM_GREEN_SIZE:
    case GLX_ACCUM_BLUE_SIZE:
    case GLX_ACCUM_ALPHA_SIZE:
      /* I believe that WGL only used the cAccumRedBits,
	 cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields
	 when returning info about the accumulation buffer precision.
	 Only cAccumBits is used for requesting an accumulation
	 buffer. */
      pfd.cAccumBits = 1;
      ++p;
      break;
    }
    ++p;
  }

  /* Let Win32 choose one for us. */
  pf = ChoosePixelFormat(XHDC, &pfd);
  if (pf > 0) {
    match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR));
    DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match);

    /* ChoosePixelFormat is dumb in that it will return a pixel
       format that doesn't have stereo even if it was requested
       so we need to make sure that if stereo was selected, we
       got it. */
    if (stereo) {
      if (!(match->dwFlags & PFD_STEREO)) {
        free(match);
	return NULL;
      }
    }
    /* XXX Brad's Matrix Millenium II has problems creating
       color index windows in 24-bit mode (lead to GDI crash)
       and 32-bit mode (lead to black window).  The cColorBits
       filed of the PIXELFORMATDESCRIPTOR returned claims to
       have 24 and 32 bits respectively of color indices. 2^24
       and 2^32 are ridiculously huge writable colormaps.
       Assume that if we get back a color index
       PIXELFORMATDESCRIPTOR with 24 or more bits, the
       PIXELFORMATDESCRIPTOR doesn't really work and skip it.
       -mjk */
    if (match->iPixelType == PFD_TYPE_COLORINDEX
      && match->cColorBits >= 24) {
      free(match);
      return NULL;
    }
  }
  return match;
}