1 // Created by: Kirill Gavrilov
2 // Copyright (c) 2021 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Wasm_Window.hxx>
17 #include <Aspect_ScrollDelta.hxx>
18 #include <Aspect_WindowInputListener.hxx>
20 #if defined(__EMSCRIPTEN__)
21 #include <emscripten.h>
22 #include <emscripten/html5.h>
23 #include <emscripten/key_codes.h>
26 IMPLEMENT_STANDARD_RTTIEXT(Wasm_Window, Aspect_Window)
28 // =======================================================================
29 // function : Wasm_Window
31 // =======================================================================
32 Wasm_Window::Wasm_Window (const TCollection_AsciiString& theCanvasId,
33 const bool theToScaleBacking)
34 : myCanvasId (theCanvasId),
36 myDevicePixelRatio (1.0),
37 myToScaleBacking (theToScaleBacking),
40 #if defined(__EMSCRIPTEN__)
41 myDevicePixelRatio = emscripten_get_device_pixel_ratio();
42 emscripten_get_canvas_element_size (myCanvasId.ToCString(), &mySize.x(), &mySize.y());
45 myDevicePixelRatio = emscripten_get_device_pixel_ratio();
46 Graphic3d_Vec2d aCssSize;
47 emscripten_get_element_css_size (myCanvasId.ToCString(), &aCssSize.x(), &aCssSize.y());
48 Graphic3d_Vec2i aCanvasSize = Graphic3d_Vec2i (aCssSize * myDevicePixelRatio);
49 if (aCanvasSize != mySize)
52 emscripten_set_canvas_element_size (myCanvasId.ToCString(), aCanvasSize.x(), aCanvasSize.y());
53 emscripten_set_element_css_size (myCanvasId.ToCString(), aCssSize.x(), aCssSize.y());
59 // =======================================================================
60 // function : ~Wasm_Window
62 // =======================================================================
63 Wasm_Window::~Wasm_Window()
68 // =======================================================================
69 // function : DoResize
71 // =======================================================================
72 Aspect_TypeOfResize Wasm_Window::DoResize()
76 return Aspect_TOR_UNKNOWN;
79 #if defined(__EMSCRIPTEN__)
80 emscripten_get_canvas_element_size (myCanvasId.ToCString(), &mySize.x(), &mySize.y());
83 myDevicePixelRatio = emscripten_get_device_pixel_ratio();
84 Graphic3d_Vec2d aCssSize;
85 emscripten_get_element_css_size (myCanvasId.ToCString(), &aCssSize.x(), &aCssSize.y());
86 Graphic3d_Vec2i aCanvasSize = Graphic3d_Vec2i (aCssSize * myDevicePixelRatio);
87 if (aCanvasSize != mySize)
90 emscripten_set_canvas_element_size (myCanvasId.ToCString(), aCanvasSize.x(), aCanvasSize.y());
91 emscripten_set_element_css_size (myCanvasId.ToCString(), aCssSize.x(), aCssSize.y());
95 return Aspect_TOR_UNKNOWN;
98 // =======================================================================
101 // =======================================================================
102 Standard_Real Wasm_Window::Ratio() const
104 Graphic3d_Vec2i aCanvasSize = mySize;
107 #if defined(__EMSCRIPTEN__)
108 emscripten_get_canvas_element_size (myCanvasId.ToCString(), &aCanvasSize.x(), &aCanvasSize.y());
112 return (aCanvasSize.x() != 0 && aCanvasSize.y() != 0)
113 ? Standard_Real(aCanvasSize.x()) / Standard_Real(aCanvasSize.y())
117 // =======================================================================
118 // function : Position
120 // =======================================================================
121 void Wasm_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1,
122 Standard_Integer& theX2, Standard_Integer& theY2) const
133 #if defined(__EMSCRIPTEN__)
134 emscripten_get_canvas_element_size (myCanvasId.ToCString(), &theX2, &theY2);
138 // =======================================================================
141 // =======================================================================
142 void Wasm_Window::Size (Standard_Integer& theWidth,
143 Standard_Integer& theHeight) const
147 theWidth = mySize.x();
148 theHeight = mySize.y();
152 #if defined(__EMSCRIPTEN__)
153 emscripten_get_canvas_element_size (myCanvasId.ToCString(), &theWidth, &theHeight);
157 // =======================================================================
158 // function : SetSizeLogical
160 // =======================================================================
161 void Wasm_Window::SetSizeLogical (const Graphic3d_Vec2d& theSize)
163 mySize = Graphic3d_Vec2i (theSize * myDevicePixelRatio);
169 #if defined(__EMSCRIPTEN__)
170 emscripten_set_canvas_element_size (myCanvasId.ToCString(), mySize.x(), mySize.y());
171 emscripten_set_element_css_size (myCanvasId.ToCString(), theSize.x(), theSize.y());
175 // =======================================================================
176 // function : SetSizeBacking
178 // =======================================================================
179 void Wasm_Window::SetSizeBacking (const Graphic3d_Vec2i& theSize)
187 #if defined(__EMSCRIPTEN__)
188 Graphic3d_Vec2i aCanvasSize = mySize;
189 Graphic3d_Vec2d aCssSize = Graphic3d_Vec2d (mySize) / myDevicePixelRatio;
190 emscripten_set_canvas_element_size (myCanvasId.ToCString(), aCanvasSize.x(), aCanvasSize.y());
191 emscripten_set_element_css_size (myCanvasId.ToCString(), aCssSize.x(), aCssSize.y());
195 // =======================================================================
196 // function : InvalidateContent
198 // =======================================================================
199 void Wasm_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& )
204 // =======================================================================
205 // function : ProcessMessage
207 // =======================================================================
208 bool Wasm_Window::ProcessMessage (Aspect_WindowInputListener& theListener,
209 int theEventType, const void* theEvent)
211 #if defined(__EMSCRIPTEN__)
212 switch (theEventType)
214 case EMSCRIPTEN_EVENT_MOUSEMOVE:
215 case EMSCRIPTEN_EVENT_MOUSEDOWN:
216 case EMSCRIPTEN_EVENT_MOUSEUP:
217 case EMSCRIPTEN_EVENT_CLICK:
218 case EMSCRIPTEN_EVENT_DBLCLICK:
219 case EMSCRIPTEN_EVENT_MOUSEENTER:
220 case EMSCRIPTEN_EVENT_MOUSELEAVE:
222 return ProcessMouseEvent (theListener, theEventType, (const EmscriptenMouseEvent* )theEvent);
224 case EMSCRIPTEN_EVENT_TOUCHSTART:
225 case EMSCRIPTEN_EVENT_TOUCHMOVE:
226 case EMSCRIPTEN_EVENT_TOUCHEND:
227 case EMSCRIPTEN_EVENT_TOUCHCANCEL:
229 return ProcessTouchEvent (theListener, theEventType, (const EmscriptenTouchEvent* )theEvent);
231 case EMSCRIPTEN_EVENT_WHEEL:
233 return ProcessWheelEvent (theListener, theEventType, (const EmscriptenWheelEvent* )theEvent);
235 case EMSCRIPTEN_EVENT_KEYDOWN:
236 case EMSCRIPTEN_EVENT_KEYUP:
237 case EMSCRIPTEN_EVENT_KEYPRESS:
239 return ProcessKeyEvent (theListener, theEventType, (const EmscriptenKeyboardEvent* )theEvent);
241 case EMSCRIPTEN_EVENT_RESIZE:
242 case EMSCRIPTEN_EVENT_CANVASRESIZED:
244 return ProcessUiEvent (theListener, theEventType, (const EmscriptenUiEvent* )theEvent);
246 case EMSCRIPTEN_EVENT_FOCUS:
247 case EMSCRIPTEN_EVENT_FOCUSIN:
248 case EMSCRIPTEN_EVENT_FOCUSOUT:
250 return ProcessFocusEvent (theListener, theEventType, (const EmscriptenFocusEvent* )theEvent);
262 // =======================================================================
263 // function : ProcessMouseEvent
265 // =======================================================================
266 bool Wasm_Window::ProcessMouseEvent (Aspect_WindowInputListener& theListener,
267 int theEventType, const EmscriptenMouseEvent* theEvent)
269 #if defined(__EMSCRIPTEN__)
270 const Graphic3d_Vec2d aNewPos2d = ConvertPointToBacking (Graphic3d_Vec2d (theEvent->targetX, theEvent->targetY));
271 const Graphic3d_Vec2i aNewPos2i = Graphic3d_Vec2i (aNewPos2d + Graphic3d_Vec2d (0.5));
272 Aspect_VKeyFlags aFlags = 0;
273 if (theEvent->ctrlKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_CTRL; }
274 if (theEvent->shiftKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_SHIFT; }
275 if (theEvent->altKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_ALT; }
276 if (theEvent->metaKey == EM_TRUE) { aFlags |= Aspect_VKeyFlags_META; }
278 const bool isEmulated = false;
279 const Aspect_VKeyMouse aButtons = Wasm_Window::MouseButtonsFromNative (theEvent->buttons);
280 switch (theEventType)
282 case EMSCRIPTEN_EVENT_MOUSEMOVE:
284 if ((aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x()
285 || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y())
286 && theListener.PressedMouseButtons() == Aspect_VKeyMouse_NONE)
290 if (theListener.UpdateMousePosition (aNewPos2i, aButtons, aFlags, isEmulated))
292 theListener.ProcessInput();
296 case EMSCRIPTEN_EVENT_MOUSEDOWN:
297 case EMSCRIPTEN_EVENT_MOUSEUP:
299 if (theEventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
301 if (aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x()
302 || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y())
307 if (theListener.UpdateMouseButtons (aNewPos2i, aButtons, aFlags, isEmulated))
309 theListener.ProcessInput();
313 case EMSCRIPTEN_EVENT_CLICK:
314 case EMSCRIPTEN_EVENT_DBLCLICK:
316 if (aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x()
317 || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y())
323 case EMSCRIPTEN_EVENT_MOUSEENTER:
327 case EMSCRIPTEN_EVENT_MOUSELEAVE:
329 // there is no SetCapture() support, so that mouse unclick events outside canvas will not arrive,
330 // so we have to forget current state...
331 if (theListener.UpdateMouseButtons (aNewPos2i, Aspect_VKeyMouse_NONE, aFlags, isEmulated))
333 theListener.ProcessInput();
347 // =======================================================================
348 // function : ProcessWheelEvent
350 // =======================================================================
351 bool Wasm_Window::ProcessWheelEvent (Aspect_WindowInputListener& theListener,
352 int theEventType, const EmscriptenWheelEvent* theEvent)
354 #if defined(__EMSCRIPTEN__)
355 if (theEventType != EMSCRIPTEN_EVENT_WHEEL)
360 const Graphic3d_Vec2d aNewPos2d = ConvertPointToBacking (Graphic3d_Vec2d (theEvent->mouse.targetX, theEvent->mouse.targetY));
361 const Graphic3d_Vec2i aNewPos2i = Graphic3d_Vec2i (aNewPos2d + Graphic3d_Vec2d (0.5));
362 if (aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x()
363 || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y())
369 switch (theEvent->deltaMode)
371 case DOM_DELTA_PIXEL:
373 aDelta = theEvent->deltaY / (5.0 * DevicePixelRatio());
378 aDelta = theEvent->deltaY * 8.0;
383 aDelta = theEvent->deltaY >= 0.0 ? 24.0 : -24.0;
389 if (theListener.UpdateMouseScroll (Aspect_ScrollDelta (aNewPos2i, -aDelta)))
391 theListener.ProcessInput();
402 // =======================================================================
403 // function : ProcessTouchEvent
405 // =======================================================================
406 bool Wasm_Window::ProcessTouchEvent (Aspect_WindowInputListener& theListener,
407 int theEventType, const EmscriptenTouchEvent* theEvent)
409 bool hasUpdates = false;
410 #if defined(__EMSCRIPTEN__)
411 if (theEventType != EMSCRIPTEN_EVENT_TOUCHSTART
412 && theEventType != EMSCRIPTEN_EVENT_TOUCHMOVE
413 && theEventType != EMSCRIPTEN_EVENT_TOUCHEND
414 && theEventType != EMSCRIPTEN_EVENT_TOUCHCANCEL)
419 for (int aTouchIter = 0; aTouchIter < theEvent->numTouches; ++aTouchIter)
421 const EmscriptenTouchPoint& aTouch = theEvent->touches[aTouchIter];
422 if (!aTouch.isChanged)
427 const Standard_Size aTouchId = (Standard_Size )aTouch.identifier;
429 const Graphic3d_Vec2d aNewPos2d = ConvertPointToBacking (Graphic3d_Vec2d (aTouch.targetX, aTouch.targetY));
430 const Graphic3d_Vec2i aNewPos2i = Graphic3d_Vec2i (aNewPos2d + Graphic3d_Vec2d (0.5));
431 switch (theEventType)
433 case EMSCRIPTEN_EVENT_TOUCHSTART:
435 if (aNewPos2i.x() >= 0 && aNewPos2i.x() < mySize.x()
436 && aNewPos2i.y() >= 0 && aNewPos2i.y() < mySize.y())
439 theListener.AddTouchPoint (aTouchId, aNewPos2d);
443 case EMSCRIPTEN_EVENT_TOUCHMOVE:
445 const int anOldIndex = theListener.TouchPoints().FindIndex (aTouchId);
449 theListener.UpdateTouchPoint (aTouchId, aNewPos2d);
453 case EMSCRIPTEN_EVENT_TOUCHEND:
454 case EMSCRIPTEN_EVENT_TOUCHCANCEL:
456 if (theListener.RemoveTouchPoint (aTouchId))
466 theListener.ProcessInput();
472 return hasUpdates || theListener.HasTouchPoints();
475 // =======================================================================
476 // function : ProcessKeyEvent
478 // =======================================================================
479 bool Wasm_Window::ProcessKeyEvent (Aspect_WindowInputListener& theListener,
480 int theEventType, const EmscriptenKeyboardEvent* theEvent)
482 #if defined(__EMSCRIPTEN__)
483 if (theEventType != EMSCRIPTEN_EVENT_KEYDOWN
484 && theEventType != EMSCRIPTEN_EVENT_KEYUP
485 && theEventType != EMSCRIPTEN_EVENT_KEYPRESS)
490 const double aTimeStamp = theListener.EventTime();
491 const Aspect_VKey aVKey = Wasm_Window::VirtualKeyFromNative (theEvent->keyCode);
492 if (aVKey == Aspect_VKey_UNKNOWN)
497 switch (theEventType)
499 case EMSCRIPTEN_EVENT_KEYDOWN:
501 if (theEvent->repeat == EM_TRUE)
506 theListener.KeyDown (aVKey, aTimeStamp);
507 theListener.ProcessInput();
510 case EMSCRIPTEN_EVENT_KEYUP:
512 theListener.KeyUp (aVKey, aTimeStamp);
513 theListener.ProcessInput();
525 // =======================================================================
526 // function : ProcessUiEvent
528 // =======================================================================
529 bool Wasm_Window::ProcessUiEvent (Aspect_WindowInputListener& theListener,
530 int theEventType, const EmscriptenUiEvent* )
532 #if defined(__EMSCRIPTEN__)
533 if (theEventType != EMSCRIPTEN_EVENT_RESIZE
534 && theEventType != EMSCRIPTEN_EVENT_CANVASRESIZED)
541 theListener.ProcessConfigure (true);
545 // =======================================================================
546 // function : ProcessFocusEvent
548 // =======================================================================
549 bool Wasm_Window::ProcessFocusEvent (Aspect_WindowInputListener& theListener,
550 int theEventType, const EmscriptenFocusEvent* )
552 bool isActivated = false;
553 #if defined(__EMSCRIPTEN__)
554 if (theEventType != EMSCRIPTEN_EVENT_FOCUS
555 && theEventType != EMSCRIPTEN_EVENT_FOCUSIN // about to receive focus
556 && theEventType != EMSCRIPTEN_EVENT_FOCUSOUT)
560 isActivated = theEventType == EMSCRIPTEN_EVENT_FOCUS;
564 theListener.ProcessFocus (isActivated);
568 // =======================================================================
569 // function : MouseButtonsFromNative
571 // =======================================================================
572 Aspect_VKeyMouse Wasm_Window::MouseButtonsFromNative (unsigned short theButtons)
574 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
575 if ((theButtons & 0x1) != 0)
577 aButtons |= Aspect_VKeyMouse_LeftButton;
579 if ((theButtons & 0x2) != 0)
581 aButtons |= Aspect_VKeyMouse_RightButton;
583 if ((theButtons & 0x4) != 0)
585 aButtons |= Aspect_VKeyMouse_MiddleButton;
590 // =======================================================================
591 // function : VirtualKeyFromNative
593 // =======================================================================
594 Aspect_VKey Wasm_Window::VirtualKeyFromNative (Standard_Integer theKey)
596 #if defined(__EMSCRIPTEN__)
597 if (theKey >= DOM_VK_0
598 && theKey <= DOM_VK_9)
601 return Aspect_VKey((theKey - DOM_VK_0) + Aspect_VKey_0);
603 if (theKey >= DOM_VK_A
604 && theKey <= DOM_VK_Z)
606 // main latin alphabet keys
607 return Aspect_VKey((theKey - DOM_VK_A) + Aspect_VKey_A);
609 if (theKey >= DOM_VK_F1
610 && theKey <= DOM_VK_F24)
613 if (theKey <= DOM_VK_F12)
615 return Aspect_VKey((theKey - DOM_VK_F1) + Aspect_VKey_F1);
617 return Aspect_VKey_UNKNOWN;
619 if (theKey >= DOM_VK_NUMPAD0
620 && theKey <= DOM_VK_NUMPAD9)
623 return Aspect_VKey((theKey - DOM_VK_NUMPAD0) + Aspect_VKey_Numpad0);
630 return Aspect_VKey_UNKNOWN;
631 case DOM_VK_BACK_SPACE:
632 return Aspect_VKey_Backspace;
634 return Aspect_VKey_Tab;
636 return Aspect_VKey_UNKNOWN;
639 return Aspect_VKey_Enter;
641 return Aspect_VKey_Shift;
643 return Aspect_VKey_Control;
645 return Aspect_VKey_Alt;
647 case DOM_VK_CAPS_LOCK:
649 //case DOM_VK_HANGUL:
655 return Aspect_VKey_UNKNOWN;
657 return Aspect_VKey_Escape;
659 case DOM_VK_NONCONVERT:
661 case DOM_VK_MODECHANGE:
662 return Aspect_VKey_UNKNOWN;
664 return Aspect_VKey_Space;
666 return Aspect_VKey_PageUp;
667 case DOM_VK_PAGE_DOWN:
668 return Aspect_VKey_PageDown;
670 return Aspect_VKey_End;
672 return Aspect_VKey_Home;
674 return Aspect_VKey_Left;
676 return Aspect_VKey_Up;
678 return Aspect_VKey_Right;
680 return Aspect_VKey_Down;
684 case DOM_VK_PRINTSCREEN:
686 return Aspect_VKey_UNKNOWN;
688 return Aspect_VKey_Delete;
690 return Aspect_VKey_Comma;
691 case DOM_VK_SEMICOLON:
692 return Aspect_VKey_Semicolon;
693 case DOM_VK_LESS_THAN:
694 return Aspect_VKey_UNKNOWN;
696 return Aspect_VKey_Equal;
697 case DOM_VK_GREATER_THAN:
698 return Aspect_VKey_UNKNOWN;
699 case DOM_VK_QUESTION_MARK:
700 return Aspect_VKey_Slash;
701 case DOM_VK_AT: // @ key
702 return Aspect_VKey_UNKNOWN;
704 return Aspect_VKey_Meta;
705 case DOM_VK_CONTEXT_MENU:
707 return Aspect_VKey_UNKNOWN;
708 case DOM_VK_MULTIPLY:
709 return Aspect_VKey_NumpadMultiply;
711 return Aspect_VKey_NumpadAdd;
712 case DOM_VK_SEPARATOR:
713 return Aspect_VKey_UNKNOWN;
714 case DOM_VK_SUBTRACT:
715 return Aspect_VKey_NumpadSubtract;
717 return Aspect_VKey_UNKNOWN;
719 return Aspect_VKey_NumpadDivide;
720 case DOM_VK_NUM_LOCK:
721 return Aspect_VKey_Numlock;
722 case DOM_VK_SCROLL_LOCK:
723 return Aspect_VKey_Scroll;
724 case DOM_VK_WIN_OEM_FJ_JISHO:
725 case DOM_VK_WIN_OEM_FJ_MASSHOU:
726 case DOM_VK_WIN_OEM_FJ_TOUROKU:
727 case DOM_VK_WIN_OEM_FJ_LOYA:
728 case DOM_VK_WIN_OEM_FJ_ROYA:
729 case DOM_VK_CIRCUMFLEX:
730 return Aspect_VKey_UNKNOWN;
731 case DOM_VK_EXCLAMATION:
732 case DOM_VK_DOUBLE_QUOTE:
736 case DOM_VK_AMPERSAND:
737 case DOM_VK_UNDERSCORE:
738 case DOM_VK_OPEN_PAREN:
739 case DOM_VK_CLOSE_PAREN:
740 case DOM_VK_ASTERISK:
741 return Aspect_VKey_UNKNOWN;
743 return Aspect_VKey_Plus;
745 case DOM_VK_HYPHEN_MINUS:
746 return Aspect_VKey_UNKNOWN;
747 case DOM_VK_OPEN_CURLY_BRACKET:
748 return Aspect_VKey_BracketLeft;
749 case DOM_VK_CLOSE_CURLY_BRACKET:
750 return Aspect_VKey_BracketRight;
752 return Aspect_VKey_Tilde;
753 case DOM_VK_VOLUME_MUTE:
754 return Aspect_VKey_VolumeMute;
755 case DOM_VK_VOLUME_DOWN:
756 return Aspect_VKey_VolumeDown;
757 case DOM_VK_VOLUME_UP:
758 return Aspect_VKey_VolumeUp;
760 return Aspect_VKey_Comma;
762 return Aspect_VKey_Period;
764 return Aspect_VKey_Slash;
765 case DOM_VK_BACK_QUOTE:
766 return Aspect_VKey_UNKNOWN;
767 case DOM_VK_OPEN_BRACKET:
768 return Aspect_VKey_BracketLeft;
769 case DOM_VK_BACK_SLASH:
770 return Aspect_VKey_Backslash;
771 case DOM_VK_CLOSE_BRACKET:
772 return Aspect_VKey_BracketRight;
774 return Aspect_VKey_UNKNOWN;
776 return Aspect_VKey_Meta;
778 return Aspect_VKey_Alt;
779 case DOM_VK_WIN_ICO_HELP:
780 case DOM_VK_WIN_ICO_00:
781 case DOM_VK_WIN_ICO_CLEAR:
782 case DOM_VK_WIN_OEM_RESET:
783 case DOM_VK_WIN_OEM_JUMP:
784 case DOM_VK_WIN_OEM_PA1:
785 case DOM_VK_WIN_OEM_PA2:
786 case DOM_VK_WIN_OEM_PA3:
787 case DOM_VK_WIN_OEM_WSCTRL:
788 case DOM_VK_WIN_OEM_CUSEL:
789 case DOM_VK_WIN_OEM_ATTN:
790 case DOM_VK_WIN_OEM_FINISH:
791 case DOM_VK_WIN_OEM_COPY:
792 case DOM_VK_WIN_OEM_AUTO:
793 case DOM_VK_WIN_OEM_ENLW:
794 case DOM_VK_WIN_OEM_BACKTAB:
799 return Aspect_VKey_UNKNOWN;
801 return Aspect_VKey_MediaPlayPause;
804 case DOM_VK_WIN_OEM_CLEAR:
805 return Aspect_VKey_UNKNOWN;
810 return Aspect_VKey_UNKNOWN;