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 #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
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
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
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
00180
00181
00182 case WM_MOUSEWHEEL:
00183 {
00184 win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
00185 break;
00186 }
00187
00188
00189
00190
00191
00192
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
00239
00240
00241
00242
00243
00244
00245 }
00246
00247 return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
00248 }
00249
00250
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
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
00309 mEGL_Display = eglGetDisplay(GetDC(mHWND));
00310 if ( mEGL_Display == EGL_NO_DISPLAY )
00311 {
00312 return false;
00313 }
00314
00315
00316 EGLint maj_version=0, min_version=0;
00317 if ( !eglInitialize(mEGL_Display, &maj_version, &min_version) )
00318 {
00319 return false;
00320 }
00321
00322
00323 EGLint num_configs = 0;
00324 if ( !eglGetConfigs(mEGL_Display, NULL, 0, &num_configs) )
00325 {
00326 return false;
00327 }
00328
00329
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
00351 EGLConfig selected_config = configurations[0];
00352
00353
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
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
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
00377 mWinMap[mHWND] = this;
00378
00379
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
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
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
00450
00451
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
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
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;
00582 }
00583
00584 void vlEGL::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
00585 {
00586
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
00629
00630
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
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
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