0031067: Visualization - Aspect_Window::DoResize() should be a non-const method
[occt.git] / src / Xw / Xw_Window.cxx
CommitLineData
ed97f43c 1// Created on: 2013-04-06
2// Created by: Kirill Gavrilov
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
ed97f43c 16#include <Xw_Window.hxx>
7fd59977 17
d8d01f6e 18#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
7fd59977 19
7fd59977 20#include <Aspect_Convert.hxx>
ed97f43c 21#include <Aspect_WindowDefinitionError.hxx>
1136702b 22#include <Message.hxx>
23#include <Message_Messenger.hxx>
7fd59977 24
49582f9d 25//#include <X11/XF86keysym.h>
26
1136702b 27#if defined(HAVE_EGL) || defined(HAVE_GLES2)
28 #include <EGL/egl.h>
9aceb23d 29 #ifndef EGL_OPENGL_ES3_BIT
30 #define EGL_OPENGL_ES3_BIT 0x00000040
31 #endif
1136702b 32#else
33 #include <GL/glx.h>
f5f4ebd0 34
ed97f43c 35namespace
36{
7fd59977 37
a6eb515f 38 //! Search for RGBA double-buffered visual with stencil buffer.
b6bf4ec1 39 static int TheDoubleBuffVisual[] =
ed97f43c 40 {
41 GLX_RGBA,
42 GLX_DEPTH_SIZE, 16,
a6eb515f 43 GLX_STENCIL_SIZE, 1,
ed97f43c 44 GLX_DOUBLEBUFFER,
45 None
46 };
47
b6bf4ec1 48 //! Search for RGBA double-buffered visual with stencil buffer.
49 static int TheDoubleBuffFBConfig[] =
50 {
51 GLX_X_RENDERABLE, True,
52 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
53 GLX_RENDER_TYPE, GLX_RGBA_BIT,
54 GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
55 GLX_DEPTH_SIZE, 16,
56 GLX_STENCIL_SIZE, 1,
57 GLX_DOUBLEBUFFER, True,
58 None
59 };
ed97f43c 60
b6bf4ec1 61}
ed97f43c 62
1136702b 63#endif
64
65IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
66
ed97f43c 67// =======================================================================
68// function : Xw_Window
69// purpose :
70// =======================================================================
71Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
72 const Standard_CString theTitle,
73 const Standard_Integer thePxLeft,
74 const Standard_Integer thePxTop,
75 const Standard_Integer thePxWidth,
b6bf4ec1 76 const Standard_Integer thePxHeight,
77 const Aspect_FBConfig theFBConfig)
ed97f43c 78: Aspect_Window(),
79 myDisplay (theXDisplay),
80 myXWindow (0),
b6bf4ec1 81 myFBConfig (theFBConfig),
ed97f43c 82 myXLeft (thePxLeft),
83 myYTop (thePxTop),
84 myXRight (thePxLeft + thePxWidth),
85 myYBottom (thePxTop + thePxHeight),
86 myIsOwnWin (Standard_True)
7fd59977 87{
ed97f43c 88 if (thePxWidth <= 0 || thePxHeight <= 0)
89 {
9775fa61 90 throw Aspect_WindowDefinitionError("Xw_Window, Coordinate(s) out of range");
ed97f43c 91 }
92 else if (theXDisplay.IsNull())
93 {
9775fa61 94 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
ed97f43c 95 return;
96 }
7fd59977 97
ed97f43c 98 Display* aDisp = myDisplay->GetDisplay();
99 int aScreen = DefaultScreen(aDisp);
100 Window aParent = RootWindow (aDisp, aScreen);
b6bf4ec1 101 XVisualInfo* aVisInfo = NULL;
7fd59977 102
1136702b 103#if defined(HAVE_EGL) || defined(HAVE_GLES2)
104 EGLDisplay anEglDisplay = eglGetDisplay (aDisp);
105 EGLint aVerMajor = 0; EGLint aVerMinor = 0;
106 XVisualInfo aVisInfoTmp; memset (&aVisInfoTmp, 0, sizeof(aVisInfoTmp));
107 if (anEglDisplay != EGL_NO_DISPLAY
108 && eglInitialize (anEglDisplay, &aVerMajor, &aVerMinor) == EGL_TRUE)
109 {
110 EGLint aConfigAttribs[] =
111 {
112 EGL_RED_SIZE, 8,
113 EGL_GREEN_SIZE, 8,
114 EGL_BLUE_SIZE, 8,
115 EGL_ALPHA_SIZE, 0,
116 EGL_DEPTH_SIZE, 24,
117 EGL_STENCIL_SIZE, 8,
118 #if defined(HAVE_GLES2)
119 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
120 #else
121 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
122 #endif
123 EGL_NONE
124 };
125
126 EGLint aNbConfigs = 0;
127 void* anEglConfig = NULL;
9aceb23d 128 for (Standard_Integer aGlesVer = 3; aGlesVer >= 2; --aGlesVer)
1136702b 129 {
9aceb23d 130 #if defined(GL_ES_VERSION_2_0)
131 aConfigAttribs[6 * 2 + 1] = aGlesVer == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
132 #else
133 if (aGlesVer == 2)
134 {
135 break;
136 }
137 #endif
138
139 if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) == EGL_TRUE
140 && anEglConfig != NULL)
141 {
142 break;
143 }
1136702b 144 eglGetError();
9aceb23d 145
1136702b 146 aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
9aceb23d 147 if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) == EGL_TRUE
148 && anEglConfig != NULL)
1136702b 149 {
9aceb23d 150 break;
1136702b 151 }
9aceb23d 152 eglGetError();
1136702b 153 }
154
155 if (anEglConfig != NULL
156 && eglGetConfigAttrib (anEglDisplay, anEglConfig, EGL_NATIVE_VISUAL_ID, (EGLint* )&aVisInfoTmp.visualid) == EGL_TRUE)
157 {
158 int aNbVisuals = 0;
159 aVisInfoTmp.screen = DefaultScreen (aDisp);
160 aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbVisuals);
161 }
162 }
163 if (aVisInfo == NULL)
164 {
165 Message::DefaultMessenger()->Send ("Warning: cannot choose Visual using EGL while creating Xw_Window", Message_Warning);
166 }
167#else
168 int aDummy = 0;
169 if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
170 {
171 throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable");
172 return;
173 }
b6bf4ec1 174 if (myFBConfig == NULL)
175 {
176 // FBConfigs were added in GLX version 1.3
177 int aGlxMajor = 0;
178 int aGlxMinor = 0;
179 const bool hasFBCfg = glXQueryVersion (aDisp, &aGlxMajor, &aGlxMinor)
180 && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1));
181 if (hasFBCfg)
182 {
183 int aFBCount = 0;
184 GLXFBConfig* aFBCfgList = NULL;
185 if (hasFBCfg)
186 {
187 aFBCfgList = glXChooseFBConfig (aDisp, aScreen, TheDoubleBuffFBConfig, &aFBCount);
188 }
189 if(aFBCfgList != NULL
190 && aFBCount >= 1)
191 {
192 myFBConfig = aFBCfgList[0];
193 aVisInfo = glXGetVisualFromFBConfig (aDisp, myFBConfig);
194 }
195 XFree (aFBCfgList);
196 }
197 }
198
199 if (aVisInfo == NULL)
200 {
201 aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuffVisual);
202 }
ed97f43c 203 if (aVisInfo == NULL)
204 {
9775fa61 205 throw Aspect_WindowDefinitionError("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
ed97f43c 206 return;
207 }
1136702b 208#endif
7fd59977 209
ed97f43c 210 unsigned long aMask = 0;
211 XSetWindowAttributes aWinAttr;
212 memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
213 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
214 aMask |= CWEventMask;
1136702b 215 if (aVisInfo != NULL)
216 {
217 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
218 }
ed97f43c 219 aWinAttr.border_pixel = 0;
220 aWinAttr.override_redirect = False;
221
222 myXWindow = XCreateWindow(aDisp, aParent,
223 myXLeft, myYTop, thePxWidth, thePxHeight,
1136702b 224 0, aVisInfo != NULL ? aVisInfo->depth : CopyFromParent,
ed97f43c 225 InputOutput,
1136702b 226 aVisInfo != NULL ? aVisInfo->visual : CopyFromParent,
ed97f43c 227 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
1136702b 228 if (aVisInfo != NULL)
229 {
230 XFree (aVisInfo);
231 aVisInfo = NULL;
232 }
ed97f43c 233 if (myXWindow == 0)
234 {
9775fa61 235 throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window");
ed97f43c 236 return;
237 }
7fd59977 238
ed97f43c 239 // if parent - desktop
240 XSizeHints aSizeHints;
241 aSizeHints.x = myXLeft;
242 aSizeHints.y = myYTop;
243 aSizeHints.flags = PPosition;
244 aSizeHints.width = thePxWidth;
245 aSizeHints.height = thePxHeight;
246 aSizeHints.flags |= PSize;
247 XSetStandardProperties (aDisp, myXWindow, theTitle, theTitle, None,
248 NULL, 0, &aSizeHints);
249
250 /*XTextProperty aTitleProperty;
251 aTitleProperty.encoding = None;
252 char* aTitle = (char* )theTitle;
253 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
254 XSetWMName (aDisp, myXWindow, &aTitleProperty);
255 XSetWMProperties(aDisp, myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
256
257 XFlush (aDisp);
7fd59977 258}
259
ed97f43c 260// =======================================================================
261// function : Xw_Window
262// purpose :
263// =======================================================================
264Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
b6bf4ec1 265 const Window theXWin,
266 const Aspect_FBConfig theFBConfig)
dc3fe572 267: Aspect_Window(),
ed97f43c 268 myDisplay (theXDisplay),
269 myXWindow (theXWin),
b6bf4ec1 270 myFBConfig (theFBConfig),
ed97f43c 271 myXLeft (0),
272 myYTop (0),
273 myXRight (512),
274 myYBottom (512),
275 myIsOwnWin (Standard_False)
7fd59977 276{
ed97f43c 277 if (theXWin == 0)
278 {
9775fa61 279 throw Aspect_WindowDefinitionError("Xw_Window, given invalid X window");
ed97f43c 280 return;
281 }
282 else if (theXDisplay.IsNull())
283 {
9775fa61 284 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
ed97f43c 285 return;
286 }
1136702b 287#if !defined(HAVE_EGL) && !defined(HAVE_GLES2)
288 int aDummy = 0;
289 if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
ed97f43c 290 {
291 myXWindow = 0;
9775fa61 292 throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable");
ed97f43c 293 return;
294 }
1136702b 295#endif
7fd59977 296
ed97f43c 297 Display* aDisp = myDisplay->GetDisplay();
298
299 XWindowAttributes aWinAttr;
300 XGetWindowAttributes (aDisp, myXWindow, &aWinAttr);
ed97f43c 301 XVisualInfo aVisInfoTmp;
302 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
1136702b 303 aVisInfoTmp.screen = DefaultScreen (aDisp);
ed97f43c 304 int aNbItems = 0;
1136702b 305 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbItems);
ed97f43c 306 if (aVisInfo == NULL)
307 {
9775fa61 308 throw Aspect_WindowDefinitionError("Xw_Window, Visual is unavailable");
ed97f43c 309 return;
310 }
311 XFree (aVisInfo);
7fd59977 312
ed97f43c 313 DoResize();
7fd59977 314}
315
ed97f43c 316// =======================================================================
e6f550da 317// function : ~Xw_Window
ed97f43c 318// purpose :
319// =======================================================================
e6f550da 320Xw_Window::~Xw_Window()
7fd59977 321{
ed97f43c 322 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
7fd59977 323 {
ed97f43c 324 XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
7fd59977 325 }
7fd59977 326}
327
ed97f43c 328// =======================================================================
329// function : XWindow
330// purpose :
331// =======================================================================
332Window Xw_Window::XWindow() const
7fd59977 333{
ed97f43c 334 return myXWindow;
7fd59977 335}
336
ed97f43c 337// =======================================================================
338// function : IsMapped
339// purpose :
340// =======================================================================
341Standard_Boolean Xw_Window::IsMapped() const
7fd59977 342{
ed97f43c 343 if (myXWindow == 0)
344 {
345 return false;
dc3fe572 346 }
ed97f43c 347 else if (IsVirtual())
348 {
349 return Standard_True;
7fd59977 350 }
dc3fe572 351
ed97f43c 352 XFlush (myDisplay->GetDisplay());
353 XWindowAttributes aWinAttr;
354 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
355 return aWinAttr.map_state == IsUnviewable
356 || aWinAttr.map_state == IsViewable;
7fd59977 357}
358
ed97f43c 359// =======================================================================
360// function : Map
361// purpose :
362// =======================================================================
363void Xw_Window::Map() const
7fd59977 364{
ed97f43c 365 if (IsVirtual() || myXWindow == 0)
366 {
367 return;
7fd59977 368 }
369
ed97f43c 370 XMapWindow (myDisplay->GetDisplay(), myXWindow);
371 XFlush (myDisplay->GetDisplay());
7fd59977 372}
373
ed97f43c 374// =======================================================================
375// function : Unmap
376// purpose :
377// =======================================================================
378void Xw_Window::Unmap() const
379{
380 if (IsVirtual() || myXWindow == 0)
381 {
382 return;
7fd59977 383 }
7fd59977 384
ed97f43c 385 XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
7fd59977 386}
387
ed97f43c 388// =======================================================================
389// function : DoResize
390// purpose :
391// =======================================================================
1a5007a9 392Aspect_TypeOfResize Xw_Window::DoResize()
ed97f43c 393{
394 if (myXWindow == 0)
395 {
396 return Aspect_TOR_UNKNOWN;
397 }
7fd59977 398
ed97f43c 399 XFlush (myDisplay->GetDisplay());
400 XWindowAttributes aWinAttr;
401 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
402 if (aWinAttr.map_state == IsUnmapped)
403 {
404 return Aspect_TOR_UNKNOWN;
405 }
7fd59977 406
ed97f43c 407 Standard_Integer aMask = 0;
408 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
7fd59977 409
ed97f43c 410 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
411 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
412 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
413 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
414 switch (aMask)
415 {
416 case 0: aMode = Aspect_TOR_NO_BORDER; break;
417 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
418 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
419 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
420 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
421 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
422 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
423 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
424 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
425 default: break;
426 }
7fd59977 427
1a5007a9 428 myXLeft = aWinAttr.x;
429 myXRight = aWinAttr.x + aWinAttr.width;
430 myYTop = aWinAttr.y;
431 myYBottom = aWinAttr.y + aWinAttr.height;
ed97f43c 432 return aMode;
7fd59977 433}
7fd59977 434
ed97f43c 435// =======================================================================
436// function : DoMapping
437// purpose :
438// =======================================================================
439Standard_Boolean Xw_Window::DoMapping() const
440{
441 return Standard_True; // IsMapped()
7fd59977 442}
443
ed97f43c 444// =======================================================================
445// function : Ratio
446// purpose :
447// =======================================================================
ee2be2a8 448Standard_Real Xw_Window::Ratio() const
ed97f43c 449{
450 if (myXWindow == 0)
451 {
452 return 1.0;
453 }
7fd59977 454
ed97f43c 455 XFlush (myDisplay->GetDisplay());
456 XWindowAttributes aWinAttr;
457 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
ee2be2a8 458 return Standard_Real(aWinAttr.width) / Standard_Real(aWinAttr.height);
7fd59977 459}
460
ed97f43c 461// =======================================================================
462// function : Position
463// purpose :
464// =======================================================================
465void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
466 Standard_Integer& X2, Standard_Integer& Y2) const
467{
18d715bd 468 if (myXWindow == 0)
469 {
470 return;
471 }
472
473 XFlush (myDisplay->GetDisplay());
474 XWindowAttributes anAttributes;
475 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
476 Window aChild;
477 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
478 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
479
480 X1 = -anAttributes.x;
481 X2 = X1 + anAttributes.width;
482 Y1 = -anAttributes.y;
483 Y2 = Y1 + anAttributes.height;
7fd59977 484}
485
ed97f43c 486// =======================================================================
487// function : Size
488// purpose :
489// =======================================================================
490void Xw_Window::Size (Standard_Integer& theWidth,
491 Standard_Integer& theHeight) const
492{
493 if (myXWindow == 0)
494 {
495 return;
496 }
7fd59977 497
ed97f43c 498 XFlush (myDisplay->GetDisplay());
499 XWindowAttributes aWinAttr;
500 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
501 theWidth = aWinAttr.width;
502 theHeight = aWinAttr.height;
7fd59977 503}
504
49582f9d 505// =======================================================================
506// function : SetTitle
507// purpose :
508// =======================================================================
509void Xw_Window::SetTitle (const TCollection_AsciiString& theTitle)
510{
511 if (myXWindow != 0)
512 {
513 XStoreName (myDisplay->GetDisplay(), myXWindow, theTitle.ToCString());
514 }
515}
516
8693dfd0 517// =======================================================================
518// function : InvalidateContent
519// purpose :
520// =======================================================================
521void Xw_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp)
522{
523 if (myXWindow == 0)
524 {
525 return;
526 }
527
528 const Handle(Aspect_DisplayConnection)& aDisp = !theDisp.IsNull() ? theDisp : myDisplay;
529 Display* aDispX = aDisp->GetDisplay();
530
531 XEvent anEvent;
532 memset (&anEvent, 0, sizeof(anEvent));
533 anEvent.type = Expose;
534 anEvent.xexpose.window = myXWindow;
535 XSendEvent (aDispX, myXWindow, False, ExposureMask, &anEvent);
536 XFlush (aDispX);
537}
538
49582f9d 539// =======================================================================
540// function : VirtualKeyFromNative
541// purpose :
542// =======================================================================
543Aspect_VKey Xw_Window::VirtualKeyFromNative (unsigned long theKey)
544{
545 if (theKey >= XK_0
546 && theKey <= XK_9)
547 {
548 return Aspect_VKey(theKey - XK_0 + Aspect_VKey_0);
549 }
550
551 if (theKey >= XK_A
552 && theKey <= XK_Z)
553 {
554 return Aspect_VKey(theKey - XK_A + Aspect_VKey_A);
555 }
556
557 if (theKey >= XK_a
558 && theKey <= XK_z)
559 {
560 return Aspect_VKey(theKey - XK_a + Aspect_VKey_A);
561 }
562
563 if (theKey >= XK_F1
564 && theKey <= XK_F24)
565 {
566 if (theKey <= XK_F12)
567 {
568 return Aspect_VKey(theKey - XK_F1 + Aspect_VKey_F1);
569 }
570 return Aspect_VKey_UNKNOWN;
571 }
572
573 switch (theKey)
574 {
575 case XK_space:
576 return Aspect_VKey_Space;
577 case XK_apostrophe:
578 return Aspect_VKey_Apostrophe;
579 case XK_comma:
580 return Aspect_VKey_Comma;
581 case XK_minus:
582 return Aspect_VKey_Minus;
583 case XK_period:
584 return Aspect_VKey_Period;
585 case XK_semicolon:
586 return Aspect_VKey_Semicolon;
587 case XK_equal:
588 return Aspect_VKey_Equal;
589 case XK_bracketleft:
590 return Aspect_VKey_BracketLeft;
591 case XK_backslash:
592 return Aspect_VKey_Backslash;
593 case XK_bracketright:
594 return Aspect_VKey_BracketRight;
595 case XK_BackSpace:
596 return Aspect_VKey_Backspace;
597 case XK_Tab:
598 return Aspect_VKey_Tab;
599 //case XK_Linefeed:
600 case XK_Return:
601 case XK_KP_Enter:
602 return Aspect_VKey_Enter;
603 //case XK_Pause:
604 // return Aspect_VKey_Pause;
605 case XK_Escape:
606 return Aspect_VKey_Escape;
607 case XK_Home:
608 return Aspect_VKey_Home;
609 case XK_Left:
610 return Aspect_VKey_Left;
611 case XK_Up:
612 return Aspect_VKey_Up;
613 case XK_Right:
614 return Aspect_VKey_Right;
615 case XK_Down:
616 return Aspect_VKey_Down;
617 case XK_Prior:
618 return Aspect_VKey_PageUp;
619 case XK_Next:
620 return Aspect_VKey_PageDown;
621 case XK_End:
622 return Aspect_VKey_End;
623 //case XK_Insert:
624 // return Aspect_VKey_Insert;
625 case XK_Menu:
626 return Aspect_VKey_Menu;
627 case XK_Num_Lock:
628 return Aspect_VKey_Numlock;
629 //case XK_KP_Delete:
630 // return Aspect_VKey_NumDelete;
631 case XK_KP_Multiply:
632 return Aspect_VKey_NumpadMultiply;
633 case XK_KP_Add:
634 return Aspect_VKey_NumpadAdd;
635 //case XK_KP_Separator:
636 // return Aspect_VKey_Separator;
637 case XK_KP_Subtract:
638 return Aspect_VKey_NumpadSubtract;
639 //case XK_KP_Decimal:
640 // return Aspect_VKey_Decimal;
641 case XK_KP_Divide:
642 return Aspect_VKey_NumpadDivide;
643 case XK_Shift_L:
644 case XK_Shift_R:
645 return Aspect_VKey_Shift;
646 case XK_Control_L:
647 case XK_Control_R:
648 return Aspect_VKey_Control;
649 //case XK_Caps_Lock:
650 // return Aspect_VKey_CapsLock;
651 case XK_Alt_L:
652 case XK_Alt_R:
653 return Aspect_VKey_Alt;
654 //case XK_Super_L:
655 //case XK_Super_R:
656 // return Aspect_VKey_Super;
657 case XK_Delete:
658 return Aspect_VKey_Delete;
659
660 case 0x1008FF11: // XF86AudioLowerVolume
661 return Aspect_VKey_VolumeDown;
662 case 0x1008FF12: // XF86AudioMute
663 return Aspect_VKey_VolumeMute;
664 case 0x1008FF13: // XF86AudioRaiseVolume
665 return Aspect_VKey_VolumeUp;
666
667 case 0x1008FF14: // XF86AudioPlay
668 return Aspect_VKey_MediaPlayPause;
669 case 0x1008FF15: // XF86AudioStop
670 return Aspect_VKey_MediaStop;
671 case 0x1008FF16: // XF86AudioPrev
672 return Aspect_VKey_MediaPreviousTrack;
673 case 0x1008FF17: // XF86AudioNext
674 return Aspect_VKey_MediaNextTrack;
675
676 case 0x1008FF18: // XF86HomePage
677 return Aspect_VKey_BrowserHome;
678 case 0x1008FF26: // XF86Back
679 return Aspect_VKey_BrowserBack;
680 case 0x1008FF27: // XF86Forward
681 return Aspect_VKey_BrowserForward;
682 case 0x1008FF28: // XF86Stop
683 return Aspect_VKey_BrowserStop;
684 case 0x1008FF29: // XF86Refresh
685 return Aspect_VKey_BrowserRefresh;
686 }
687 return Aspect_VKey_UNKNOWN;
688}
689
ed97f43c 690#endif // Win32 or Mac OS X