0032323: Configuration - drop unused dependency from Xmu
[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
7fd59977 18#include <Aspect_Convert.hxx>
e8e157df 19#include <Aspect_ScrollDelta.hxx>
ed97f43c 20#include <Aspect_WindowDefinitionError.hxx>
e8e157df 21#include <Aspect_WindowInputListener.hxx>
1136702b 22#include <Message.hxx>
23#include <Message_Messenger.hxx>
b69e576a 24#include <Standard_NotImplemented.hxx>
25
26#if defined(HAVE_XLIB)
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
b69e576a 29 //#include <X11/XF86keysym.h>
30#endif
7fd59977 31
b69e576a 32#include <Aspect_DisplayConnection.hxx>
49582f9d 33
1136702b 34IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
35
ed97f43c 36// =======================================================================
37// function : Xw_Window
38// purpose :
39// =======================================================================
40Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
41 const Standard_CString theTitle,
42 const Standard_Integer thePxLeft,
43 const Standard_Integer thePxTop,
44 const Standard_Integer thePxWidth,
3ae8c60b 45 const Standard_Integer thePxHeight)
ed97f43c 46: Aspect_Window(),
47 myDisplay (theXDisplay),
48 myXWindow (0),
3ae8c60b 49 myFBConfig (NULL),
ed97f43c 50 myXLeft (thePxLeft),
51 myYTop (thePxTop),
52 myXRight (thePxLeft + thePxWidth),
53 myYBottom (thePxTop + thePxHeight),
54 myIsOwnWin (Standard_True)
7fd59977 55{
ed97f43c 56 if (thePxWidth <= 0 || thePxHeight <= 0)
57 {
9775fa61 58 throw Aspect_WindowDefinitionError("Xw_Window, Coordinate(s) out of range");
ed97f43c 59 }
60 else if (theXDisplay.IsNull())
61 {
9775fa61 62 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
ed97f43c 63 }
7fd59977 64
b69e576a 65#if defined(HAVE_XLIB)
3ae8c60b 66 myFBConfig = theXDisplay->GetDefaultFBConfig();
b69e576a 67 XVisualInfo* aVisInfo = theXDisplay->GetDefaultVisualInfoX();
3ae8c60b 68
ed97f43c 69 Display* aDisp = myDisplay->GetDisplay();
70 int aScreen = DefaultScreen(aDisp);
71 Window aParent = RootWindow (aDisp, aScreen);
9aceb23d 72
ed97f43c 73 unsigned long aMask = 0;
74 XSetWindowAttributes aWinAttr;
b69e576a 75 memset (&aWinAttr, 0, sizeof(aWinAttr));
ed97f43c 76 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
77 aMask |= CWEventMask;
1136702b 78 if (aVisInfo != NULL)
79 {
80 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
81 }
ed97f43c 82 aWinAttr.border_pixel = 0;
83 aWinAttr.override_redirect = False;
84
b69e576a 85 myXWindow = (Window )XCreateWindow (aDisp, aParent,
ed97f43c 86 myXLeft, myYTop, thePxWidth, thePxHeight,
1136702b 87 0, aVisInfo != NULL ? aVisInfo->depth : CopyFromParent,
ed97f43c 88 InputOutput,
1136702b 89 aVisInfo != NULL ? aVisInfo->visual : CopyFromParent,
ed97f43c 90 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
ed97f43c 91 if (myXWindow == 0)
92 {
9775fa61 93 throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window");
ed97f43c 94 }
7fd59977 95
ed97f43c 96 // if parent - desktop
97 XSizeHints aSizeHints;
98 aSizeHints.x = myXLeft;
99 aSizeHints.y = myYTop;
100 aSizeHints.flags = PPosition;
101 aSizeHints.width = thePxWidth;
102 aSizeHints.height = thePxHeight;
103 aSizeHints.flags |= PSize;
b69e576a 104 XSetStandardProperties (aDisp, (Window )myXWindow, theTitle, theTitle, None,
ed97f43c 105 NULL, 0, &aSizeHints);
106
107 /*XTextProperty aTitleProperty;
108 aTitleProperty.encoding = None;
109 char* aTitle = (char* )theTitle;
110 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
b69e576a 111 XSetWMName (aDisp, (Window )myXWindow, &aTitleProperty);
112 XSetWMProperties(aDisp, (Window )myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
ed97f43c 113
114 XFlush (aDisp);
b69e576a 115#else
116 (void )theTitle;
117 if (myXWindow == 0)
118 {
119 throw Aspect_WindowDefinitionError ("Xw_Window, Unable to create window - not implemented");
120 }
121#endif
7fd59977 122}
123
ed97f43c 124// =======================================================================
125// function : Xw_Window
126// purpose :
127// =======================================================================
128Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
b69e576a 129 const Aspect_Drawable theXWin,
b6bf4ec1 130 const Aspect_FBConfig theFBConfig)
dc3fe572 131: Aspect_Window(),
ed97f43c 132 myDisplay (theXDisplay),
133 myXWindow (theXWin),
b6bf4ec1 134 myFBConfig (theFBConfig),
ed97f43c 135 myXLeft (0),
136 myYTop (0),
137 myXRight (512),
138 myYBottom (512),
139 myIsOwnWin (Standard_False)
7fd59977 140{
ed97f43c 141 if (theXWin == 0)
142 {
9775fa61 143 throw Aspect_WindowDefinitionError("Xw_Window, given invalid X window");
ed97f43c 144 }
145 else if (theXDisplay.IsNull())
146 {
9775fa61 147 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
ed97f43c 148 }
7fd59977 149
b69e576a 150#if defined(HAVE_XLIB)
ed97f43c 151 Display* aDisp = myDisplay->GetDisplay();
152
153 XWindowAttributes aWinAttr;
b69e576a 154 XGetWindowAttributes (aDisp, (Window )myXWindow, &aWinAttr);
ed97f43c 155 XVisualInfo aVisInfoTmp;
156 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
1136702b 157 aVisInfoTmp.screen = DefaultScreen (aDisp);
ed97f43c 158 int aNbItems = 0;
1136702b 159 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbItems);
ed97f43c 160 if (aVisInfo == NULL)
161 {
9775fa61 162 throw Aspect_WindowDefinitionError("Xw_Window, Visual is unavailable");
ed97f43c 163 }
164 XFree (aVisInfo);
7fd59977 165
ed97f43c 166 DoResize();
b69e576a 167#else
168 //throw Standard_NotImplemented("Xw_Window, not implemented");
169#endif
7fd59977 170}
171
ed97f43c 172// =======================================================================
e6f550da 173// function : ~Xw_Window
ed97f43c 174// purpose :
175// =======================================================================
e6f550da 176Xw_Window::~Xw_Window()
7fd59977 177{
ed97f43c 178 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
7fd59977 179 {
b69e576a 180 #if defined(HAVE_XLIB)
181 XDestroyWindow (myDisplay->GetDisplay(), (Window )myXWindow);
182 #endif
7fd59977 183 }
7fd59977 184}
185
ed97f43c 186// =======================================================================
187// function : IsMapped
188// purpose :
189// =======================================================================
190Standard_Boolean Xw_Window::IsMapped() const
7fd59977 191{
ed97f43c 192 if (myXWindow == 0)
193 {
194 return false;
dc3fe572 195 }
ed97f43c 196 else if (IsVirtual())
197 {
198 return Standard_True;
7fd59977 199 }
dc3fe572 200
b69e576a 201#if defined(HAVE_XLIB)
ed97f43c 202 XFlush (myDisplay->GetDisplay());
203 XWindowAttributes aWinAttr;
b69e576a 204 XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
ed97f43c 205 return aWinAttr.map_state == IsUnviewable
206 || aWinAttr.map_state == IsViewable;
b69e576a 207#else
208 return Standard_False;
209#endif
7fd59977 210}
211
ed97f43c 212// =======================================================================
213// function : Map
214// purpose :
215// =======================================================================
216void Xw_Window::Map() const
7fd59977 217{
ed97f43c 218 if (IsVirtual() || myXWindow == 0)
219 {
220 return;
7fd59977 221 }
222
b69e576a 223#if defined(HAVE_XLIB)
224 XMapWindow (myDisplay->GetDisplay(), (Window )myXWindow);
ed97f43c 225 XFlush (myDisplay->GetDisplay());
b69e576a 226#endif
7fd59977 227}
228
ed97f43c 229// =======================================================================
230// function : Unmap
231// purpose :
232// =======================================================================
233void Xw_Window::Unmap() const
234{
235 if (IsVirtual() || myXWindow == 0)
236 {
237 return;
7fd59977 238 }
7fd59977 239
b69e576a 240#if defined(HAVE_XLIB)
241 XIconifyWindow (myDisplay->GetDisplay(), (Window )myXWindow, DefaultScreen(myDisplay->GetDisplay()));
242#endif
7fd59977 243}
244
ed97f43c 245// =======================================================================
246// function : DoResize
247// purpose :
248// =======================================================================
1a5007a9 249Aspect_TypeOfResize Xw_Window::DoResize()
ed97f43c 250{
e89202ea 251 if (IsVirtual() || myXWindow == 0)
ed97f43c 252 {
253 return Aspect_TOR_UNKNOWN;
254 }
7fd59977 255
b69e576a 256#if defined(HAVE_XLIB)
ed97f43c 257 XFlush (myDisplay->GetDisplay());
258 XWindowAttributes aWinAttr;
b69e576a 259 memset (&aWinAttr, 0, sizeof(aWinAttr));
260 XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
ed97f43c 261 if (aWinAttr.map_state == IsUnmapped)
262 {
263 return Aspect_TOR_UNKNOWN;
264 }
7fd59977 265
ed97f43c 266 Standard_Integer aMask = 0;
267 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
7fd59977 268
ed97f43c 269 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
270 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
271 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
272 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
273 switch (aMask)
274 {
275 case 0: aMode = Aspect_TOR_NO_BORDER; break;
276 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
277 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
278 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
279 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
280 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
281 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
282 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
283 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
284 default: break;
285 }
7fd59977 286
1a5007a9 287 myXLeft = aWinAttr.x;
288 myXRight = aWinAttr.x + aWinAttr.width;
289 myYTop = aWinAttr.y;
290 myYBottom = aWinAttr.y + aWinAttr.height;
ed97f43c 291 return aMode;
b69e576a 292#else
293 return Aspect_TOR_UNKNOWN;
294#endif
7fd59977 295}
296
ed97f43c 297// =======================================================================
298// function : Ratio
299// purpose :
300// =======================================================================
ee2be2a8 301Standard_Real Xw_Window::Ratio() const
ed97f43c 302{
e89202ea 303 if (IsVirtual() || myXWindow == 0)
ed97f43c 304 {
e89202ea 305 return Standard_Real(myXRight - myXLeft) / Standard_Real(myYBottom - myYTop);
ed97f43c 306 }
7fd59977 307
b69e576a 308#if defined(HAVE_XLIB)
ed97f43c 309 XFlush (myDisplay->GetDisplay());
310 XWindowAttributes aWinAttr;
b69e576a 311 memset (&aWinAttr, 0, sizeof(aWinAttr));
312 XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
ee2be2a8 313 return Standard_Real(aWinAttr.width) / Standard_Real(aWinAttr.height);
b69e576a 314#else
315 return 1.0;
316#endif
7fd59977 317}
318
ed97f43c 319// =======================================================================
320// function : Position
321// purpose :
322// =======================================================================
e89202ea 323void Xw_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1,
324 Standard_Integer& theX2, Standard_Integer& theY2) const
ed97f43c 325{
e89202ea 326 if (IsVirtual() || myXWindow == 0)
18d715bd 327 {
e89202ea 328 theX1 = myXLeft;
329 theX2 = myXRight;
330 theY1 = myYTop;
331 theY2 = myYBottom;
18d715bd 332 return;
333 }
334
b69e576a 335#if defined(HAVE_XLIB)
18d715bd 336 XFlush (myDisplay->GetDisplay());
337 XWindowAttributes anAttributes;
b69e576a 338 memset (&anAttributes, 0, sizeof(anAttributes));
339 XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &anAttributes);
18d715bd 340 Window aChild;
b69e576a 341 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, (Window )myXWindow,
18d715bd 342 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
343
e89202ea 344 theX1 = -anAttributes.x;
345 theX2 = theX1 + anAttributes.width;
346 theY1 = -anAttributes.y;
347 theY2 = theY1 + anAttributes.height;
b69e576a 348#endif
7fd59977 349}
350
ed97f43c 351// =======================================================================
352// function : Size
353// purpose :
354// =======================================================================
355void Xw_Window::Size (Standard_Integer& theWidth,
356 Standard_Integer& theHeight) const
357{
e89202ea 358 if (IsVirtual() || myXWindow == 0)
ed97f43c 359 {
e89202ea 360 theWidth = myXRight - myXLeft;
361 theHeight = myYBottom - myYTop;
ed97f43c 362 return;
363 }
7fd59977 364
b69e576a 365#if defined(HAVE_XLIB)
ed97f43c 366 XFlush (myDisplay->GetDisplay());
367 XWindowAttributes aWinAttr;
b69e576a 368 memset (&aWinAttr, 0, sizeof(aWinAttr));
369 XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
ed97f43c 370 theWidth = aWinAttr.width;
371 theHeight = aWinAttr.height;
b69e576a 372#endif
7fd59977 373}
374
49582f9d 375// =======================================================================
376// function : SetTitle
377// purpose :
378// =======================================================================
379void Xw_Window::SetTitle (const TCollection_AsciiString& theTitle)
380{
381 if (myXWindow != 0)
382 {
b69e576a 383 #if defined(HAVE_XLIB)
384 XStoreName (myDisplay->GetDisplay(), (Window )myXWindow, theTitle.ToCString());
385 #else
386 (void )theTitle;
387 #endif
49582f9d 388 }
389}
390
8693dfd0 391// =======================================================================
392// function : InvalidateContent
393// purpose :
394// =======================================================================
395void Xw_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp)
396{
397 if (myXWindow == 0)
398 {
399 return;
400 }
401
b69e576a 402#if defined(HAVE_XLIB)
8693dfd0 403 const Handle(Aspect_DisplayConnection)& aDisp = !theDisp.IsNull() ? theDisp : myDisplay;
404 Display* aDispX = aDisp->GetDisplay();
405
406 XEvent anEvent;
407 memset (&anEvent, 0, sizeof(anEvent));
408 anEvent.type = Expose;
b69e576a 409 anEvent.xexpose.window = (Window )myXWindow;
410 XSendEvent (aDispX, (Window )myXWindow, False, ExposureMask, &anEvent);
8693dfd0 411 XFlush (aDispX);
b69e576a 412#else
413 (void )theDisp;
414#endif
8693dfd0 415}
416
49582f9d 417// =======================================================================
418// function : VirtualKeyFromNative
419// purpose :
420// =======================================================================
421Aspect_VKey Xw_Window::VirtualKeyFromNative (unsigned long theKey)
422{
b69e576a 423#if defined(HAVE_XLIB)
49582f9d 424 if (theKey >= XK_0
425 && theKey <= XK_9)
426 {
427 return Aspect_VKey(theKey - XK_0 + Aspect_VKey_0);
428 }
429
430 if (theKey >= XK_A
431 && theKey <= XK_Z)
432 {
433 return Aspect_VKey(theKey - XK_A + Aspect_VKey_A);
434 }
435
436 if (theKey >= XK_a
437 && theKey <= XK_z)
438 {
439 return Aspect_VKey(theKey - XK_a + Aspect_VKey_A);
440 }
441
442 if (theKey >= XK_F1
443 && theKey <= XK_F24)
444 {
445 if (theKey <= XK_F12)
446 {
447 return Aspect_VKey(theKey - XK_F1 + Aspect_VKey_F1);
448 }
449 return Aspect_VKey_UNKNOWN;
450 }
451
452 switch (theKey)
453 {
454 case XK_space:
455 return Aspect_VKey_Space;
456 case XK_apostrophe:
457 return Aspect_VKey_Apostrophe;
458 case XK_comma:
459 return Aspect_VKey_Comma;
460 case XK_minus:
461 return Aspect_VKey_Minus;
462 case XK_period:
463 return Aspect_VKey_Period;
464 case XK_semicolon:
465 return Aspect_VKey_Semicolon;
466 case XK_equal:
467 return Aspect_VKey_Equal;
468 case XK_bracketleft:
469 return Aspect_VKey_BracketLeft;
470 case XK_backslash:
471 return Aspect_VKey_Backslash;
472 case XK_bracketright:
473 return Aspect_VKey_BracketRight;
474 case XK_BackSpace:
475 return Aspect_VKey_Backspace;
476 case XK_Tab:
477 return Aspect_VKey_Tab;
478 //case XK_Linefeed:
479 case XK_Return:
480 case XK_KP_Enter:
481 return Aspect_VKey_Enter;
482 //case XK_Pause:
483 // return Aspect_VKey_Pause;
484 case XK_Escape:
485 return Aspect_VKey_Escape;
486 case XK_Home:
487 return Aspect_VKey_Home;
488 case XK_Left:
489 return Aspect_VKey_Left;
490 case XK_Up:
491 return Aspect_VKey_Up;
492 case XK_Right:
493 return Aspect_VKey_Right;
494 case XK_Down:
495 return Aspect_VKey_Down;
496 case XK_Prior:
497 return Aspect_VKey_PageUp;
498 case XK_Next:
499 return Aspect_VKey_PageDown;
500 case XK_End:
501 return Aspect_VKey_End;
502 //case XK_Insert:
503 // return Aspect_VKey_Insert;
504 case XK_Menu:
505 return Aspect_VKey_Menu;
506 case XK_Num_Lock:
507 return Aspect_VKey_Numlock;
508 //case XK_KP_Delete:
509 // return Aspect_VKey_NumDelete;
510 case XK_KP_Multiply:
511 return Aspect_VKey_NumpadMultiply;
512 case XK_KP_Add:
513 return Aspect_VKey_NumpadAdd;
514 //case XK_KP_Separator:
515 // return Aspect_VKey_Separator;
516 case XK_KP_Subtract:
517 return Aspect_VKey_NumpadSubtract;
518 //case XK_KP_Decimal:
519 // return Aspect_VKey_Decimal;
520 case XK_KP_Divide:
521 return Aspect_VKey_NumpadDivide;
522 case XK_Shift_L:
523 case XK_Shift_R:
524 return Aspect_VKey_Shift;
525 case XK_Control_L:
526 case XK_Control_R:
527 return Aspect_VKey_Control;
528 //case XK_Caps_Lock:
529 // return Aspect_VKey_CapsLock;
530 case XK_Alt_L:
531 case XK_Alt_R:
532 return Aspect_VKey_Alt;
533 //case XK_Super_L:
534 //case XK_Super_R:
535 // return Aspect_VKey_Super;
536 case XK_Delete:
537 return Aspect_VKey_Delete;
538
539 case 0x1008FF11: // XF86AudioLowerVolume
540 return Aspect_VKey_VolumeDown;
541 case 0x1008FF12: // XF86AudioMute
542 return Aspect_VKey_VolumeMute;
543 case 0x1008FF13: // XF86AudioRaiseVolume
544 return Aspect_VKey_VolumeUp;
545
546 case 0x1008FF14: // XF86AudioPlay
547 return Aspect_VKey_MediaPlayPause;
548 case 0x1008FF15: // XF86AudioStop
549 return Aspect_VKey_MediaStop;
550 case 0x1008FF16: // XF86AudioPrev
551 return Aspect_VKey_MediaPreviousTrack;
552 case 0x1008FF17: // XF86AudioNext
553 return Aspect_VKey_MediaNextTrack;
554
555 case 0x1008FF18: // XF86HomePage
556 return Aspect_VKey_BrowserHome;
557 case 0x1008FF26: // XF86Back
558 return Aspect_VKey_BrowserBack;
559 case 0x1008FF27: // XF86Forward
560 return Aspect_VKey_BrowserForward;
561 case 0x1008FF28: // XF86Stop
562 return Aspect_VKey_BrowserStop;
563 case 0x1008FF29: // XF86Refresh
564 return Aspect_VKey_BrowserRefresh;
565 }
b69e576a 566#else
567 (void )theKey;
568#endif
49582f9d 569 return Aspect_VKey_UNKNOWN;
570}
571
e8e157df 572// =======================================================================
573// function : ProcessMessage
574// purpose :
575// =======================================================================
576bool Xw_Window::ProcessMessage (Aspect_WindowInputListener& theListener,
b69e576a 577 XEvent&
578 #if defined(HAVE_XLIB) // msvc before VS2015 had problems with (void )theMsg
579 theMsg
580 #endif
581 )
e8e157df 582{
b69e576a 583#if defined(HAVE_XLIB)
e8e157df 584 Display* aDisplay = myDisplay->GetDisplay();
585
586 // Handle event for the chosen display connection
587 switch (theMsg.type)
588 {
589 case ClientMessage:
590 {
591 if ((Atom)theMsg.xclient.data.l[0] == myDisplay->GetAtom (Aspect_XA_DELETE_WINDOW)
b69e576a 592 && theMsg.xclient.window == (Window )myXWindow)
e8e157df 593 {
594 theListener.ProcessClose();
595 return true;
596 }
597 return false;
598 }
599 case FocusIn:
600 case FocusOut:
601 {
b69e576a 602 if (theMsg.xfocus.window == (Window )myXWindow)
e8e157df 603 {
604 theListener.ProcessFocus (theMsg.type == FocusIn);
605 }
606 return true;
607 }
608 case Expose:
609 {
b69e576a 610 if (theMsg.xexpose.window == (Window )myXWindow)
e8e157df 611 {
612 theListener.ProcessExpose();
613 }
614
615 // remove all the ExposureMask and process them at once
616 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
617 {
b69e576a 618 if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, ExposureMask, &theMsg))
e8e157df 619 {
620 break;
621 }
622 }
623
624 return true;
625 }
626 case ConfigureNotify:
627 {
628 // remove all the StructureNotifyMask and process them at once
629 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
630 {
b69e576a 631 if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, StructureNotifyMask, &theMsg))
e8e157df 632 {
633 break;
634 }
635 }
636
b69e576a 637 if (theMsg.xconfigure.window == (Window )myXWindow)
e8e157df 638 {
639 theListener.ProcessConfigure (true);
640 }
641 return true;
642 }
643 case KeyPress:
644 case KeyRelease:
645 {
646 XKeyEvent* aKeyEvent = (XKeyEvent* )&theMsg;
647 const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
648 const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
649 if (aVKey != Aspect_VKey_UNKNOWN)
650 {
651 const double aTimeStamp = theListener.EventTime();
652 if (theMsg.type == KeyPress)
653 {
654 theListener.KeyDown (aVKey, aTimeStamp);
655 }
656 else
657 {
658 theListener.KeyUp (aVKey, aTimeStamp);
659 }
660 theListener.ProcessInput();
661 }
662 return true;
663 }
664 case ButtonPress:
665 case ButtonRelease:
666 {
667 const Graphic3d_Vec2i aPos (theMsg.xbutton.x, theMsg.xbutton.y);
668 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
669 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
670 if (theMsg.xbutton.button == Button1) { aButton = Aspect_VKeyMouse_LeftButton; }
671 if (theMsg.xbutton.button == Button2) { aButton = Aspect_VKeyMouse_MiddleButton; }
672 if (theMsg.xbutton.button == Button3) { aButton = Aspect_VKeyMouse_RightButton; }
673
674 if ((theMsg.xbutton.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
675 if ((theMsg.xbutton.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
676 if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
677 {
678 aFlags |= Aspect_VKeyFlags_ALT;
679 }
680
681 if (theMsg.xbutton.button == Button4
682 || theMsg.xbutton.button == Button5)
683 {
684 if (theMsg.type != ButtonPress)
685 {
686 return true;
687 }
688
689 const double aDeltaF = (theMsg.xbutton.button == Button4 ? 1.0 : -1.0);
690 theListener.UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
691 }
692 else if (theMsg.type == ButtonPress)
693 {
694 theListener.PressMouseButton (aPos, aButton, aFlags, false);
695 }
696 else
697 {
698 theListener.ReleaseMouseButton (aPos, aButton, aFlags, false);
699 }
700 theListener.ProcessInput();
701 return true;
702 }
703 case MotionNotify:
704 {
b69e576a 705 if (theMsg.xmotion.window != (Window )myXWindow)
e8e157df 706 {
707 return false;
708 }
709
710 // remove all the ButtonMotionMask and process them at once
711 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
712 {
b69e576a 713 if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, ButtonMotionMask | PointerMotionMask, &theMsg))
e8e157df 714 {
715 break;
716 }
717 }
718
719 Graphic3d_Vec2i aPos (theMsg.xmotion.x, theMsg.xmotion.y);
720 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
721 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
722 if ((theMsg.xmotion.state & Button1Mask) != 0) { aButtons |= Aspect_VKeyMouse_LeftButton; }
723 if ((theMsg.xmotion.state & Button2Mask) != 0) { aButtons |= Aspect_VKeyMouse_MiddleButton; }
724 if ((theMsg.xmotion.state & Button3Mask) != 0) { aButtons |= Aspect_VKeyMouse_RightButton; }
725
726 if ((theMsg.xmotion.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
727 if ((theMsg.xmotion.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
728 if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
729 {
730 aFlags |= Aspect_VKeyFlags_ALT;
731 }
732
733 theListener.UpdateMousePosition (aPos, aButtons, aFlags, false);
734 theListener.ProcessInput();
735 return true;
736 }
737 }
b69e576a 738#else
739 (void )theListener;
740#endif
e8e157df 741 return false;
742}