VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c@ 16281

Last change on this file since 16281 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 32.2 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7
8#define WIN32_LEAN_AND_MEAN
9#include <windows.h>
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <memory.h>
14
15#include "cr_environment.h"
16#include "cr_error.h"
17#include "cr_string.h"
18#include "renderspu.h"
19#include "cr_mem.h"
20
21#define WINDOW_NAME window->title
22
23static BOOL
24bSetupPixelFormat( HDC hdc, GLbitfield visAttribs );
25
26GLboolean renderspu_SystemInitVisual( VisualInfo *visual )
27{
28 if (visual->visAttribs & CR_PBUFFER_BIT) {
29 crWarning("Render SPU: PBuffers not support on Windows yet.");
30 }
31
32 /* In the windows world, we need a window before a context.
33 * Use the device_context as a marker to do just that */
34 visual->device_context = 0;
35
36 return TRUE;
37}
38
39void renderspu_SystemDestroyWindow( WindowInfo *window )
40{
41 VBOX_RENDERSPU_DESTROY_WINDOW vrdw;
42
43 CRASSERT(window);
44
45 /*DestroyWindow( window->hWnd );*/
46
47 vrdw.hWnd = window->hWnd;
48
49 PostThreadMessage(render_spu.dwWinThreadId, WM_VBOX_RENDERSPU_DESTROY_WINDOW, 0, (LPARAM) &vrdw);
50 WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
51
52 window->hWnd = NULL;
53 window->visual = NULL;
54}
55
56static LONG WINAPI
57MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
58{
59 /* int w,h; */
60
61 switch ( uMsg ) {
62
63 case WM_SIZE:
64 /* w = LOWORD( lParam );
65 * h = HIWORD( lParam ); */
66
67 /* glViewport( 0, 0, w, h ); */
68#if 0
69 glViewport( -render_spu.mural_x, -render_spu.mural_y,
70 render_spu.mural_width, render_spu.mural_height );
71 glScissor( -render_spu.mural_x, -render_spu.mural_y,
72 render_spu.mural_width, render_spu.mural_height );
73#endif
74 break;
75
76 case WM_CLOSE:
77 crWarning( "Render SPU: caught WM_CLOSE -- quitting." );
78 exit( 0 );
79 break;
80
81 case WM_NCHITTEST:
82 crDebug("WM_NCHITTEST");
83 return HTNOWHERE;
84 }
85
86 return DefWindowProc( hWnd, uMsg, wParam, lParam );
87}
88
89static BOOL
90bSetupPixelFormatEXT( HDC hdc, GLbitfield visAttribs)
91{
92 PIXELFORMATDESCRIPTOR ppfd;
93 int pixelFormat;
94 int attribList[100];
95 float fattribList[] = { 0.0, 0.0 };
96 int numFormats;
97 int i = 0;
98 BOOL vis;
99
100 CRASSERT(visAttribs & CR_RGB_BIT); /* anybody need color index */
101
102 crWarning("Render SPU: Using WGL_EXT_pixel_format to select visual ID.");
103
104 attribList[i++] = WGL_DRAW_TO_WINDOW_EXT;
105 attribList[i++] = GL_TRUE;
106 attribList[i++] = WGL_ACCELERATION_EXT;
107 attribList[i++] = WGL_FULL_ACCELERATION_EXT;
108 attribList[i++] = WGL_COLOR_BITS_EXT;
109 attribList[i++] = 24;
110 attribList[i++] = WGL_RED_BITS_EXT;
111 attribList[i++] = 1;
112 attribList[i++] = WGL_GREEN_BITS_EXT;
113 attribList[i++] = 1;
114 attribList[i++] = WGL_BLUE_BITS_EXT;
115 attribList[i++] = 1;
116
117 crWarning("Render SPU: Visual chosen is... RGB");
118
119 if (visAttribs & CR_ALPHA_BIT)
120 {
121 attribList[i++] = WGL_ALPHA_BITS_EXT;
122 attribList[i++] = 1;
123 crWarning("A");
124 }
125
126 crWarning(", ");
127
128 if (visAttribs & CR_DOUBLE_BIT) {
129 attribList[i++] = WGL_DOUBLE_BUFFER_EXT;
130 attribList[i++] = GL_TRUE;
131 crWarning("DB, ");
132 }
133
134 if (visAttribs & CR_STEREO_BIT) {
135 attribList[i++] = WGL_STEREO_EXT;
136 attribList[i++] = GL_TRUE;
137 crWarning("Stereo, ");
138 }
139
140 if (visAttribs & CR_DEPTH_BIT)
141 {
142 attribList[i++] = WGL_DEPTH_BITS_EXT;
143 attribList[i++] = 1;
144 crWarning("Z, ");
145 }
146
147 if (visAttribs & CR_STENCIL_BIT)
148 {
149 attribList[i++] = WGL_STENCIL_BITS_EXT;
150 attribList[i++] = 1;
151 crWarning("Stencil, ");
152 }
153
154 if (visAttribs & CR_ACCUM_BIT)
155 {
156 attribList[i++] = WGL_ACCUM_RED_BITS_EXT;
157 attribList[i++] = 1;
158 attribList[i++] = WGL_ACCUM_GREEN_BITS_EXT;
159 attribList[i++] = 1;
160 attribList[i++] = WGL_ACCUM_BLUE_BITS_EXT;
161 attribList[i++] = 1;
162 crWarning("Accum, ");
163 if (visAttribs & CR_ALPHA_BIT)
164 {
165 attribList[i++] = WGL_ACCUM_ALPHA_BITS_EXT;
166 attribList[i++] = 1;
167 crWarning("Accum Alpha, ");
168 }
169 }
170
171 if (visAttribs & CR_MULTISAMPLE_BIT)
172 {
173 attribList[i++] = WGL_SAMPLE_BUFFERS_EXT;
174 attribList[i++] = 1;
175 attribList[i++] = WGL_SAMPLES_EXT;
176 attribList[i++] = 4;
177 crWarning("Multisample, ");
178 }
179
180 crWarning("\n");
181
182 /* End the list */
183 attribList[i++] = 0;
184 attribList[i++] = 0;
185
186 vis = render_spu.ws.wglChoosePixelFormatEXT( hdc, attribList, fattribList, 1, &pixelFormat, &numFormats);
187
188 crDebug("Render SPU: wglChoosePixelFormatEXT (vis 0x%x, LastError 0x%x, pixelFormat 0x%x", vis, GetLastError(), pixelFormat);
189
190 render_spu.ws.wglSetPixelFormat( hdc, pixelFormat, &ppfd );
191
192 crDebug("Render SPU: wglSetPixelFormat (Last error 0x%x)", GetLastError());
193
194 return vis;
195}
196
197static BOOL
198bSetupPixelFormatNormal( HDC hdc, GLbitfield visAttribs )
199{
200 PIXELFORMATDESCRIPTOR pfd = {
201 sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
202 1, /* version number */
203 PFD_DRAW_TO_WINDOW | /* support window */
204 PFD_SUPPORT_OPENGL, /* support OpenGL */
205 PFD_TYPE_RGBA, /* RGBA type */
206 24, /* 24-bit color depth */
207 0, 0, 0, 0, 0, 0, /* color bits ignored */
208 0, /* no alpha buffer */
209 0, /* shift bit ignored */
210 0, /* no accumulation buffer */
211 0, 0, 0, 0, /* accum bits ignored */
212 0, /* set depth buffer */
213 0, /* set stencil buffer */
214 0, /* no auxiliary buffer */
215 PFD_MAIN_PLANE, /* main layer */
216 0, /* reserved */
217 0, 0, 0 /* layer masks ignored */
218 };
219 PIXELFORMATDESCRIPTOR *ppfd = &pfd;
220 char s[1000];
221 GLbitfield b = 0;
222 int pixelformat;
223
224 renderspuMakeVisString( visAttribs, s );
225
226 crWarning( "Render SPU: WGL wants these visual capabilities: %s", s);
227
228 /* These really come into play with sort-last configs */
229 if (visAttribs & CR_DEPTH_BIT)
230 ppfd->cDepthBits = 24;
231 if (visAttribs & CR_ACCUM_BIT)
232 ppfd->cAccumBits = 16;
233 if (visAttribs & CR_RGB_BIT)
234 ppfd->cColorBits = 24;
235 if (visAttribs & CR_STENCIL_BIT)
236 ppfd->cStencilBits = 8;
237 if (visAttribs & CR_ALPHA_BIT)
238 ppfd->cAlphaBits = 8;
239 if (visAttribs & CR_DOUBLE_BIT)
240 ppfd->dwFlags |= PFD_DOUBLEBUFFER;
241 if (visAttribs & CR_STEREO_BIT)
242 ppfd->dwFlags |= PFD_STEREO;
243
244 /*
245 * We call the wgl functions directly if the SPU was loaded
246 * by our faker library, otherwise we have to call the GDI
247 * versions.
248 */
249 if (crGetenv( "CR_WGL_DO_NOT_USE_GDI" ) != NULL)
250 {
251 pixelformat = render_spu.ws.wglChoosePixelFormat( hdc, ppfd );
252 /* doing this twice is normal Win32 magic */
253 pixelformat = render_spu.ws.wglChoosePixelFormat( hdc, ppfd );
254 if ( pixelformat == 0 )
255 {
256 crError( "render_spu.ws.wglChoosePixelFormat failed" );
257 }
258 if ( !render_spu.ws.wglSetPixelFormat( hdc, pixelformat, ppfd ) )
259 {
260 crError( "render_spu.ws.wglSetPixelFormat failed" );
261 }
262
263 render_spu.ws.wglDescribePixelFormat( hdc, pixelformat, sizeof(*ppfd), ppfd );
264 }
265 else
266 {
267 /* Okay, we were loaded manually. Call the GDI functions. */
268 pixelformat = ChoosePixelFormat( hdc, ppfd );
269 /* doing this twice is normal Win32 magic */
270 pixelformat = ChoosePixelFormat( hdc, ppfd );
271 if ( pixelformat == 0 )
272 {
273 crError( "ChoosePixelFormat failed" );
274 }
275 if ( !SetPixelFormat( hdc, pixelformat, ppfd ) )
276 {
277 crError( "SetPixelFormat failed (Error 0x%x)", GetLastError() );
278 }
279
280 DescribePixelFormat( hdc, pixelformat, sizeof(*ppfd), ppfd );
281 }
282
283
284 if (ppfd->cDepthBits > 0)
285 b |= CR_DEPTH_BIT;
286 if (ppfd->cAccumBits > 0)
287 b |= CR_ACCUM_BIT;
288 if (ppfd->cColorBits > 8)
289 b |= CR_RGB_BIT;
290 if (ppfd->cStencilBits > 0)
291 b |= CR_STENCIL_BIT;
292 if (ppfd->cAlphaBits > 0)
293 b |= CR_ALPHA_BIT;
294 if (ppfd->dwFlags & PFD_DOUBLEBUFFER)
295 b |= CR_DOUBLE_BIT;
296 if (ppfd->dwFlags & PFD_STEREO)
297 b |= CR_STEREO_BIT;
298
299 renderspuMakeVisString( b, s );
300
301 crWarning( "Render SPU: WGL chose these visual capabilities: %s", s);
302 return TRUE;
303}
304
305static BOOL
306bSetupPixelFormat( HDC hdc, GLbitfield visAttribs )
307{
308 if (render_spu.ws.wglChoosePixelFormatEXT)
309 return bSetupPixelFormatEXT( hdc, visAttribs );
310 else
311 return bSetupPixelFormatNormal( hdc, visAttribs );
312}
313
314GLboolean renderspu_SystemCreateWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
315{
316 HDESK desktop;
317 HINSTANCE hinstance;
318 WNDCLASS wc;
319 DWORD window_style;
320 int window_plus_caption_width;
321 int window_plus_caption_height;
322
323 window->visual = visual;
324 window->nativeWindow = 0;
325
326 if ( render_spu.use_L2 )
327 {
328 crWarning( "Going fullscreen because we think we're using Lightning-2." );
329 render_spu.fullscreen = 1;
330 }
331
332 /*
333 * Begin Windows / WGL code
334 */
335
336 hinstance = GetModuleHandle( NULL );
337 if (!hinstance)
338 {
339 crError( "Render SPU: Couldn't get a handle to my module." );
340 return GL_FALSE;
341 }
342 crDebug( "Render SPU: Got the module handle: 0x%x", hinstance );
343
344 /* If we were launched from a service, telnet, or rsh, we need to
345 * get the input desktop. */
346
347 desktop = OpenInputDesktop( 0, FALSE,
348 DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
349 DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
350 DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
351 DESKTOP_SWITCHDESKTOP | GENERIC_WRITE );
352
353 if ( !desktop )
354 {
355 crError( "Render SPU: Couldn't aquire input desktop" );
356 return GL_FALSE;
357 }
358 crDebug( "Render SPU: Got the desktop: 0x%x", desktop );
359
360 if ( !SetThreadDesktop( desktop ) )
361 {
362 /* If this function fails, it's probably because
363 * it's already been called (i.e., the render SPU
364 * is bolted to an application?) */
365
366 /*crError( "Couldn't set thread to input desktop" ); */
367 }
368 crDebug( "Render SPU: Set the thread desktop -- this might have failed." );
369
370 if ( !GetClassInfo(hinstance, WINDOW_NAME, &wc) )
371 {
372 wc.style = CS_OWNDC;
373 wc.lpfnWndProc = (WNDPROC) MainWndProc;
374 wc.cbClsExtra = 0;
375 wc.cbWndExtra = 0;
376 wc.hInstance = hinstance;
377 wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
378 wc.hCursor = LoadCursor( NULL, IDC_ARROW );
379 wc.hbrBackground = NULL;
380 wc.lpszMenuName = NULL;
381 wc.lpszClassName = WINDOW_NAME;
382
383 if ( !RegisterClass( &wc ) )
384 {
385 crError( "Render SPU: Couldn't register window class -- you're not trying "
386 "to do multi-pipe stuff on windows, are you?\n\nNote --"
387 "This error message is from 1997 and probably doesn't make"
388 "any sense any more, but it's nostalgic for Humper." );
389 return GL_FALSE;
390 }
391 crDebug( "Render SPU: Registered the class" );
392 }
393 crDebug( "Render SPU: Got the class information" );
394
395 /* Full screen window should be a popup (undecorated) window */
396#if 1
397 window_style = ( render_spu.fullscreen ? WS_POPUP : WS_CAPTION );
398#else
399 window_style = ( WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
400 window_style |= WS_SYSMENU;
401#endif
402
403 crDebug( "Render SPU: Fullscreen: %s", render_spu.fullscreen ? "yes" : "no");
404
405 if ( render_spu.fullscreen )
406 {
407#if 0
408
409 int smCxFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME );
410 int smCyFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME ) + 1;
411 int smCyCaption = GetSystemMetrics( SM_CYCAPTION );
412
413 window->width = GetSystemMetrics( SM_CXSCREEN ) ;
414 window->height = GetSystemMetrics( SM_CYSCREEN ) ;
415
416 crDebug( "Render SPU: Window Dims: %d, %d", window->width, window->height );
417
418 window->x = render_spu->defaultX - smCxFixedFrame - 1;
419 window->y = render_spu->defaultY - smCyFixedFrame - smCyCaption;
420
421 window_plus_caption_width = window->width + 2 * smCxFixedFrame;
422 window_plus_caption_height = window->height + 2 * smCyFixedFrame + smCyCaption;
423
424#else
425 /* Since it's undecorated, we don't have to do anything fancy
426 * with these parameters. */
427
428 window->width = GetSystemMetrics( SM_CXSCREEN ) ;
429 window->height = GetSystemMetrics( SM_CYSCREEN ) ;
430 window->x = 0;
431 window->y = 0;
432 window_plus_caption_width = window->width;
433 window_plus_caption_height = window->height;
434
435#endif
436 }
437 else
438 {
439 /* CreateWindow takes the size of the entire window, so we add
440 * in the size necessary for the frame and the caption. */
441
442 int smCxFixedFrame, smCyFixedFrame, smCyCaption;
443 smCxFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME );
444 crDebug( "Render SPU: Got the X fixed frame" );
445 smCyFixedFrame = GetSystemMetrics( SM_CYFIXEDFRAME );
446 crDebug( "Render SPU: Got the Y fixed frame" );
447 smCyCaption = GetSystemMetrics( SM_CYCAPTION );
448 crDebug( "Render SPU: Got the Caption " );
449
450 window_plus_caption_width = window->width + 2 * smCxFixedFrame;
451 window_plus_caption_height = window->height + 2 * smCyFixedFrame + smCyCaption;
452
453 window->x = render_spu.defaultX - smCxFixedFrame;
454 window->y = render_spu.defaultY - smCyFixedFrame - smCyCaption;
455 }
456
457 crDebug( "Render SPU: Creating the window: (%d,%d), (%d,%d)", render_spu.defaultX, render_spu.defaultY, window_plus_caption_width, window_plus_caption_height );
458 window->hWnd = CreateWindow( WINDOW_NAME, WINDOW_NAME,
459 window_style,
460 window->x, window->y,
461 window_plus_caption_width,
462 window_plus_caption_height,
463 NULL, NULL, hinstance, &render_spu );
464
465 if ( !window->hWnd )
466 {
467 crError( "Render SPU: Create Window failed! That's almost certainly terrible." );
468 return GL_FALSE;
469 }
470
471 if (showIt) {
472 /* NO ERROR CODE FOR SHOWWINDOW */
473 crDebug( "Render SPU: Showing the window" );
474 ShowWindow( window->hWnd, SW_SHOWNORMAL );
475 }
476
477 SetForegroundWindow( window->hWnd );
478
479 SetWindowPos( window->hWnd, HWND_TOP, window->x, window->y,
480 window_plus_caption_width, window_plus_caption_height,
481 ( render_spu.fullscreen ? (SWP_SHOWWINDOW |
482 SWP_NOSENDCHANGING |
483 SWP_NOREDRAW |
484 SWP_NOACTIVATE ) :
485 0 ) );
486
487 if ( render_spu.fullscreen )
488 ShowCursor( FALSE );
489
490 window->device_context = GetDC( window->hWnd );
491
492 crDebug( "Render SPU: Got the DC: 0x%x", window->device_context );
493
494 if ( !bSetupPixelFormat( window->device_context, visual->visAttribs ) )
495 {
496 crError( "Render SPU: Couldn't set up the device context! Yikes!" );
497 return GL_FALSE;
498 }
499
500 return GL_TRUE;
501}
502
503GLboolean renderspu_SystemVBoxCreateWindow( VisualInfo *visual, GLboolean showIt, WindowInfo *window )
504{
505 HDESK desktop;
506 HINSTANCE hinstance;
507 WNDCLASS wc;
508 DWORD window_style;
509 int window_plus_caption_width;
510 int window_plus_caption_height;
511
512 window->visual = visual;
513 window->nativeWindow = 0;
514
515 if ( render_spu.use_L2 )
516 {
517 crWarning( "Going fullscreen because we think we're using Lightning-2." );
518 render_spu.fullscreen = 1;
519 }
520
521 /*
522 * Begin Windows / WGL code
523 */
524
525 hinstance = GetModuleHandle( NULL );
526 if (!hinstance)
527 {
528 crError( "Render SPU: Couldn't get a handle to my module." );
529 return GL_FALSE;
530 }
531 crDebug( "Render SPU: Got the module handle: 0x%x", hinstance );
532
533#if 0
534 /* If we were launched from a service, telnet, or rsh, we need to
535 * get the input desktop. */
536
537 desktop = OpenInputDesktop( 0, FALSE,
538 DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
539 DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
540 DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
541 DESKTOP_SWITCHDESKTOP | GENERIC_WRITE );
542
543 if ( !desktop )
544 {
545 crError( "Render SPU: Couldn't aquire input desktop" );
546 return GL_FALSE;
547 }
548 crDebug( "Render SPU: Got the desktop: 0x%x", desktop );
549
550 if ( !SetThreadDesktop( desktop ) )
551 {
552 /* If this function fails, it's probably because
553 * it's already been called (i.e., the render SPU
554 * is bolted to an application?) */
555
556 /*crError( "Couldn't set thread to input desktop" ); */
557 }
558 crDebug( "Render SPU: Set the thread desktop -- this might have failed." );
559#endif
560
561 if ( !GetClassInfo(hinstance, WINDOW_NAME, &wc) )
562 {
563 wc.style = CS_OWNDC; // | CS_PARENTDC;
564 wc.lpfnWndProc = (WNDPROC) MainWndProc;
565 wc.cbClsExtra = 0;
566 wc.cbWndExtra = 0;
567 wc.hInstance = hinstance;
568 wc.hIcon = NULL; //LoadIcon( NULL, IDI_APPLICATION );
569 wc.hCursor = NULL; //LoadCursor( NULL, IDC_ARROW );
570 wc.hbrBackground = NULL;
571 wc.lpszMenuName = NULL;
572 wc.lpszClassName = WINDOW_NAME;
573
574 if ( !RegisterClass( &wc ) )
575 {
576 crError( "Render SPU: Couldn't register window class -- you're not trying "
577 "to do multi-pipe stuff on windows, are you?\n\nNote --"
578 "This error message is from 1997 and probably doesn't make"
579 "any sense any more, but it's nostalgic for Humper." );
580 return GL_FALSE;
581 }
582 crDebug( "Render SPU: Registered the class" );
583 }
584 crDebug( "Render SPU: Got the class information" );
585
586 /* Full screen window should be a popup (undecorated) window */
587#if 1
588 window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED;
589 if (render_spu_parent_window_id)
590 {
591 window_style |= WS_CHILD;
592 }
593#else
594 window_style = ( WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
595 window_style |= WS_SYSMENU;
596#endif
597
598 crDebug( "Render SPU: Fullscreen: %s", render_spu.fullscreen ? "yes" : "no");
599
600 if ( render_spu.fullscreen )
601 {
602#if 0
603
604 int smCxFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME );
605 int smCyFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME ) + 1;
606 int smCyCaption = GetSystemMetrics( SM_CYCAPTION );
607
608 window->width = GetSystemMetrics( SM_CXSCREEN ) ;
609 window->height = GetSystemMetrics( SM_CYSCREEN ) ;
610
611 crDebug( "Render SPU: Window Dims: %d, %d", window->width, window->height );
612
613 window->x = render_spu->defaultX - smCxFixedFrame - 1;
614 window->y = render_spu->defaultY - smCyFixedFrame - smCyCaption;
615
616 window_plus_caption_width = window->width + 2 * smCxFixedFrame;
617 window_plus_caption_height = window->height + 2 * smCyFixedFrame + smCyCaption;
618
619#else
620 /* Since it's undecorated, we don't have to do anything fancy
621 * with these parameters. */
622
623 window->width = GetSystemMetrics( SM_CXSCREEN ) ;
624 window->height = GetSystemMetrics( SM_CYSCREEN ) ;
625 window->x = 0;
626 window->y = 0;
627 window_plus_caption_width = window->width;
628 window_plus_caption_height = window->height;
629
630#endif
631 }
632 else
633 {
634 /* CreateWindow takes the size of the entire window, so we add
635 * in the size necessary for the frame and the caption. */
636 int smCxFixedFrame, smCyFixedFrame, smCyCaption;
637 smCxFixedFrame = GetSystemMetrics( SM_CXFIXEDFRAME );
638 crDebug( "Render SPU: Got the X fixed frame" );
639 smCyFixedFrame = GetSystemMetrics( SM_CYFIXEDFRAME );
640 crDebug( "Render SPU: Got the Y fixed frame" );
641 smCyCaption = GetSystemMetrics( SM_CYCAPTION );
642 crDebug( "Render SPU: Got the Caption " );
643
644 window_plus_caption_width = window->width + 2 * smCxFixedFrame;
645 window_plus_caption_height = window->height + 2 * smCyFixedFrame + smCyCaption;
646
647 window->x = render_spu.defaultX;
648 window->y = render_spu.defaultY;
649 }
650
651 crDebug( "Render SPU: Creating the window: (%d,%d), (%d,%d)", render_spu.defaultX, render_spu.defaultY, window_plus_caption_width, window_plus_caption_height );
652 /*window->hWnd = CreateWindowEx( WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY,
653 WINDOW_NAME, WINDOW_NAME,
654 window_style,
655 window->x, window->y,
656 window->width,
657 window->height,
658 (void*) render_spu_parent_window_id, NULL, hinstance, &render_spu );*/
659 {
660 CREATESTRUCT cs;
661
662 cs.lpCreateParams = &window->hWnd;
663
664 cs.dwExStyle = WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY;
665 cs.lpszName = WINDOW_NAME;
666 cs.lpszClass = WINDOW_NAME;
667 cs.style = window_style;
668 cs.x = window->x;
669 cs.y = window->y;
670 cs.cx = window->width;
671 cs.cy = window->height;
672 cs.hwndParent = (void*) render_spu_parent_window_id;
673 cs.hMenu = NULL;
674 cs.hInstance = hinstance;
675
676 PostThreadMessage(render_spu.dwWinThreadId, WM_VBOX_RENDERSPU_CREATE_WINDOW, 0, (LPARAM) &cs);
677 WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
678 }
679
680
681 if ( !window->hWnd )
682 {
683 crError( "Render SPU: Create Window failed! That's almost certainly terrible." );
684 return GL_FALSE;
685 }
686
687 if (showIt) {
688 /* NO ERROR CODE FOR SHOWWINDOW */
689 crDebug( "Render SPU: Showing the window" );
690 ShowWindow( window->hWnd, SW_SHOWNORMAL );
691 }
692
693 //SetForegroundWindow( visual->hWnd );
694
695 SetWindowPos( window->hWnd, HWND_TOP, window->x, window->y,
696 window->width, window->height,
697 ( render_spu.fullscreen ?
698 (SWP_SHOWWINDOW | SWP_NOSENDCHANGING | SWP_NOREDRAW | SWP_NOACTIVATE ) : SWP_NOACTIVATE
699 ) );
700 crDebug("Render SPU: SetWindowPos (%x, %d, %d, %d, %d)", window->hWnd,
701 window->x, window->y, window->width, window->height);
702
703 if ( render_spu.fullscreen )
704 ShowCursor( FALSE );
705
706 window->device_context = GetDC( window->hWnd );
707
708 crDebug( "Render SPU: Got the DC: 0x%x", window->device_context );
709
710 if ( !bSetupPixelFormat( window->device_context, visual->visAttribs ) )
711 {
712 crError( "Render SPU: Couldn't set up the device context! Yikes!" );
713 return GL_FALSE;
714 }
715
716 return GL_TRUE;
717}
718
719
720/* Either show or hide the render SPU's window. */
721void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
722{
723 if (showIt)
724 ShowWindow( window->hWnd, SW_SHOWNORMAL );
725 else
726 ShowWindow( window->hWnd, SW_HIDE );
727}
728
729GLboolean renderspu_SystemCreateContext( VisualInfo *visual, ContextInfo *context, ContextInfo *sharedContext )
730{
731 (void) sharedContext;
732 context->visual = visual;
733
734 /* Found a visual, so we're o.k. to create the context now */
735 if (0/*visual->device_context*/) {
736
737 //crDebug( "Render SPU: Using the DC: 0x%x", visual->device_context );
738
739 //context->hRC = render_spu.ws.wglCreateContext( visual->device_context );
740 if (!context->hRC)
741 {
742 crError( "Render SPU: wglCreateContext failed (error 0x%x)", GetLastError() );
743 return GL_FALSE;
744 }
745 } else {
746 crDebug( "Render SPU: Delaying DC creation " );
747 context->hRC = NULL; /* create it later in makecurrent */
748 }
749
750
751 return GL_TRUE;
752}
753
754void renderspu_SystemDestroyContext( ContextInfo *context )
755{
756 render_spu.ws.wglDeleteContext( context->hRC );
757 context->hRC = NULL;
758}
759
760void renderspu_SystemMakeCurrent( WindowInfo *window, GLint nativeWindow, ContextInfo *context )
761{
762 CRASSERT(render_spu.ws.wglMakeCurrent);
763
764 if (context && window) {
765 if (window->visual != context->visual) {
766 /*
767 * XXX have to revisit this issue!!!
768 *
769 * But for now we destroy the current window
770 * and re-create it with the context's visual abilities
771 */
772
773 /*@todo Chromium has no correct code to remove window ids and associated info from
774 * various tables. This is hack which just hides the root case.
775 */
776 crDebug("Recreating window in renderspu_SystemMakeCurrent\n");
777 renderspu_SystemDestroyWindow( window );
778 renderspu_SystemVBoxCreateWindow( context->visual, window->visible, window );
779 }
780
781 if (render_spu.render_to_app_window && nativeWindow)
782 {
783 /* The render_to_app_window option
784 * is set and we've got a nativeWindow
785 * handle, save the handle for
786 * later calls to swapbuffers().
787 *
788 * NOTE: This doesn't work, except
789 * for software driven Mesa.
790 * We'd need to object link the
791 * crappfaker and crserver to be able to share
792 * the HDC values between processes.. FIXME!
793 */
794 window->nativeWindow = (HDC) nativeWindow;
795 if (context->hRC == 0) {
796 context->hRC = render_spu.ws.wglCreateContext( window->nativeWindow );
797 if (!context->hRC)
798 {
799 crError( "(MakeCurrent) Couldn't create the context for the window (error 0x%x)", GetLastError() );
800 }
801 }
802 render_spu.ws.wglMakeCurrent( window->nativeWindow, context->hRC );
803 }
804 else
805 {
806 if (!context->visual->device_context) {
807 context->visual->device_context = GetDC( window->hWnd );
808
809 crDebug( "Render SPU: MakeCurrent made the DC: 0x%x", context->visual->device_context );
810
811 if ( !bSetupPixelFormat( context->visual->device_context, context->visual->visAttribs ) )
812 {
813 crError( "Render SPU: (MakeCurrent) Couldn't set up the device context! Yikes!" );
814 }
815 }
816
817 if (!context->hRC) {
818 context->hRC = render_spu.ws.wglCreateContext( context->visual->device_context );
819 if (!context->hRC)
820 {
821 crError( "Render SPU: (MakeCurrent) Couldn't create the context for the window (error 0x%x)", GetLastError() );
822 }
823 }
824
825 render_spu.ws.wglMakeCurrent( window->device_context, context->hRC );
826 }
827
828 }
829 else {
830 render_spu.ws.wglMakeCurrent( 0, 0 );
831 }
832}
833
834void renderspu_SystemWindowSize( WindowInfo *window, GLint w, GLint h )
835{
836 int winprop;
837 CRASSERT(window);
838 CRASSERT(window->visual);
839 if ( render_spu.fullscreen )
840 winprop = SWP_SHOWWINDOW | SWP_NOSENDCHANGING |
841 SWP_NOREDRAW | SWP_NOACTIVATE;
842 else
843 winprop = SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_NOZORDER; //SWP_SHOWWINDOW;
844
845 /*SetWindowRgn(window->hWnd, NULL, false);*/
846
847 if (!SetWindowPos( window->hWnd, HWND_TOP,
848 window->x, window->y, w, h, winprop )) {
849 crWarning("!!!FAILED!!! Render SPU: SetWindowPos (%x, %d, %d, %d, %d)", window->hWnd, window->x, window->y, w, h);
850 } else {
851 crDebug("Render SPU: SetWindowSize (%x, %d, %d, %d, %d)", window->hWnd, window->x, window->y, w, h);
852 }
853 /* save the new size */
854 window->width = w;
855 window->height = h;
856}
857
858
859void renderspu_SystemGetWindowGeometry( WindowInfo *window, GLint *x, GLint *y, GLint *w, GLint *h )
860{
861 RECT rect;
862
863 CRASSERT(window);
864 CRASSERT(window->visual);
865
866 GetClientRect( window->hWnd, &rect );
867 *x = rect.left;
868 *y = rect.top;
869 *w = rect.right - rect.left;
870 *h = rect.bottom - rect.top;
871}
872
873
874void renderspu_SystemGetMaxWindowSize( WindowInfo *window, GLint *w, GLint *h )
875{
876 /* XXX fix this */
877 (void) window;
878 *w = 1600;
879 *h = 1200;
880}
881
882
883void renderspu_SystemWindowPosition( WindowInfo *window, GLint x, GLint y )
884{
885 int winprop;
886 CRASSERT(window);
887 CRASSERT(window->visual);
888 if ( render_spu.fullscreen )
889 winprop = SWP_SHOWWINDOW | SWP_NOSENDCHANGING |
890 SWP_NOREDRAW | SWP_NOACTIVATE;
891 else
892 winprop = SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_NOZORDER; //SWP_SHOWWINDOW;
893
894 /*SetWindowRgn(window->visual->hWnd, NULL, false);*/
895
896 if (!SetWindowPos( window->hWnd, HWND_TOP,
897 x, y, window->width, window->height, winprop )) {
898 crWarning("!!!FAILED!!! Render SPU: SetWindowPos (%x, %d, %d, %d, %d)", window->hWnd, x, y, window->width, window->height);
899 } else {
900 crDebug("Render SPU: SetWindowPos (%x, %d, %d, %d, %d)", window->hWnd,
901 x, y, window->width, window->height);
902 }
903}
904
905void renderspu_SystemWindowVisibleRegion(WindowInfo *window, GLint cRects, GLint* pRects)
906{
907 GLint i;
908 HRGN hRgn, hTmpRgn;
909
910 CRASSERT(window);
911 CRASSERT(window->visual);
912
913 hRgn = CreateRectRgn(0, 0, 0, 0);
914
915 for (i=0; i<cRects; i++)
916 {
917 hTmpRgn = CreateRectRgn(pRects[4*i], pRects[4*i+1], pRects[4*i+2], pRects[4*i+3]);
918 CombineRgn(hRgn, hRgn, hTmpRgn, RGN_OR);
919 DeleteObject(hTmpRgn);
920 }
921
922 SetWindowRgn(window->hWnd, hRgn, true);
923 crDebug("Render SPU: SetWindowRgn (%x, cRects=%i)", window->hWnd, cRects);
924}
925
926static void renderspuHandleWindowMessages( HWND hWnd )
927{
928 MSG msg;
929 while ( PeekMessage( &msg, hWnd, 0, 0xffffffff, PM_REMOVE ) )
930 {
931 TranslateMessage( &msg );
932 DispatchMessage( &msg );
933 }
934
935 //BringWindowToTop( hWnd );
936}
937
938void renderspu_SystemSwapBuffers( WindowInfo *w, GLint flags )
939{
940 int return_value;
941
942 /* peek at the windows message queue */
943 renderspuHandleWindowMessages( w->hWnd );
944
945 /* render_to_app_window:
946 * w->nativeWindow will only be non-zero if the
947 * render_spu.render_to_app_window option is true and
948 * MakeCurrent() recorded the nativeWindow handle in the WindowInfo
949 * structure.
950 */
951 if (render_spu.render_to_app_window && w->nativeWindow) {
952 return_value = render_spu.ws.wglSwapBuffers( w->nativeWindow );
953 } else {
954 /*
955 HRGN hRgn1, hRgn2, hRgn3;
956 HWND hWndParent;
957 LONG ws;
958
959 hRgn1 = CreateRectRgn(0, 0, w->width, w->height);
960 hRgn2 = CreateRectRgn(50, 50, 100, 100);
961 hRgn3 = CreateRectRgn(0, 0, 0, 0);
962 CombineRgn(hRgn3, hRgn1, hRgn2, RGN_DIFF);
963 SetWindowRgn(w->visual->hWnd, hRgn3, true);
964 DeleteObject(hRgn1);
965 DeleteObject(hRgn2);
966
967 hWndParent = GetParent(w->visual->hWnd);
968 ws = GetWindowLong(hWndParent, GWL_STYLE);
969 ws &= ~WS_CLIPCHILDREN;
970 SetWindowLong(hWndParent, GWL_STYLE, ws);
971
972 RECT rcClip;
973
974 rcClip.left = 50;
975 rcClip.top = 50;
976 rcClip.right = 100;
977 rcClip.bottom = 100;
978 ValidateRect(w->visual->hWnd, &rcClip);
979
980 return_value = GetClipBox(w->visual->device_context, &rcClip);
981 crDebug("GetClipBox returned %d (NR=%d,SR=%d,CR=%d,ERR=%d)",
982 return_value, NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR);
983
984 crDebug("rcClip(%d, %d, %d, %d)", rcClip.left, rcClip.top, rcClip.right, rcClip.bottom);
985
986 return_value = ExcludeClipRect(w->visual->device_context, 50, 50, 100, 100);
987 crDebug("ExcludeClipRect returned %d (NR=%d,SR=%d,CR=%d,ERR=%d)",
988 return_value, NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR);
989
990 return_value = GetClipBox(w->visual->device_context, &rcClip);
991 crDebug("GetClipBox returned %d (NR=%d,SR=%d,CR=%d,ERR=%d)",
992 return_value, NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR);
993 crDebug("rcClip(%d, %d, %d, %d)", rcClip.left, rcClip.top, rcClip.right, rcClip.bottom);
994 */
995 return_value = render_spu.ws.wglSwapBuffers( w->device_context );
996 }
997 if (!return_value)
998 {
999 /* GOD DAMN IT. The latest versions of the NVIDIA drivers
1000 * return failure from wglSwapBuffers, but it works just fine.
1001 * WHAT THE HELL?! */
1002
1003 crWarning( "wglSwapBuffers failed: return value of %d!", return_value);
1004 }
1005}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette