VirtualBox

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

Last change on this file since 18262 was 18256, checked in by vboxsync, 16 years ago

crOpenGL: typo

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