Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlEGL/EGLWindow.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlEGL/EGLWindow.hpp>
00033 #include <vlCore/Log.hpp>
00034 #include <vlCore/Say.hpp>
00035 #include <vlCore/Time.hpp>
00036 #include <shellapi.h>
00037 
00038 using namespace vl;
00039 using namespace vlEGL;
00040 
00041 //-----------------------------------------------------------------------------
00042 namespace
00043 {
00044   #if 0
00045     // used for debugging purposes
00046     void win32PrintError(LPTSTR lpszFunction) 
00047     { 
00048         TCHAR szBuf[80]; 
00049         LPVOID lpMsgBuf;
00050         DWORD dw = GetLastError(); 
00051 
00052         FormatMessage(
00053             FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00054             FORMAT_MESSAGE_FROM_SYSTEM,
00055             NULL,
00056             dw,
00057             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00058             (LPTSTR) &lpMsgBuf,
00059             0, NULL );
00060 
00061         wsprintf(szBuf, 
00062             L"%s failed with error %d: %s", 
00063             lpszFunction, dw, lpMsgBuf); 
00064      
00065         MessageBox(NULL, szBuf, L"Visualization Library Error", MB_OK); 
00066 
00067         LocalFree(lpMsgBuf);
00068     }
00069   #endif
00070 
00071   bool registerClass()
00072   {
00073     static bool class_already_registered = false;
00074     if (!class_already_registered)
00075     {
00076       WNDCLASS wc;
00077       memset(&wc, 0, sizeof(wc));
00078       /* only register the window class once. */
00079       wc.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
00080       wc.lpfnWndProc   = (WNDPROC)EGLWindow::WindowProc;
00081       wc.cbClsExtra    = 0;
00082       wc.cbWndExtra    = 0;
00083       wc.hInstance     = GetModuleHandle(NULL);
00084       wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
00085       wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
00086       wc.hbrBackground = NULL;
00087       wc.lpszMenuName  = NULL;
00088       wc.lpszClassName = EGLWindow::EGLWindowClassName;
00089 
00090       if (!RegisterClass(&wc))
00091         MessageBox(NULL, L"Class registration failed.", L"Visualization Library Error", MB_OK);
00092       else
00093         class_already_registered = true;
00094     }
00095     return class_already_registered;
00096   }
00097 }
00098 //-----------------------------------------------------------------------------
00099 const wchar_t* EGLWindow::EGLWindowClassName = L"VisualizationLibraryWindowClass";
00100 //-----------------------------------------------------------------------------
00101 std::map< HWND, EGLWindow* > EGLWindow::mWinMap;
00102 //-----------------------------------------------------------------------------
00103 LONG WINAPI EGLWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00104 { 
00105   EGLWindow* win = EGLWindow::getWindow(hWnd);
00106   if (!win)
00107     return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00108 
00109   switch(uMsg) 
00110   {
00111     case WM_PAINT:
00112     {
00113       // handle event and then dispatch: solves MessageBox dialog problem.
00114       LONG val = (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00115       if (win->eglContext() && win->eglSurface() && win->hwnd())
00116         win->dispatchRunEvent();
00117       return val;
00118     }
00119 
00120     case WM_SIZE:
00121     {
00122       win->framebuffer()->setWidth( LOWORD(lParam) );
00123       win->framebuffer()->setHeight( HIWORD(lParam) );
00124       win->dispatchResizeEvent( LOWORD(lParam), HIWORD(lParam) );
00125       break;
00126     }
00127 
00128     case WM_MOUSEMOVE:
00129     {
00130       POINTS pt = MAKEPOINTS(lParam);
00131       win->dispatchMouseMoveEvent( pt.x, pt.y );
00132       break;
00133     }
00134 
00135     case WM_LBUTTONDBLCLK:
00136     case WM_LBUTTONDOWN:
00137     case WM_MBUTTONDBLCLK:
00138     case WM_MBUTTONDOWN:
00139     case WM_RBUTTONDBLCLK:
00140     case WM_RBUTTONDOWN:
00141     {
00142       win->mMouseDownCount++;
00143       if (win->mMouseDownCount == 1)
00144         SetCapture(win->hwnd());
00145       EMouseButton button = UnknownButton;
00146       if (uMsg == WM_LBUTTONDBLCLK || uMsg == WM_LBUTTONDOWN)
00147         button = LeftButton;
00148       else if (uMsg == WM_MBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN)
00149         button = MiddleButton;
00150       else if (uMsg == WM_RBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN)
00151         button = RightButton;
00152       POINTS pt = MAKEPOINTS(lParam);
00153       win->dispatchMouseDownEvent( button, pt.x, pt.y );
00154       break;
00155     }
00156 
00157     case WM_LBUTTONUP:
00158     case WM_RBUTTONUP:
00159     case WM_MBUTTONUP:
00160     {
00161       win->mMouseDownCount--;
00162       if (win->mMouseDownCount <= 0)
00163       {
00164         ReleaseCapture();
00165         win->mMouseDownCount = 0;
00166       }
00167       EMouseButton button = UnknownButton;
00168       if (uMsg == WM_LBUTTONUP)
00169         button = LeftButton;
00170       else if (uMsg == WM_MBUTTONUP)
00171         button = MiddleButton;
00172       else if (uMsg == WM_RBUTTONUP)
00173         button = RightButton;
00174       POINTS pt = MAKEPOINTS(lParam);
00175       win->dispatchMouseUpEvent( button, pt.x, pt.y );
00176       break;
00177     }
00178 
00179     // If you get a compilation error here:
00180     // 1 - you didn't define _WIN32_WINNT as 0x0400 or above.
00181     // 2 - you are trying to compile VL with a VERY old (unsupported) Visual Studio / Platform SDK.
00182     case WM_MOUSEWHEEL:
00183     {
00184       win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
00185       break;
00186     }
00187 
00188     /*case WM_CLOSE:
00189     {
00190       win->dispatchDestroyEvent();
00191       win->destroyEGLGLWindow();
00192       break;
00193     }*/
00194 
00195     case WM_DESTROY:
00196     {
00197       EGLWindow::mWinMap.erase(hWnd);
00198       win->dispatchDestroyEvent();
00199       win->destroyEGLGLWindow();
00200       break;
00201     }
00202 
00203     case WM_KEYDOWN:
00204     {
00205       unsigned short unicode_out = 0;
00206       vl::EKey       key_out     = Key_None;
00207       translateKeyEvent(wParam, lParam, unicode_out, key_out);
00208       win->dispatchKeyPressEvent(unicode_out, key_out);
00209       break;
00210     }
00211 
00212     case WM_KEYUP:
00213     {
00214       unsigned short unicode_out = 0;
00215       vl::EKey       key_out     = Key_None;
00216       translateKeyEvent(wParam, lParam, unicode_out, key_out);
00217       win->dispatchKeyReleaseEvent(unicode_out, key_out);
00218       break;
00219     }
00220 
00221     case WM_DROPFILES:
00222     {
00223       HDROP hDrop = (HDROP)wParam;
00224       int count = DragQueryFile(hDrop, 0xFFFFFFFF, 0, 0);
00225       const int char_count = 1024;
00226       std::vector<String> files;
00227       for(int i=0; i<count; ++i)
00228       {
00229         wchar_t file_path[char_count];
00230         memset(file_path, 0, char_count);
00231         DragQueryFile(hDrop,i,file_path,char_count);
00232         files.push_back(file_path);
00233       }
00234       win->dispatchFileDroppedEvent(files);
00235       break;
00236     }
00237 
00238     // WM_SYSKEYDOWN
00239     // WM_SYSKEYUP
00240     // WM_GETICON
00241     // WM_SETCURSOR
00242     // WM_SETICON
00243     // WM_CAPTURECHANGED
00244     // WM_MOUSEFIRST 
00245   }
00246 
00247   return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam); 
00248 }
00249 //-----------------------------------------------------------------------------
00250 // EGLWindow
00251 //-----------------------------------------------------------------------------
00252 EGLWindow::EGLWindow()
00253 {
00254   mEGL_Display = 0;
00255   mEGL_Context = 0;
00256   mEGL_Surface = 0;
00257 
00258   mHWND  = NULL;
00259   mMouseDownCount = 0;
00260 
00261   mStyle   = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
00262   mExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
00263   mWindowClassName = EGLWindowClassName;
00264 }
00265 //-----------------------------------------------------------------------------
00266 EGLWindow::~EGLWindow()
00267 {
00268   destroyEGLGLWindow();
00269 }
00270 //-----------------------------------------------------------------------------
00271 bool EGLWindow::initEGLWindow(HWND parent, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
00272 {
00273   destroyEGLGLWindow();
00274 
00275   if (!registerClass())
00276     return false;
00277 
00278   unsigned style = mStyle & ~(WS_CHILD|WS_OVERLAPPEDWINDOW);;
00279   style |= parent?WS_CHILD:WS_OVERLAPPEDWINDOW;
00280 
00281   mHWND = CreateWindowEx(
00282     mExStyle,
00283     mWindowClassName,
00284     L"Visualization Library's EGLWindow",
00285     style,
00286     x, y, width, height, 
00287     parent, NULL, GetModuleHandle(NULL), NULL);
00288 
00289   setWindowTitle(title);
00290 
00291   // EGL initialization
00292 
00293   EGLint client_version[] = { EGL_CONTEXT_CLIENT_VERSION, fmt.contextClientVersion(), EGL_NONE };
00294 
00295   EGLint attrib_list[] =
00296   {
00297     EGL_RED_SIZE,       fmt.rgbaBits().r(),
00298     EGL_GREEN_SIZE,     fmt.rgbaBits().g(),
00299     EGL_BLUE_SIZE,      fmt.rgbaBits().b(),
00300     EGL_ALPHA_SIZE,     fmt.rgbaBits().a()      ? fmt.rgbaBits().a()      : EGL_DONT_CARE,
00301     EGL_DEPTH_SIZE,     fmt.depthBufferBits()   ? fmt.depthBufferBits()   : EGL_DONT_CARE,
00302     EGL_STENCIL_SIZE,   fmt.stencilBufferBits() ? fmt.stencilBufferBits() : EGL_DONT_CARE,
00303     EGL_SAMPLE_BUFFERS, fmt.multisample() ? 1 : 0,
00304     EGL_SAMPLES,        fmt.multisample() ? fmt.multisampleSamples() : EGL_DONT_CARE,
00305     EGL_NONE
00306   };
00307 
00308   // Get Display
00309   mEGL_Display = eglGetDisplay(GetDC(mHWND));
00310   if ( mEGL_Display == EGL_NO_DISPLAY )
00311   {
00312     return false;
00313   }
00314 
00315   // Initialize EGL
00316   EGLint maj_version=0, min_version=0;
00317   if ( !eglInitialize(mEGL_Display, &maj_version, &min_version) )
00318   {
00319     return false;
00320   }
00321 
00322   // Get configs
00323   EGLint num_configs = 0;
00324   if ( !eglGetConfigs(mEGL_Display, NULL, 0, &num_configs) )
00325   {
00326     return false;
00327   }
00328 
00329   // Choose config
00330   EGLConfig configurations[32] = {0};
00331   if ( !eglChooseConfig(mEGL_Display, attrib_list, configurations, 32, &num_configs) )
00332   {
00333     return false;
00334   }
00335 
00336 #if 0
00337   for(int i=0; i<num_configs; ++i)
00338   {
00339     printf("EGLConfig #%d:\n", i);
00340     EGLint value = 0;
00341     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_RED_SIZE, &value);     printf("EGL_RED_SIZE = %d\n", value);
00342     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_GREEN_SIZE, &value);   printf("EGL_GREEN_SIZE = %d\n", value);
00343     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_BLUE_SIZE, &value);    printf("EGL_BLUE_SIZE = %d\n", value);
00344     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_ALPHA_SIZE, &value);   printf("EGL_ALPHA_SIZE = %d\n", value);
00345     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_DEPTH_SIZE, &value);   printf("EGL_DEPTH_SIZE = %d\n", value);
00346     eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_STENCIL_SIZE, &value); printf("EGL_STENCIL_SIZE = %d\n", value);
00347   }
00348 #endif
00349 
00350   // Sorting explained here: http://www.khronos.org/opengles/documentation/opengles1_0/html/eglChooseConfig.html
00351   EGLConfig selected_config = configurations[0];
00352 
00353   // Create a surface
00354   mEGL_Surface = eglCreateWindowSurface(mEGL_Display, selected_config, (EGLNativeWindowType)mHWND, NULL);
00355   if ( mEGL_Surface == EGL_NO_SURFACE )
00356   {
00357     return false;
00358   }
00359 
00360   // Create a GL context
00361   mEGL_Context = eglCreateContext(mEGL_Display, selected_config, EGL_NO_CONTEXT, client_version );
00362   if ( mEGL_Context == EGL_NO_CONTEXT )
00363   {
00364     return false;
00365   }   
00366 
00367   // Make the context current
00368   if ( !eglMakeCurrent(mEGL_Display, mEGL_Surface, mEGL_Surface, mEGL_Context) )
00369   {
00370     return false;
00371   }
00372 
00373   if ( !initGLContext() )
00374     return false;
00375 
00376   // register window
00377   mWinMap[mHWND] = this;
00378 
00379   // vSync
00380   eglSwapInterval(mEGL_Display, fmt.vSync() ? 1 : 0);
00381 
00382   dispatchInitEvent();
00383 
00384   setPosition(x, y);
00385 
00386   setSize(width, height);
00387 
00388   return true;
00389 }
00390 //-----------------------------------------------------------------------------
00391 void EGLWindow::swapBuffers()
00392 {
00393   // Due to the fact that eglSwapBuffers() can call WM_DESTROY mEGL_Surface might become NULL after calling it.
00394   if ( !eglSwapBuffers(mEGL_Display, mEGL_Surface) && mEGL_Surface )
00395   {
00396     Log::error("EGLWindow::swapBuffers() failed!\n");
00397   }
00398 }
00399 //-----------------------------------------------------------------------------
00400 void EGLWindow::makeCurrent()
00401 {
00402   if ( !eglMakeCurrent(mEGL_Display, mEGL_Surface, mEGL_Surface, mEGL_Context) )
00403   {
00404     Log::error("EGLWindow::makeCurrent() failed!\n");
00405   }
00406 }
00407 //-----------------------------------------------------------------------------
00408 void EGLWindow::update()
00409 {
00410   if (mHWND)
00411     PostMessage(hwnd(), WM_PAINT, 0, 0);
00412 }
00413 //-----------------------------------------------------------------------------
00414 void EGLWindow::quitApplication()
00415 {
00416   PostQuitMessage(0);
00417 }
00418 //-----------------------------------------------------------------------------
00419 void EGLWindow::setMouseVisible(bool visible)
00420 {
00421   mMouseVisible = visible;
00422   if (visible)
00423     while(ShowCursor(TRUE ) <  0) {}
00424   else
00425     while(ShowCursor(FALSE) >= 0) {}
00426 }
00427 //-----------------------------------------------------------------------------
00428 void EGLWindow::setPosition(int x, int y)
00429 {
00430   if (hwnd())
00431       SetWindowPos(hwnd(), 0, x, y, 0, 0, SWP_NOSIZE );
00432 }
00433 //-----------------------------------------------------------------------------
00434 void EGLWindow::setSize(int w, int h)
00435 {
00436   if (hwnd())
00437   {
00438     RECT windowRect = { 0, 0, w, h };
00439     AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
00440     // computes the actual window based on the client dimensions
00441     int cx = windowRect.right  - windowRect.left;
00442     int cy = windowRect.bottom - windowRect.top;
00443     SetWindowPos(hwnd(), 0, 0, 0, cx, cy, SWP_NOMOVE );
00444   }
00445 }
00446 //-----------------------------------------------------------------------------
00447 void EGLWindow::setWindowSize(int w, int h)
00448 {
00449   // Sset by WM_SIZE event handler:
00450   // mFramebuffer->setWidth(w);
00451   // mFramebuffer->setHeight(h);
00452 
00453     SetWindowPos(hwnd(), 0, 0, 0, w, h, SWP_NOMOVE);
00454 }
00455 //-----------------------------------------------------------------------------
00456 vl::ivec2 EGLWindow::position() const
00457 {
00458   RECT r = {0,0,0,0};
00459   if (hwnd())
00460       GetWindowRect(hwnd(), &r);
00461   return vl::ivec2(r.left,r.top);
00462 }
00463 //-----------------------------------------------------------------------------
00464 vl::ivec2 EGLWindow::windowSize() const
00465 {
00466   RECT r = {0,0,0,0};
00467   if (hwnd())
00468       GetWindowRect(hwnd(), &r);
00469   return vl::ivec2(r.right - r.left, r.bottom - r.top);
00470 }
00471 //-----------------------------------------------------------------------------
00472 vl::ivec2 EGLWindow::size() const
00473 {
00474   RECT r = {0,0,0,0};
00475   if (hwnd())
00476       GetClientRect(hwnd(), &r);
00477   return vl::ivec2(r.right - r.left, r.bottom - r.top);
00478 }
00479 //-----------------------------------------------------------------------------
00480 void EGLWindow::setWindowTitle(const String& title)
00481 {
00482   if (hwnd())
00483     SetWindowText(hwnd(), (wchar_t*)title.ptr());
00484 }
00485 //-----------------------------------------------------------------------------
00486 void EGLWindow::show()
00487 {
00488   if (hwnd())
00489     ShowWindow(hwnd(), SW_SHOW);
00490 }
00491 //-----------------------------------------------------------------------------
00492 void EGLWindow::hide()
00493 {
00494   if (hwnd())
00495     ShowWindow(hwnd(), SW_HIDE);
00496 }
00497 //-----------------------------------------------------------------------------
00498 void EGLWindow::getFocus()
00499 {
00500   if (hwnd())
00501     SetFocus(hwnd());
00502 }
00503 //-----------------------------------------------------------------------------
00504 void EGLWindow::setMousePosition(int x, int y)
00505 {
00506   if (hwnd())
00507   {
00508     POINT pt = {x, y};
00509     ClientToScreen( hwnd(), &pt );
00510     SetCursorPos(pt.x, pt.y);
00511   }
00512 }
00513 //-----------------------------------------------------------------------------
00514 EGLWindow* EGLWindow::getWindow(HWND hWnd)
00515 {
00516   std::map< HWND, EGLWindow* >::const_iterator it = mWinMap.find(hWnd);
00517   if (it != mWinMap.end())
00518     return it->second;
00519   else 
00520     return NULL;
00521 }
00522 //-----------------------------------------------------------------------------
00523 void EGLWindow::destroyEGLGLWindow()
00524 {
00525   if (hwnd())
00526   {
00527     bool destroy_win = mWinMap.find(mHWND) != mWinMap.end();
00528 
00529     // WM_DESTROY must be dispatched while the OpenGL context is still available!
00530     if (destroy_win)
00531     {
00532       DestroyWindow(mHWND);
00533       mHWND = NULL;
00534     }
00535 
00536     eglDestroyContext ( eglDisplay(), eglContext() ); mEGL_Context = NULL;
00537     eglDestroySurface ( eglDisplay(), eglSurface() ); mEGL_Surface = NULL;
00538     eglTerminate      ( eglDisplay() );               mEGL_Display = NULL;
00539   }
00540 }
00541 //-----------------------------------------------------------------------------
00542 void vlEGL::dispatchUpdate()
00543 {
00544   // iterate over all opengl contexts
00545   std::map< HWND, EGLWindow* > wins = EGLWindow::winMap();
00546   for( std::map< HWND, EGLWindow* >::iterator it = wins.begin();
00547        it != wins.end(); 
00548        ++it )
00549   {
00550     EGLWindow* win = it->second;
00551     if ( win->continuousUpdate() )
00552       win->update();
00553     else
00554       Sleep(10);
00555   }
00556 }
00557 //-----------------------------------------------------------------------------
00558 void vlEGL::peekMessage(MSG& msg)
00559 {
00560   if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
00561   {
00562     if (msg.message != WM_QUIT)
00563     {
00564       TranslateMessage(&msg);
00565       DispatchMessage(&msg);
00566     }
00567   }
00568   else
00569     dispatchUpdate();
00570 }
00571 //-----------------------------------------------------------------------------
00572 int vlEGL::messageLoop()
00573 {
00574   while(!EGLWindow::winMap().empty())
00575   {
00576     MSG msg = {0,0,0,0,0,0,0};
00577     peekMessage(msg);
00578     if (msg.message == WM_QUIT)
00579       return (int)msg.wParam;
00580   }
00581   return 0; /* never reached */
00582 }
00583 //-----------------------------------------------------------------------------
00584 void vlEGL::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
00585 {
00586   // translate non unicode characters
00587   key_out     = Key_None;
00588   unicode_out = 0;
00589 
00590   switch(wParam)
00591   {
00592     case VK_CLEAR:    key_out = Key_Clear; break;
00593     case VK_CONTROL:  key_out = Key_Ctrl; break;
00594     case VK_LCONTROL: key_out = Key_LeftCtrl; break;
00595     case VK_RCONTROL: key_out = Key_RightCtrl; break;
00596     case VK_MENU:     key_out = Key_Alt; break;
00597     case VK_LMENU:    key_out = Key_LeftAlt; break;
00598     case VK_RMENU:    key_out = Key_RightAlt; break;
00599     case VK_SHIFT:    key_out = Key_Shift; break;
00600     case VK_LSHIFT:   key_out = Key_LeftShift; break;
00601     case VK_RSHIFT:   key_out = Key_RightShift; break;
00602     case VK_INSERT:   key_out = Key_Insert; break;
00603     case VK_DELETE:   key_out = Key_Delete; break;
00604     case VK_HOME:     key_out = Key_Home; break;
00605     case VK_END:      key_out = Key_End; break;
00606     case VK_PRINT:    key_out = Key_Print; break;
00607     case VK_PAUSE:    key_out = Key_Pause; break;
00608     case VK_PRIOR:    key_out = Key_PageUp; break;
00609     case VK_NEXT:     key_out = Key_PageDown; break;
00610     case VK_LEFT:     key_out = Key_Left; break;
00611     case VK_RIGHT:    key_out = Key_Right; break;
00612     case VK_UP:       key_out = Key_Up; break;
00613     case VK_DOWN:     key_out = Key_Down; break;
00614     case VK_F1:       key_out = Key_F1; break;
00615     case VK_F2:       key_out = Key_F2; break;
00616     case VK_F3:       key_out = Key_F3; break;
00617     case VK_F4:       key_out = Key_F4; break;
00618     case VK_F5:       key_out = Key_F5; break;
00619     case VK_F6:       key_out = Key_F6; break;
00620     case VK_F7:       key_out = Key_F7; break;
00621     case VK_F8:       key_out = Key_F8; break;
00622     case VK_F9:       key_out = Key_F9; break;
00623     case VK_F10:      key_out = Key_F10; break;
00624     case VK_F11:      key_out = Key_F11; break;
00625     case VK_F12:      key_out = Key_F12; break;
00626 
00627     /*
00628      * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
00629      * 0x40 : is unassigned
00630      * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
00631      */
00632 
00633     case L'0': key_out = Key_0; break;
00634     case L'1': key_out = Key_1; break;
00635     case L'2': key_out = Key_2; break;
00636     case L'3': key_out = Key_3; break;
00637     case L'4': key_out = Key_4; break;
00638     case L'5': key_out = Key_5; break;
00639     case L'6': key_out = Key_6; break;
00640     case L'7': key_out = Key_7; break;
00641     case L'8': key_out = Key_8; break;
00642     case L'9': key_out = Key_9; break;
00643 
00644     case L'A': key_out = Key_A; break;
00645     case L'B': key_out = Key_B; break;
00646     case L'C': key_out = Key_C; break;
00647     case L'D': key_out = Key_D; break;
00648     case L'E': key_out = Key_E; break;
00649     case L'F': key_out = Key_F; break;
00650     case L'G': key_out = Key_G; break;
00651     case L'H': key_out = Key_H; break;
00652     case L'I': key_out = Key_I; break;
00653     case L'J': key_out = Key_J; break;
00654     case L'K': key_out = Key_K; break;
00655     case L'L': key_out = Key_L; break;
00656     case L'M': key_out = Key_M; break;
00657     case L'N': key_out = Key_N; break;
00658     case L'O': key_out = Key_O; break;
00659     case L'P': key_out = Key_P; break;
00660     case L'Q': key_out = Key_Q; break;
00661     case L'R': key_out = Key_R; break;
00662     case L'S': key_out = Key_S; break;
00663     case L'T': key_out = Key_T; break;
00664     case L'U': key_out = Key_U; break;
00665     case L'V': key_out = Key_V; break;
00666     case L'W': key_out = Key_W; break;
00667     case L'X': key_out = Key_X; break;
00668     case L'Y': key_out = Key_Y; break;
00669     case L'Z': key_out = Key_Z; break;
00670   }
00671 
00672   // fill unicode
00673   BYTE mskeys[256];
00674   memset( mskeys, 0, sizeof(BYTE)*256 );
00675   WCHAR unicode[4] = { 0, 0 };
00676   if ( ToUnicode( (UINT)wParam, (UINT)((lParam >> 16) & 0xFF), mskeys, unicode, 4, 0 ) == 1 )
00677   {
00678     unicode_out = unicode[0];
00679 
00680     // fill key
00681     switch(unicode_out)
00682     {
00683       case L'0': key_out = Key_0; break;
00684       case L'1': key_out = Key_1; break;
00685       case L'2': key_out = Key_2; break;
00686       case L'3': key_out = Key_3; break;
00687       case L'4': key_out = Key_4; break;
00688       case L'5': key_out = Key_5; break;
00689       case L'6': key_out = Key_6; break;
00690       case L'7': key_out = Key_7; break;
00691       case L'8': key_out = Key_8; break;
00692       case L'9': key_out = Key_9; break;
00693 
00694       case L'A': key_out = Key_A; break;
00695       case L'B': key_out = Key_B; break;
00696       case L'C': key_out = Key_C; break;
00697       case L'D': key_out = Key_D; break;
00698       case L'E': key_out = Key_E; break;
00699       case L'F': key_out = Key_F; break;
00700       case L'G': key_out = Key_G; break;
00701       case L'H': key_out = Key_H; break;
00702       case L'I': key_out = Key_I; break;
00703       case L'J': key_out = Key_J; break;
00704       case L'K': key_out = Key_K; break;
00705       case L'L': key_out = Key_L; break;
00706       case L'M': key_out = Key_M; break;
00707       case L'N': key_out = Key_N; break;
00708       case L'O': key_out = Key_O; break;
00709       case L'P': key_out = Key_P; break;
00710       case L'Q': key_out = Key_Q; break;
00711       case L'R': key_out = Key_R; break;
00712       case L'S': key_out = Key_S; break;
00713       case L'T': key_out = Key_T; break;
00714       case L'U': key_out = Key_U; break;
00715       case L'V': key_out = Key_V; break;
00716       case L'W': key_out = Key_W; break;
00717       case L'X': key_out = Key_X; break;
00718       case L'Y': key_out = Key_Y; break;
00719       case L'Z': key_out = Key_Z; break;
00720 
00721       case L'a': key_out = Key_A; break;
00722       case L'b': key_out = Key_B; break;
00723       case L'c': key_out = Key_C; break;
00724       case L'd': key_out = Key_D; break;
00725       case L'e': key_out = Key_E; break;
00726       case L'f': key_out = Key_F; break;
00727       case L'g': key_out = Key_G; break;
00728       case L'h': key_out = Key_H; break;
00729       case L'i': key_out = Key_I; break;
00730       case L'j': key_out = Key_J; break;
00731       case L'k': key_out = Key_K; break;
00732       case L'l': key_out = Key_L; break;
00733       case L'm': key_out = Key_M; break;
00734       case L'n': key_out = Key_N; break;
00735       case L'o': key_out = Key_O; break;
00736       case L'p': key_out = Key_P; break;
00737       case L'q': key_out = Key_Q; break;
00738       case L'r': key_out = Key_R; break;
00739       case L's': key_out = Key_S; break;
00740       case L't': key_out = Key_T; break;
00741       case L'u': key_out = Key_U; break;
00742       case L'v': key_out = Key_V; break;
00743       case L'w': key_out = Key_W; break;
00744       case L'x': key_out = Key_X; break;
00745       case L'y': key_out = Key_Y; break;
00746       case L'z': key_out = Key_Z; break;
00747 
00748       case 13: key_out = Key_Return; break;
00749       case 8: key_out = Key_BackSpace; break;
00750       case 9: key_out = Key_Tab; break;
00751       case L' ': key_out = Key_Space; break;
00752 
00753       case 27: key_out = Key_Escape; break;
00754       case L'!': key_out = Key_Exclam; break;
00755       case L'"': key_out = Key_QuoteDbl; break;
00756       case L'#': key_out = Key_Hash; break;
00757       case L'$': key_out = Key_Dollar; break;
00758       case L'&': key_out = Key_Ampersand; break;
00759       case L'\'': key_out = Key_Quote; break;
00760       case L'(': key_out = Key_LeftParen; break;
00761       case L')': key_out = Key_RightParen; break;
00762       case L'*': key_out = Key_Asterisk; break;
00763       case L'+': key_out = Key_Plus; break;
00764       case L',': key_out = Key_Comma; break;
00765       case L'-': key_out = Key_Minus; break;
00766       case L'.': key_out = Key_Period; break;
00767       case L'\\': key_out = Key_Slash; break;
00768       case L':': key_out = Key_Colon; break;
00769       case L';': key_out = Key_Semicolon; break;
00770       case L'<': key_out = Key_Less; break;
00771       case L'=': key_out = Key_Equal; break;
00772       case L'>': key_out = Key_Greater; break;
00773       case L'?': key_out = Key_Question; break;
00774       case L'@': key_out = Key_At; break;
00775       case L'[': key_out = Key_LeftBracket; break;
00776       case L'/': key_out = Key_BackSlash; break;
00777       case L']': key_out = Key_RightBracket; break;
00778       case L'|': key_out = Key_Caret; break;
00779       case L'_': key_out = Key_Underscore; break;
00780       case L'`': key_out = Key_QuoteLeft; break;
00781     }
00782   }
00783 }
00784 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:34.
Permission is granted to use this page to write and publish articles regarding Visualization Library.