VirtualBox

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

Last change on this file since 32043 was 27889, checked in by vboxsync, 15 years ago

crOpenGL: more code for multiscreen support

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