mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
739 lines
22 KiB
C++
739 lines
22 KiB
C++
// Created on: 2013-04-06
|
|
// Created by: Kirill Gavrilov
|
|
// Copyright (c) 2013-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <Xw_Window.hxx>
|
|
|
|
#include <Aspect_ScrollDelta.hxx>
|
|
#include <Aspect_WindowDefinitionError.hxx>
|
|
#include <Aspect_WindowInputListener.hxx>
|
|
#include <Message.hxx>
|
|
|
|
#if defined(HAVE_XLIB)
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
//#include <X11/XF86keysym.h>
|
|
#endif
|
|
|
|
#include <Aspect_DisplayConnection.hxx>
|
|
|
|
IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
|
|
|
|
// =======================================================================
|
|
// function : Xw_Window
|
|
// purpose :
|
|
// =======================================================================
|
|
Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
|
|
const Standard_CString theTitle,
|
|
const Standard_Integer thePxLeft,
|
|
const Standard_Integer thePxTop,
|
|
const Standard_Integer thePxWidth,
|
|
const Standard_Integer thePxHeight)
|
|
: Aspect_Window(),
|
|
myXWindow (0),
|
|
myFBConfig (NULL),
|
|
myXLeft (thePxLeft),
|
|
myYTop (thePxTop),
|
|
myXRight (thePxLeft + thePxWidth),
|
|
myYBottom (thePxTop + thePxHeight),
|
|
myIsOwnWin (Standard_True)
|
|
{
|
|
myDisplay = theXDisplay;
|
|
if (thePxWidth <= 0 || thePxHeight <= 0)
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, Coordinate(s) out of range");
|
|
}
|
|
else if (theXDisplay.IsNull())
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
myFBConfig = theXDisplay->GetDefaultFBConfig();
|
|
XVisualInfo* aVisInfo = theXDisplay->GetDefaultVisualInfoX();
|
|
|
|
Display* aDisp = myDisplay->GetDisplay();
|
|
int aScreen = DefaultScreen(aDisp);
|
|
Window aParent = RootWindow (aDisp, aScreen);
|
|
|
|
XSetWindowAttributes aWinAttr;
|
|
memset (&aWinAttr, 0, sizeof(aWinAttr));
|
|
aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
|
|
|
|
if (aVisInfo != NULL)
|
|
{
|
|
aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
|
|
}
|
|
aWinAttr.border_pixel = 0;
|
|
aWinAttr.override_redirect = False;
|
|
|
|
myXWindow = (Window )XCreateWindow (aDisp, aParent,
|
|
myXLeft, myYTop, thePxWidth, thePxHeight,
|
|
0, aVisInfo != NULL ? aVisInfo->depth : CopyFromParent,
|
|
InputOutput,
|
|
aVisInfo != NULL ? aVisInfo->visual : CopyFromParent,
|
|
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
|
|
if (myXWindow == 0)
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window");
|
|
}
|
|
|
|
// if parent - desktop
|
|
XSizeHints aSizeHints;
|
|
aSizeHints.x = myXLeft;
|
|
aSizeHints.y = myYTop;
|
|
aSizeHints.flags = PPosition;
|
|
aSizeHints.width = thePxWidth;
|
|
aSizeHints.height = thePxHeight;
|
|
aSizeHints.flags |= PSize;
|
|
XSetStandardProperties (aDisp, (Window )myXWindow, theTitle, theTitle, None,
|
|
NULL, 0, &aSizeHints);
|
|
|
|
/*XTextProperty aTitleProperty;
|
|
aTitleProperty.encoding = None;
|
|
char* aTitle = (char* )theTitle;
|
|
Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
|
|
XSetWMName (aDisp, (Window )myXWindow, &aTitleProperty);
|
|
XSetWMProperties(aDisp, (Window )myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
|
|
|
|
XFlush (aDisp);
|
|
#else
|
|
(void )theTitle;
|
|
if (myXWindow == 0)
|
|
{
|
|
throw Aspect_WindowDefinitionError ("Xw_Window, Unable to create window - not implemented");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Xw_Window
|
|
// purpose :
|
|
// =======================================================================
|
|
Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
|
|
const Aspect_Drawable theXWin,
|
|
const Aspect_FBConfig theFBConfig)
|
|
: Aspect_Window(),
|
|
myXWindow (theXWin),
|
|
myFBConfig (theFBConfig),
|
|
myXLeft (0),
|
|
myYTop (0),
|
|
myXRight (512),
|
|
myYBottom (512),
|
|
myIsOwnWin (Standard_False)
|
|
{
|
|
myDisplay = theXDisplay;
|
|
if (theXWin == 0)
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, given invalid X window");
|
|
}
|
|
else if (theXDisplay.IsNull())
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
Display* aDisp = myDisplay->GetDisplay();
|
|
|
|
XWindowAttributes aWinAttr;
|
|
XGetWindowAttributes (aDisp, (Window )myXWindow, &aWinAttr);
|
|
XVisualInfo aVisInfoTmp;
|
|
aVisInfoTmp.visualid = aWinAttr.visual->visualid;
|
|
aVisInfoTmp.screen = DefaultScreen (aDisp);
|
|
int aNbItems = 0;
|
|
XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbItems);
|
|
if (aVisInfo == NULL)
|
|
{
|
|
throw Aspect_WindowDefinitionError("Xw_Window, Visual is unavailable");
|
|
}
|
|
XFree (aVisInfo);
|
|
|
|
DoResize();
|
|
#else
|
|
//throw Standard_NotImplemented("Xw_Window, not implemented");
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~Xw_Window
|
|
// purpose :
|
|
// =======================================================================
|
|
Xw_Window::~Xw_Window()
|
|
{
|
|
if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
|
|
{
|
|
#if defined(HAVE_XLIB)
|
|
XDestroyWindow (myDisplay->GetDisplay(), (Window )myXWindow);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : IsMapped
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean Xw_Window::IsMapped() const
|
|
{
|
|
if (myXWindow == 0)
|
|
{
|
|
return false;
|
|
}
|
|
else if (IsVirtual())
|
|
{
|
|
return Standard_True;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush (myDisplay->GetDisplay());
|
|
XWindowAttributes aWinAttr;
|
|
XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
|
|
return aWinAttr.map_state == IsUnviewable
|
|
|| aWinAttr.map_state == IsViewable;
|
|
#else
|
|
return Standard_False;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Map
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::Map() const
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XMapWindow (myDisplay->GetDisplay(), (Window )myXWindow);
|
|
XFlush (myDisplay->GetDisplay());
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Unmap
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::Unmap() const
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XIconifyWindow (myDisplay->GetDisplay(), (Window )myXWindow, DefaultScreen(myDisplay->GetDisplay()));
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : DoResize
|
|
// purpose :
|
|
// =======================================================================
|
|
Aspect_TypeOfResize Xw_Window::DoResize()
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
return Aspect_TOR_UNKNOWN;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush (myDisplay->GetDisplay());
|
|
XWindowAttributes aWinAttr;
|
|
memset (&aWinAttr, 0, sizeof(aWinAttr));
|
|
XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
|
|
if (aWinAttr.map_state == IsUnmapped)
|
|
{
|
|
return Aspect_TOR_UNKNOWN;
|
|
}
|
|
|
|
Standard_Integer aMask = 0;
|
|
Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
|
|
|
|
if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
|
|
if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
|
|
if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
|
|
if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
|
|
switch (aMask)
|
|
{
|
|
case 0: aMode = Aspect_TOR_NO_BORDER; break;
|
|
case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
|
|
case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
|
|
case 4: aMode = Aspect_TOR_TOP_BORDER; break;
|
|
case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
|
|
case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
|
|
case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
|
|
case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
|
|
case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
|
|
default: break;
|
|
}
|
|
|
|
myXLeft = aWinAttr.x;
|
|
myXRight = aWinAttr.x + aWinAttr.width;
|
|
myYTop = aWinAttr.y;
|
|
myYBottom = aWinAttr.y + aWinAttr.height;
|
|
return aMode;
|
|
#else
|
|
return Aspect_TOR_UNKNOWN;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Ratio
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Real Xw_Window::Ratio() const
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
return Standard_Real(myXRight - myXLeft) / Standard_Real(myYBottom - myYTop);
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush (myDisplay->GetDisplay());
|
|
XWindowAttributes aWinAttr;
|
|
memset (&aWinAttr, 0, sizeof(aWinAttr));
|
|
XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
|
|
return Standard_Real(aWinAttr.width) / Standard_Real(aWinAttr.height);
|
|
#else
|
|
return 1.0;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Position
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1,
|
|
Standard_Integer& theX2, Standard_Integer& theY2) const
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
theX1 = myXLeft;
|
|
theX2 = myXRight;
|
|
theY1 = myYTop;
|
|
theY2 = myYBottom;
|
|
return;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush (myDisplay->GetDisplay());
|
|
XWindowAttributes anAttributes;
|
|
memset (&anAttributes, 0, sizeof(anAttributes));
|
|
XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &anAttributes);
|
|
Window aChild;
|
|
XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, (Window )myXWindow,
|
|
0, 0, &anAttributes.x, &anAttributes.y, &aChild);
|
|
|
|
theX1 = -anAttributes.x;
|
|
theX2 = theX1 + anAttributes.width;
|
|
theY1 = -anAttributes.y;
|
|
theY2 = theY1 + anAttributes.height;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Size
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::Size (Standard_Integer& theWidth,
|
|
Standard_Integer& theHeight) const
|
|
{
|
|
if (IsVirtual() || myXWindow == 0)
|
|
{
|
|
theWidth = myXRight - myXLeft;
|
|
theHeight = myYBottom - myYTop;
|
|
return;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush (myDisplay->GetDisplay());
|
|
XWindowAttributes aWinAttr;
|
|
memset (&aWinAttr, 0, sizeof(aWinAttr));
|
|
XGetWindowAttributes (myDisplay->GetDisplay(), (Window )myXWindow, &aWinAttr);
|
|
theWidth = aWinAttr.width;
|
|
theHeight = aWinAttr.height;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetTitle
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::SetTitle (const TCollection_AsciiString& theTitle)
|
|
{
|
|
if (myXWindow != 0)
|
|
{
|
|
#if defined(HAVE_XLIB)
|
|
XStoreName (myDisplay->GetDisplay(), (Window )myXWindow, theTitle.ToCString());
|
|
#else
|
|
(void )theTitle;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : InvalidateContent
|
|
// purpose :
|
|
// =======================================================================
|
|
void Xw_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp)
|
|
{
|
|
if (myXWindow == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
const Handle(Aspect_DisplayConnection)& aDisp = !theDisp.IsNull() ? theDisp : myDisplay;
|
|
Display* aDispX = aDisp->GetDisplay();
|
|
|
|
XEvent anEvent;
|
|
memset (&anEvent, 0, sizeof(anEvent));
|
|
anEvent.type = Expose;
|
|
anEvent.xexpose.window = (Window )myXWindow;
|
|
XSendEvent (aDispX, (Window )myXWindow, False, ExposureMask, &anEvent);
|
|
XFlush (aDispX);
|
|
#else
|
|
(void )theDisp;
|
|
#endif
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : VirtualKeyFromNative
|
|
// purpose :
|
|
// =======================================================================
|
|
Aspect_VKey Xw_Window::VirtualKeyFromNative (unsigned long theKey)
|
|
{
|
|
#if defined(HAVE_XLIB)
|
|
if (theKey >= XK_0
|
|
&& theKey <= XK_9)
|
|
{
|
|
return Aspect_VKey(theKey - XK_0 + Aspect_VKey_0);
|
|
}
|
|
|
|
if (theKey >= XK_A
|
|
&& theKey <= XK_Z)
|
|
{
|
|
return Aspect_VKey(theKey - XK_A + Aspect_VKey_A);
|
|
}
|
|
|
|
if (theKey >= XK_a
|
|
&& theKey <= XK_z)
|
|
{
|
|
return Aspect_VKey(theKey - XK_a + Aspect_VKey_A);
|
|
}
|
|
|
|
if (theKey >= XK_F1
|
|
&& theKey <= XK_F24)
|
|
{
|
|
if (theKey <= XK_F12)
|
|
{
|
|
return Aspect_VKey(theKey - XK_F1 + Aspect_VKey_F1);
|
|
}
|
|
return Aspect_VKey_UNKNOWN;
|
|
}
|
|
|
|
switch (theKey)
|
|
{
|
|
case XK_space:
|
|
return Aspect_VKey_Space;
|
|
case XK_apostrophe:
|
|
return Aspect_VKey_Apostrophe;
|
|
case XK_comma:
|
|
return Aspect_VKey_Comma;
|
|
case XK_minus:
|
|
return Aspect_VKey_Minus;
|
|
case XK_period:
|
|
return Aspect_VKey_Period;
|
|
case XK_semicolon:
|
|
return Aspect_VKey_Semicolon;
|
|
case XK_equal:
|
|
return Aspect_VKey_Equal;
|
|
case XK_bracketleft:
|
|
return Aspect_VKey_BracketLeft;
|
|
case XK_backslash:
|
|
return Aspect_VKey_Backslash;
|
|
case XK_bracketright:
|
|
return Aspect_VKey_BracketRight;
|
|
case XK_BackSpace:
|
|
return Aspect_VKey_Backspace;
|
|
case XK_Tab:
|
|
return Aspect_VKey_Tab;
|
|
//case XK_Linefeed:
|
|
case XK_Return:
|
|
case XK_KP_Enter:
|
|
return Aspect_VKey_Enter;
|
|
//case XK_Pause:
|
|
// return Aspect_VKey_Pause;
|
|
case XK_Escape:
|
|
return Aspect_VKey_Escape;
|
|
case XK_Home:
|
|
return Aspect_VKey_Home;
|
|
case XK_Left:
|
|
return Aspect_VKey_Left;
|
|
case XK_Up:
|
|
return Aspect_VKey_Up;
|
|
case XK_Right:
|
|
return Aspect_VKey_Right;
|
|
case XK_Down:
|
|
return Aspect_VKey_Down;
|
|
case XK_Prior:
|
|
return Aspect_VKey_PageUp;
|
|
case XK_Next:
|
|
return Aspect_VKey_PageDown;
|
|
case XK_End:
|
|
return Aspect_VKey_End;
|
|
//case XK_Insert:
|
|
// return Aspect_VKey_Insert;
|
|
case XK_Menu:
|
|
return Aspect_VKey_Menu;
|
|
case XK_Num_Lock:
|
|
return Aspect_VKey_Numlock;
|
|
//case XK_KP_Delete:
|
|
// return Aspect_VKey_NumDelete;
|
|
case XK_KP_Multiply:
|
|
return Aspect_VKey_NumpadMultiply;
|
|
case XK_KP_Add:
|
|
return Aspect_VKey_NumpadAdd;
|
|
//case XK_KP_Separator:
|
|
// return Aspect_VKey_Separator;
|
|
case XK_KP_Subtract:
|
|
return Aspect_VKey_NumpadSubtract;
|
|
//case XK_KP_Decimal:
|
|
// return Aspect_VKey_Decimal;
|
|
case XK_KP_Divide:
|
|
return Aspect_VKey_NumpadDivide;
|
|
case XK_Shift_L:
|
|
case XK_Shift_R:
|
|
return Aspect_VKey_Shift;
|
|
case XK_Control_L:
|
|
case XK_Control_R:
|
|
return Aspect_VKey_Control;
|
|
//case XK_Caps_Lock:
|
|
// return Aspect_VKey_CapsLock;
|
|
case XK_Alt_L:
|
|
case XK_Alt_R:
|
|
return Aspect_VKey_Alt;
|
|
//case XK_Super_L:
|
|
//case XK_Super_R:
|
|
// return Aspect_VKey_Super;
|
|
case XK_Delete:
|
|
return Aspect_VKey_Delete;
|
|
|
|
case 0x1008FF11: // XF86AudioLowerVolume
|
|
return Aspect_VKey_VolumeDown;
|
|
case 0x1008FF12: // XF86AudioMute
|
|
return Aspect_VKey_VolumeMute;
|
|
case 0x1008FF13: // XF86AudioRaiseVolume
|
|
return Aspect_VKey_VolumeUp;
|
|
|
|
case 0x1008FF14: // XF86AudioPlay
|
|
return Aspect_VKey_MediaPlayPause;
|
|
case 0x1008FF15: // XF86AudioStop
|
|
return Aspect_VKey_MediaStop;
|
|
case 0x1008FF16: // XF86AudioPrev
|
|
return Aspect_VKey_MediaPreviousTrack;
|
|
case 0x1008FF17: // XF86AudioNext
|
|
return Aspect_VKey_MediaNextTrack;
|
|
|
|
case 0x1008FF18: // XF86HomePage
|
|
return Aspect_VKey_BrowserHome;
|
|
case 0x1008FF26: // XF86Back
|
|
return Aspect_VKey_BrowserBack;
|
|
case 0x1008FF27: // XF86Forward
|
|
return Aspect_VKey_BrowserForward;
|
|
case 0x1008FF28: // XF86Stop
|
|
return Aspect_VKey_BrowserStop;
|
|
case 0x1008FF29: // XF86Refresh
|
|
return Aspect_VKey_BrowserRefresh;
|
|
}
|
|
#else
|
|
(void )theKey;
|
|
#endif
|
|
return Aspect_VKey_UNKNOWN;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ProcessMessage
|
|
// purpose :
|
|
// =======================================================================
|
|
bool Xw_Window::ProcessMessage (Aspect_WindowInputListener& theListener,
|
|
XEvent&
|
|
#if defined(HAVE_XLIB) // msvc before VS2015 had problems with (void )theMsg
|
|
theMsg
|
|
#endif
|
|
)
|
|
{
|
|
#if defined(HAVE_XLIB)
|
|
Display* aDisplay = myDisplay->GetDisplay();
|
|
|
|
// Handle event for the chosen display connection
|
|
switch (theMsg.type)
|
|
{
|
|
case ClientMessage:
|
|
{
|
|
if ((Atom)theMsg.xclient.data.l[0] == myDisplay->GetAtom (Aspect_XA_DELETE_WINDOW)
|
|
&& theMsg.xclient.window == (Window )myXWindow)
|
|
{
|
|
theListener.ProcessClose();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
case FocusIn:
|
|
case FocusOut:
|
|
{
|
|
if (theMsg.xfocus.window == (Window )myXWindow)
|
|
{
|
|
theListener.ProcessFocus (theMsg.type == FocusIn);
|
|
}
|
|
return true;
|
|
}
|
|
case Expose:
|
|
{
|
|
if (theMsg.xexpose.window == (Window )myXWindow)
|
|
{
|
|
theListener.ProcessExpose();
|
|
}
|
|
|
|
// remove all the ExposureMask and process them at once
|
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
{
|
|
if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, ExposureMask, &theMsg))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
case ConfigureNotify:
|
|
{
|
|
// remove all the StructureNotifyMask and process them at once
|
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
{
|
|
if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, StructureNotifyMask, &theMsg))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (theMsg.xconfigure.window == (Window )myXWindow)
|
|
{
|
|
theListener.ProcessConfigure (true);
|
|
}
|
|
return true;
|
|
}
|
|
case KeyPress:
|
|
case KeyRelease:
|
|
{
|
|
XKeyEvent* aKeyEvent = (XKeyEvent* )&theMsg;
|
|
const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
|
|
const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
|
|
if (aVKey != Aspect_VKey_UNKNOWN)
|
|
{
|
|
const double aTimeStamp = theListener.EventTime();
|
|
if (theMsg.type == KeyPress)
|
|
{
|
|
theListener.KeyDown (aVKey, aTimeStamp);
|
|
}
|
|
else
|
|
{
|
|
theListener.KeyUp (aVKey, aTimeStamp);
|
|
}
|
|
theListener.ProcessInput();
|
|
}
|
|
return true;
|
|
}
|
|
case ButtonPress:
|
|
case ButtonRelease:
|
|
{
|
|
const Graphic3d_Vec2i aPos (theMsg.xbutton.x, theMsg.xbutton.y);
|
|
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
|
Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
|
|
if (theMsg.xbutton.button == Button1) { aButton = Aspect_VKeyMouse_LeftButton; }
|
|
if (theMsg.xbutton.button == Button2) { aButton = Aspect_VKeyMouse_MiddleButton; }
|
|
if (theMsg.xbutton.button == Button3) { aButton = Aspect_VKeyMouse_RightButton; }
|
|
|
|
if ((theMsg.xbutton.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
|
|
if ((theMsg.xbutton.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
|
|
if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
|
|
{
|
|
aFlags |= Aspect_VKeyFlags_ALT;
|
|
}
|
|
|
|
if (theMsg.xbutton.button == Button4
|
|
|| theMsg.xbutton.button == Button5)
|
|
{
|
|
if (theMsg.type != ButtonPress)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
const double aDeltaF = (theMsg.xbutton.button == Button4 ? 1.0 : -1.0);
|
|
theListener.UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
|
|
}
|
|
else if (theMsg.type == ButtonPress)
|
|
{
|
|
theListener.PressMouseButton (aPos, aButton, aFlags, false);
|
|
}
|
|
else
|
|
{
|
|
theListener.ReleaseMouseButton (aPos, aButton, aFlags, false);
|
|
}
|
|
theListener.ProcessInput();
|
|
return true;
|
|
}
|
|
case MotionNotify:
|
|
{
|
|
if (theMsg.xmotion.window != (Window )myXWindow)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// remove all the ButtonMotionMask and process them at once
|
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
{
|
|
if (!XCheckWindowEvent (aDisplay, (Window )myXWindow, ButtonMotionMask | PointerMotionMask, &theMsg))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Graphic3d_Vec2i aPos (theMsg.xmotion.x, theMsg.xmotion.y);
|
|
Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
|
|
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
|
if ((theMsg.xmotion.state & Button1Mask) != 0) { aButtons |= Aspect_VKeyMouse_LeftButton; }
|
|
if ((theMsg.xmotion.state & Button2Mask) != 0) { aButtons |= Aspect_VKeyMouse_MiddleButton; }
|
|
if ((theMsg.xmotion.state & Button3Mask) != 0) { aButtons |= Aspect_VKeyMouse_RightButton; }
|
|
|
|
if ((theMsg.xmotion.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
|
|
if ((theMsg.xmotion.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
|
|
if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
|
|
{
|
|
aFlags |= Aspect_VKeyFlags_ALT;
|
|
}
|
|
|
|
theListener.UpdateMousePosition (aPos, aButtons, aFlags, false);
|
|
theListener.ProcessInput();
|
|
return true;
|
|
}
|
|
}
|
|
#else
|
|
(void )theListener;
|
|
#endif
|
|
return false;
|
|
}
|