00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <vrj/vrjConfig.h>
00034
00035 #include <jccl/Config/ConfigElement.h>
00036
00037 #include <vpr/Util/Assert.h>
00038 #include <gadget/InputManager.h>
00039 #include <vrj/Util/Debug.h>
00040 #include <vrj/Kernel/Kernel.h>
00041 #include <vrj/Display/Display.h>
00042 #include <vrj/Display/DisplayManager.h>
00043 #include <vrj/Draw/OGL/GlWindow.h>
00044 #include <vrj/Draw/OGL/GlWindowWin32.h>
00045
00046 #define GL_WINDOW_WIN32_CLASSNAME "vrj::GlWindowWin32"
00047
00048 namespace vrj
00049 {
00050
00051 GlWindowWin32::GlWindowWin32()
00052 : mMatch(NULL), mWinHandle(NULL), mRenderContext(NULL),
00053 mDeviceContext(NULL)
00054 {
00055 }
00056 GlWindowWin32::~GlWindowWin32()
00057 {
00058 this->close();
00059 }
00060
00061
00062
00063
00064
00065 int GlWindowWin32::open()
00066 {
00067 if ( false == GlWindowWin32::registerWindowClass() )
00068 {
00069 return 0;
00070 }
00071
00072 if ( window_is_open )
00073 {
00074 return 1;
00075 }
00076
00077 HMODULE hMod = GetModuleHandle(NULL);
00078 DWORD style;
00079 int root_height;
00080
00081
00082 style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00083
00084
00085
00086 if ( border )
00087 {
00088 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL) << "attempting to give window a border"
00089 << std::endl << vprDEBUG_FLUSH;
00090 style |= WS_OVERLAPPEDWINDOW;
00091 }
00092
00093
00094 else
00095 {
00096 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL) << "attempting to make window borderless"
00097 << std::endl << vprDEBUG_FLUSH;
00098 style |= WS_OVERLAPPED | WS_POPUP | WS_VISIBLE;
00099 }
00100
00101 root_height = GetSystemMetrics(SM_CYSCREEN);
00102
00103
00104 mWinHandle = CreateWindow(GL_WINDOW_WIN32_CLASSNAME,
00105 GL_WINDOW_WIN32_CLASSNAME, style,
00106 origin_x, root_height - origin_y - window_height,
00107 window_width, window_height, NULL, NULL, hMod,
00108 NULL);
00109
00110
00111 if ( NULL == mWinHandle )
00112 {
00113 return 0;
00114 }
00115
00116
00117 SetWindowLong( mWinHandle, GWL_USERDATA, (LPARAM)this );
00118
00119
00120
00121 mDeviceContext = GetDC(mWinHandle);
00122 if ( false == setPixelFormat(mDeviceContext) )
00123 {
00124 return 0;
00125 }
00126
00127
00128 mRenderContext = wglCreateContext(mDeviceContext);
00129 vprASSERT(mRenderContext != NULL);
00130 wglMakeCurrent(mDeviceContext, mRenderContext);
00131
00132
00133 GlWindowWin32::addWindow(mWinHandle,this);
00134
00135
00136 ShowWindow(mWinHandle, SW_SHOW);
00137 UpdateWindow(mWinHandle);
00138 window_is_open = true;
00139
00140
00141
00142 if (true == mAreEventSource)
00143 {
00144 this->becomeEventWindowDevice();
00145 }
00146
00147 return 1;
00148 }
00149
00151 void GlWindowWin32::becomeEventWindowDevice()
00152 {
00153
00154 gadget::EventWindowWin32::m_hWnd = mWinHandle;
00155
00156
00157
00158
00159
00160
00161 gadget::Input* dev_ptr = dynamic_cast<gadget::Input*>(this);
00162 vprASSERT( dev_ptr != NULL );
00163
00164
00165
00166
00167 vrj::Kernel::instance()->getInputManager()->addDevice( dev_ptr );
00168 }
00169
00170 void GlWindowWin32::removeEventWindowDevice()
00171 {
00172 gadget::EventWindowWin32::m_hWnd = 0;
00173
00174 gadget::Input* dev_ptr = dynamic_cast<gadget::Input*>(this);
00175 vprASSERT( dev_ptr != NULL );
00176
00177
00178
00179
00180
00181
00182
00183 }
00184
00189 int GlWindowWin32::close()
00190 {
00191
00192
00193
00194
00195
00196
00197 if ( !window_is_open )
00198 {
00199 return false;
00200 }
00201
00202 if (mAreEventSource)
00203 {
00204 this->removeEventWindowDevice();
00205 }
00206
00207
00208 GlWindowWin32::removeWindow(mWinHandle);
00209
00210 window_is_open = false;
00211
00212
00213 return(1 == DestroyWindow(mWinHandle));
00214 }
00215
00220 bool GlWindowWin32::makeCurrent()
00221 {
00222 vprASSERT((mDeviceContext != NULL) && (mRenderContext != NULL));
00223 wglMakeCurrent(mDeviceContext, mRenderContext);
00224 return true;
00225 }
00226
00227
00228
00229 void GlWindowWin32::swapBuffers()
00230 {
00231 vprASSERT(mDeviceContext != NULL);
00232 SwapBuffers(mDeviceContext);
00233 }
00234
00235 void GlWindowWin32::checkEvents()
00236 {
00237 if (true == mAreEventSource)
00238 {
00240 gadget::EventWindowWin32::sample();
00241
00242
00243
00244 }
00245 else
00246 {
00247
00248 MSG win_message;
00249 while (PeekMessage( &win_message, NULL, 0, 0, PM_REMOVE ))
00250 {
00251
00252 if (win_message.message == WM_QUIT)
00253 {
00254 break;
00255 }
00256
00257 TranslateMessage( &win_message );
00258 DispatchMessage( &win_message );
00259 }
00260 }
00261 }
00262
00263 void GlWindowWin32::processEvent( UINT message, UINT wParam, LONG lParam )
00264 {
00265
00266 }
00267
00268 void GlWindowWin32::configWindow( vrj::Display* disp )
00269 {
00270 const char neg_one_STRING[] = "-1";
00271 vprASSERT( disp != NULL );
00272 vrj::GlWindow::configWindow( disp );
00273
00274
00275 jccl::ConfigElementPtr disp_sys_elt = DisplayManager::instance()->getDisplaySystemElement();
00276 jccl::ConfigElementPtr display_elt = disp->getConfigElement();
00277
00278 window_name = disp->getName();
00279 mPipe = disp->getPipe();
00280 vprASSERT( mPipe >= 0 );
00281
00282 mXDisplayName = disp_sys_elt->getProperty<std::string>("x11_pipes", mPipe);
00283 if (mXDisplayName == neg_one_STRING)
00284 {
00285 const std::string DISPLAY_str("DISPLAY");
00286 const char* d = getenv(DISPLAY_str.c_str());
00287 if (NULL != d)
00288 {
00289 mXDisplayName = std::string( d );
00290 }
00291 }
00292 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_VERB_LVL)
00293 << "glxWindow::config: display name is: "
00294 << mXDisplayName << std::endl << vprDEBUG_FLUSH;
00295
00296 bool was_i_a_keyboard = mAreEventSource;
00297 mAreEventSource = display_elt->getProperty<bool>("act_as_event_source");
00298
00299
00300 if (false == mAreEventSource && true == was_i_a_keyboard)
00301 {
00302 this->removeEventWindowDevice();
00303 }
00304
00305
00306 else if (true == mAreEventSource && false == was_i_a_keyboard)
00307 {
00308
00309 jccl::ConfigElementPtr event_win_chunk =
00310 display_elt->getProperty<jccl::ConfigElementPtr>("event_window_device");
00311
00312
00313
00314
00315 gadget::EventWindowWin32::config(event_win_chunk);
00316
00317
00318 gadget::EventWindowWin32::mWidth = GlWindowWin32::window_width;
00319 gadget::EventWindowWin32::mHeight = GlWindowWin32::window_height;
00320
00321 mWeOwnTheWindow = false;
00322
00323
00324
00325 if (window_is_open)
00326 {
00327 this->becomeEventWindowDevice();
00328 }
00329 }
00330 }
00331
00332
00333
00334 LRESULT GlWindowWin32::handleEvent( HWND hWnd, UINT message, WPARAM wParam,
00335 LPARAM lParam )
00336 {
00337 switch ( message )
00338 {
00339
00340 case WM_CREATE:
00341 vprASSERT(false);
00342
00343
00344 mDeviceContext = GetDC(hWnd);
00345 if ( false == setPixelFormat(mDeviceContext) )
00346 {
00347 return 0;
00348 }
00349
00350
00351 mRenderContext = wglCreateContext(mDeviceContext);
00352 wglMakeCurrent(mDeviceContext, mRenderContext);
00353 break;
00354
00355
00356 case WM_DESTROY:
00357
00358
00359 wglMakeCurrent(mDeviceContext, NULL);
00360 wglDeleteContext(mRenderContext);
00361
00362
00363
00364 PostQuitMessage(0);
00365 break;
00366
00367
00368 case WM_SIZE:
00369
00370
00371 sizeChanged(LOWORD(lParam), HIWORD(lParam));
00372 break;
00373
00374
00375
00376
00377 case WM_PAINT:
00378 {
00379 PAINTSTRUCT ps;
00380 BeginPaint(hWnd, &ps);
00381 EndPaint(hWnd, &ps);
00382 }
00383 break;
00384
00385 default:
00386 return(DefWindowProc(hWnd, message, wParam, lParam));
00387
00388 }
00389
00390 return(0L);
00391 }
00392
00393
00394 bool GlWindowWin32::setPixelFormat(HDC hDC)
00395 {
00396 int pixel_format;
00397 PIXELFORMATDESCRIPTOR pfd;
00398 mMatch = NULL;
00399
00400 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
00401 pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR));
00402 pfd.nVersion = 1;
00403
00404
00405 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
00406
00407 if ( mVrjDisplay->isStereoRequested() )
00408 {
00409 in_stereo = true;
00410 pfd.dwFlags |= PFD_STEREO;
00411 }
00412 else
00413 {
00414 in_stereo = false;
00415 }
00416
00417 int red_size(8), green_size(8), blue_size(8), alpha_size(8), db_size(32);
00418 jccl::ConfigElementPtr gl_fb_chunk = mVrjDisplay->getGlFrameBufferConfig();
00419
00420 if ( gl_fb_chunk.get() != NULL )
00421 {
00422 red_size = gl_fb_chunk->getProperty<int>("red_size");
00423 green_size = gl_fb_chunk->getProperty<int>("green_size");
00424 blue_size = gl_fb_chunk->getProperty<int>("blue_size");
00425 alpha_size = gl_fb_chunk->getProperty<int>("alpha_size");
00426 db_size = gl_fb_chunk->getProperty<int>("depth_buffer_size");
00427
00428 if ( red_size < 0 )
00429 {
00430 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL)
00431 << "WARNING: Red channel size was negative, set to: " << red_size
00432 << ". Setting to 1.\n" << vprDEBUG_FLUSH;
00433 red_size = 1;
00434 }
00435
00436 if ( green_size < 0 )
00437 {
00438 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL)
00439 << "WARNING: Green channel size was negative, set to: "
00440 << green_size << ". Setting to 1.\n" << vprDEBUG_FLUSH;
00441 green_size = 1;
00442 }
00443
00444 if ( blue_size < 0 )
00445 {
00446 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL)
00447 << "WARNING: Blue channel size was negative, set to: " << blue_size
00448 << ". Setting to 1.\n" << vprDEBUG_FLUSH;
00449 blue_size = 1;
00450 }
00451
00452 if ( alpha_size < 0 )
00453 {
00454 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL)
00455 << "WARNING: Alpha channel size was negative, set to: "
00456 << alpha_size << ". Setting to 1.\n" << vprDEBUG_FLUSH;
00457 alpha_size = 1;
00458 }
00459
00460 if ( db_size < 0 )
00461 {
00462 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL)
00463 << "WARNING: Depth buffer size was negative, set to: " << db_size
00464 << ". Setting to 1.\n" << vprDEBUG_FLUSH;
00465 db_size = 1;
00466 }
00467 }
00468
00469 vprDEBUG(vrjDBG_DISP_MGR, vprDBG_CONFIG_LVL)
00470 << "Frame buffer visual settings for " << mVrjDisplay->getName()
00471 << ": R:" << red_size << " G:" << green_size << " B:" << blue_size
00472 << " A:" << alpha_size << " DB:" << db_size << std::endl
00473 << vprDEBUG_FLUSH;
00474
00475 pfd.iPixelType = PFD_TYPE_RGBA;
00476 pfd.cColorBits = 32;
00477 pfd.cRedBits = red_size;
00478 pfd.cGreenBits = green_size;
00479 pfd.cBlueBits = blue_size;
00480 pfd.cAlphaBits = alpha_size;
00481 pfd.cDepthBits = db_size;
00482 pfd.cStencilBits = 0;
00483 pfd.cAccumBits = 0;
00484 pfd.cAuxBuffers = 0;
00485
00486
00487 pixel_format = ChoosePixelFormat(hDC, &pfd);
00488 if ( pixel_format > 0 )
00489 {
00490 mMatch = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR));
00491 DescribePixelFormat(hDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
00492 mMatch);
00493
00494
00495
00496
00497
00498 if ( mVrjDisplay->isStereoRequested() )
00499 {
00500 if ( !(mMatch->dwFlags & PFD_STEREO) )
00501 {
00502 free(mMatch);
00503 return NULL;
00504 }
00505 }
00506 }
00507
00508
00509 SetPixelFormat(hDC, pixel_format, &pfd);
00510 return true;
00511 }
00512
00513
00514 void GlWindowWin32::sizeChanged( long width, long height )
00515 {
00516 window_width = width;
00517 window_height = height;
00518
00519 if ( window_width == 0 )
00520 {
00521 window_width = 1;
00522 }
00523
00524 if ( window_height == 0 )
00525 {
00526 window_height = 1;
00527 }
00528
00529
00530 }
00531
00532
00533
00537 LRESULT CALLBACK GlWindowWin32::WndProc(HWND hWnd, UINT message,
00538 WPARAM wParam, LPARAM lParam)
00539 {
00540 GlWindowWin32* glWin = getGlWin(hWnd);
00541
00542 if ( glWin != NULL )
00543 {
00544 glWin->processEvent( message, wParam, lParam );
00545 return glWin->handleEvent(hWnd, message, wParam, lParam);
00546 }
00547 else
00548 {
00549 return DefWindowProc(hWnd, message, wParam, lParam);
00550 }
00551 }
00552
00556 bool GlWindowWin32::mWinRegisteredClass = false;
00557 WNDCLASS GlWindowWin32::mWinClass;
00558 std::map<HWND, GlWindowWin32*> GlWindowWin32::mGlWinMap;
00559
00560
00561 bool GlWindowWin32::registerWindowClass()
00562 {
00563 if ( mWinRegisteredClass )
00564 {
00565 return true;
00566 }
00567
00568 char lpszAppName[1024];
00569 GetModuleFileName(NULL,lpszAppName,sizeof(lpszAppName));
00570
00571 mWinRegisteredClass = true;
00572
00573 HINSTANCE hInstance = GetModuleHandle(NULL);
00574
00575
00576 mWinClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00577 mWinClass.lpfnWndProc = (WNDPROC)GlWindowWin32::WndProc;
00578 mWinClass.cbClsExtra = 0;
00579 mWinClass.cbWndExtra = 0;
00580 mWinClass.hInstance = hInstance;
00581 mWinClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);;
00582 mWinClass.hCursor = LoadCursor(NULL, IDC_ARROW);
00583
00584
00585 mWinClass.hbrBackground = NULL;
00586
00587 mWinClass.lpszMenuName = NULL;
00588 mWinClass.lpszClassName = GL_WINDOW_WIN32_CLASSNAME;
00589
00590
00591 if ( RegisterClass(&mWinClass) == 0 )
00592 {
00593 return false;
00594 }
00595 else
00596 {
00597 return true;
00598 }
00599 }
00600
00601
00602
00603
00604 void GlWindowWin32::addWindow(HWND handle, GlWindowWin32* glWin)
00605 {
00606 vprASSERT(glWin != NULL);
00607
00608 if ( mGlWinMap.find(handle) == mGlWinMap.end() )
00609 {
00610 mGlWinMap[handle] = glWin;
00611 }
00612
00613
00614 }
00615
00616 void GlWindowWin32::removeWindow(HWND handle)
00617 {
00618 mGlWinMap.erase(handle);
00619 }
00620
00621 GlWindowWin32* GlWindowWin32::getGlWin(HWND handle)
00622 {
00623 std::map<HWND, GlWindowWin32*>::iterator glWinIter;
00624
00625 glWinIter = mGlWinMap.find(handle);
00626 if ( glWinIter == mGlWinMap.end() )
00627 {
00628 return NULL;
00629 }
00630 else
00631 {
00632 return(*glWinIter).second;
00633 }
00634 }
00635
00636 }