Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2010 VMware, Inc.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 **************************************************************************/
27
 
28
#include 
29
 
30
#define WGL_WGLEXT_PROTOTYPES
31
 
32
#include 
33
#include 
34
 
35
#include "pipe/p_defines.h"
36
#include "pipe/p_screen.h"
37
 
38
#include "stw_device.h"
39
#include "stw_pixelformat.h"
40
#include "stw_framebuffer.h"
41
 
42
 
43
#define LARGE_WINDOW_SIZE 60000
44
 
45
 
46
static LRESULT CALLBACK
47
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
48
{
49
    MINMAXINFO *pMMI;
50
    switch (uMsg) {
51
    case WM_GETMINMAXINFO:
52
        // Allow to create a window bigger than the desktop
53
        pMMI = (MINMAXINFO *)lParam;
54
        pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE;
55
        pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE;
56
        pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE;
57
        pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE;
58
        break;
59
    default:
60
        break;
61
    }
62
 
63
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
64
}
65
 
66
 
67
HPBUFFERARB WINAPI
68
wglCreatePbufferARB(HDC hCurrentDC,
69
                    int iPixelFormat,
70
                    int iWidth,
71
                    int iHeight,
72
                    const int *piAttribList)
73
{
74
   static boolean first = TRUE;
75
   const int *piAttrib;
76
   int useLargest = 0;
77
   const struct stw_pixelformat_info *info;
78
   struct stw_framebuffer *fb;
79
   DWORD dwExStyle;
80
   DWORD dwStyle;
81
   RECT rect;
82
   HWND hWnd;
83
   HDC hDC;
84
   int iDisplayablePixelFormat;
85
   PIXELFORMATDESCRIPTOR pfd;
86
   BOOL bRet;
87
 
88
   info = stw_pixelformat_get_info(iPixelFormat - 1);
89
   if (!info) {
90
      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
91
      return 0;
92
   }
93
 
94
   if (iWidth <= 0 || iHeight <= 0) {
95
      SetLastError(ERROR_INVALID_DATA);
96
      return 0;
97
   }
98
 
99
   for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
100
      switch (*piAttrib) {
101
      case WGL_PBUFFER_LARGEST_ARB:
102
         piAttrib++;
103
         useLargest = *piAttrib;
104
         break;
105
      default:
106
         SetLastError(ERROR_INVALID_DATA);
107
         return 0;
108
      }
109
   }
110
 
111
   if (iWidth > stw_dev->max_2d_length) {
112
      if (useLargest) {
113
         iWidth = stw_dev->max_2d_length;
114
      } else {
115
         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
116
         return 0;
117
      }
118
   }
119
 
120
   if (iHeight > stw_dev->max_2d_length) {
121
      if (useLargest) {
122
         iHeight = stw_dev->max_2d_length;
123
      } else {
124
         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
125
         return 0;
126
      }
127
   }
128
 
129
   /*
130
    * Implement pbuffers through invisible windows
131
    */
132
 
133
   if (first) {
134
      WNDCLASS wc;
135
      memset(&wc, 0, sizeof wc);
136
      wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
137
      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
138
      wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
139
      wc.lpfnWndProc = WndProc;
140
      wc.lpszClassName = "wglpbuffer";
141
      wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
142
      RegisterClass(&wc);
143
      first = FALSE;
144
   }
145
 
146
   dwExStyle = 0;
147
   dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
148
 
149
   if (0) {
150
      /*
151
       * Don't hide the window -- useful for debugging what the application is
152
       * drawing
153
       */
154
 
155
      dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW;
156
   } else {
157
      dwStyle |= WS_POPUPWINDOW;
158
   }
159
 
160
   rect.left = 0;
161
   rect.top = 0;
162
   rect.right = rect.left + iWidth;
163
   rect.bottom = rect.top + iHeight;
164
 
165
   /*
166
    * The CreateWindowEx parameters are the total (outside) dimensions of the
167
    * window, which can vary with Windows version and user settings.  Use
168
    * AdjustWindowRect to get the required total area for the given client area.
169
    *
170
    * AdjustWindowRectEx does not accept WS_OVERLAPPED style (which is defined
171
    * as 0), which means we need to use some other style instead, e.g.,
172
    * WS_OVERLAPPEDWINDOW or WS_POPUPWINDOW as above.
173
    */
174
 
175
   AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
176
 
177
   hWnd = CreateWindowEx(dwExStyle,
178
                         "wglpbuffer", /* wc.lpszClassName */
179
                         NULL,
180
                         dwStyle,
181
                         CW_USEDEFAULT, /* x */
182
                         CW_USEDEFAULT, /* y */
183
                         rect.right - rect.left, /* width */
184
                         rect.bottom - rect.top, /* height */
185
                         NULL,
186
                         NULL,
187
                         NULL,
188
                         NULL);
189
   if (!hWnd) {
190
      return 0;
191
   }
192
 
193
#ifdef DEBUG
194
   /*
195
    * Verify the client area size matches the specified size.
196
    */
197
 
198
   GetClientRect(hWnd, &rect);
199
   assert(rect.left == 0);
200
   assert(rect.top == 0);
201
   assert(rect.right - rect.left == iWidth);
202
   assert(rect.bottom - rect.top == iHeight);
203
#endif
204
 
205
   hDC = GetDC(hWnd);
206
   if (!hDC) {
207
      return 0;
208
   }
209
 
210
   /*
211
    * We can't pass non-displayable pixel formats to GDI, which is why we
212
    * create the framebuffer object before calling SetPixelFormat().
213
    */
214
   fb = stw_framebuffer_create(hDC, iPixelFormat);
215
   if (!fb) {
216
      SetLastError(ERROR_NO_SYSTEM_RESOURCES);
217
      return NULL;
218
   }
219
 
220
   fb->bPbuffer = TRUE;
221
   iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
222
 
223
   stw_framebuffer_release(fb);
224
 
225
   /*
226
    * We need to set a displayable pixel format on the hidden window DC
227
    * so that wglCreateContext and wglMakeCurrent are not overruled by GDI.
228
    */
229
   bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd);
230
   assert(bRet);
231
 
232
   return (HPBUFFERARB)fb;
233
}
234
 
235
 
236
HDC WINAPI
237
wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
238
{
239
   struct stw_framebuffer *fb;
240
   HDC hDC;
241
 
242
   if (!hPbuffer) {
243
      SetLastError(ERROR_INVALID_HANDLE);
244
      return NULL;
245
   }
246
 
247
   fb = (struct stw_framebuffer *)hPbuffer;
248
 
249
   hDC = GetDC(fb->hWnd);
250
 
251
   return hDC;
252
}
253
 
254
 
255
int WINAPI
256
wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
257
                       HDC hDC)
258
{
259
   struct stw_framebuffer *fb;
260
 
261
   if (!hPbuffer) {
262
      SetLastError(ERROR_INVALID_HANDLE);
263
      return 0;
264
   }
265
 
266
   fb = (struct stw_framebuffer *)hPbuffer;
267
 
268
   return ReleaseDC(fb->hWnd, hDC);
269
}
270
 
271
 
272
BOOL WINAPI
273
wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
274
{
275
   struct stw_framebuffer *fb;
276
 
277
   if (!hPbuffer) {
278
      SetLastError(ERROR_INVALID_HANDLE);
279
      return FALSE;
280
   }
281
 
282
   fb = (struct stw_framebuffer *)hPbuffer;
283
 
284
   /* This will destroy all our data */
285
   return DestroyWindow(fb->hWnd);
286
}
287
 
288
 
289
BOOL WINAPI
290
wglQueryPbufferARB(HPBUFFERARB hPbuffer,
291
                   int iAttribute,
292
                   int *piValue)
293
{
294
   struct stw_framebuffer *fb;
295
 
296
   if (!hPbuffer) {
297
      SetLastError(ERROR_INVALID_HANDLE);
298
      return FALSE;
299
   }
300
 
301
   fb = (struct stw_framebuffer *)hPbuffer;
302
 
303
   switch (iAttribute) {
304
   case WGL_PBUFFER_WIDTH_ARB:
305
      *piValue = fb->width;
306
      return TRUE;
307
   case WGL_PBUFFER_HEIGHT_ARB:
308
      *piValue = fb->height;
309
      return TRUE;
310
   case WGL_PBUFFER_LOST_ARB:
311
      /* We assume that no content is ever lost due to display mode change */
312
      *piValue = FALSE;
313
      return TRUE;
314
   default:
315
      SetLastError(ERROR_INVALID_DATA);
316
      return FALSE;
317
   }
318
}