1 // Created on: 2013-04-06
2 // Created by: Kirill Gavrilov
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Xw_Window.hxx>
18 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__)
20 #include <Aspect_Convert.hxx>
21 #include <Aspect_WindowDefinitionError.hxx>
22 #include <Message.hxx>
23 #include <Message_Messenger.hxx>
25 #if defined(HAVE_EGL) || defined(HAVE_GLES2)
33 //! Search for RGBA double-buffered visual with stencil buffer.
34 static int TheDoubleBuffVisual[] =
43 //! Search for RGBA double-buffered visual with stencil buffer.
44 static int TheDoubleBuffFBConfig[] =
46 GLX_X_RENDERABLE, True,
47 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
48 GLX_RENDER_TYPE, GLX_RGBA_BIT,
49 GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
52 GLX_DOUBLEBUFFER, True,
60 IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
62 // =======================================================================
63 // function : Xw_Window
65 // =======================================================================
66 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
67 const Standard_CString theTitle,
68 const Standard_Integer thePxLeft,
69 const Standard_Integer thePxTop,
70 const Standard_Integer thePxWidth,
71 const Standard_Integer thePxHeight,
72 const Aspect_FBConfig theFBConfig)
74 myDisplay (theXDisplay),
76 myFBConfig (theFBConfig),
79 myXRight (thePxLeft + thePxWidth),
80 myYBottom (thePxTop + thePxHeight),
81 myIsOwnWin (Standard_True)
83 if (thePxWidth <= 0 || thePxHeight <= 0)
85 throw Aspect_WindowDefinitionError("Xw_Window, Coordinate(s) out of range");
87 else if (theXDisplay.IsNull())
89 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
93 Display* aDisp = myDisplay->GetDisplay();
94 int aScreen = DefaultScreen(aDisp);
95 Window aParent = RootWindow (aDisp, aScreen);
96 XVisualInfo* aVisInfo = NULL;
98 #if defined(HAVE_EGL) || defined(HAVE_GLES2)
99 EGLDisplay anEglDisplay = eglGetDisplay (aDisp);
100 EGLint aVerMajor = 0; EGLint aVerMinor = 0;
101 XVisualInfo aVisInfoTmp; memset (&aVisInfoTmp, 0, sizeof(aVisInfoTmp));
102 if (anEglDisplay != EGL_NO_DISPLAY
103 && eglInitialize (anEglDisplay, &aVerMajor, &aVerMinor) == EGL_TRUE)
105 EGLint aConfigAttribs[] =
113 #if defined(HAVE_GLES2)
114 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
116 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
121 EGLint aNbConfigs = 0;
122 void* anEglConfig = NULL;
123 if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) != EGL_TRUE
124 || anEglConfig == NULL)
127 aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
128 if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) != EGL_TRUE
129 || anEglConfig == NULL)
135 if (anEglConfig != NULL
136 && eglGetConfigAttrib (anEglDisplay, anEglConfig, EGL_NATIVE_VISUAL_ID, (EGLint* )&aVisInfoTmp.visualid) == EGL_TRUE)
139 aVisInfoTmp.screen = DefaultScreen (aDisp);
140 aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbVisuals);
143 if (aVisInfo == NULL)
145 Message::DefaultMessenger()->Send ("Warning: cannot choose Visual using EGL while creating Xw_Window", Message_Warning);
149 if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
151 throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable");
154 if (myFBConfig == NULL)
156 // FBConfigs were added in GLX version 1.3
159 const bool hasFBCfg = glXQueryVersion (aDisp, &aGlxMajor, &aGlxMinor)
160 && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1));
164 GLXFBConfig* aFBCfgList = NULL;
167 aFBCfgList = glXChooseFBConfig (aDisp, aScreen, TheDoubleBuffFBConfig, &aFBCount);
169 if(aFBCfgList != NULL
172 myFBConfig = aFBCfgList[0];
173 aVisInfo = glXGetVisualFromFBConfig (aDisp, myFBConfig);
179 if (aVisInfo == NULL)
181 aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuffVisual);
183 if (aVisInfo == NULL)
185 throw Aspect_WindowDefinitionError("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
190 unsigned long aMask = 0;
191 XSetWindowAttributes aWinAttr;
192 memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
193 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
194 aMask |= CWEventMask;
195 if (aVisInfo != NULL)
197 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
199 aWinAttr.border_pixel = 0;
200 aWinAttr.override_redirect = False;
202 myXWindow = XCreateWindow(aDisp, aParent,
203 myXLeft, myYTop, thePxWidth, thePxHeight,
204 0, aVisInfo != NULL ? aVisInfo->depth : CopyFromParent,
206 aVisInfo != NULL ? aVisInfo->visual : CopyFromParent,
207 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
208 if (aVisInfo != NULL)
215 throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window");
219 // if parent - desktop
220 XSizeHints aSizeHints;
221 aSizeHints.x = myXLeft;
222 aSizeHints.y = myYTop;
223 aSizeHints.flags = PPosition;
224 aSizeHints.width = thePxWidth;
225 aSizeHints.height = thePxHeight;
226 aSizeHints.flags |= PSize;
227 XSetStandardProperties (aDisp, myXWindow, theTitle, theTitle, None,
228 NULL, 0, &aSizeHints);
230 /*XTextProperty aTitleProperty;
231 aTitleProperty.encoding = None;
232 char* aTitle = (char* )theTitle;
233 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
234 XSetWMName (aDisp, myXWindow, &aTitleProperty);
235 XSetWMProperties(aDisp, myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
240 // =======================================================================
241 // function : Xw_Window
243 // =======================================================================
244 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
245 const Window theXWin,
246 const Aspect_FBConfig theFBConfig)
248 myDisplay (theXDisplay),
250 myFBConfig (theFBConfig),
255 myIsOwnWin (Standard_False)
259 throw Aspect_WindowDefinitionError("Xw_Window, given invalid X window");
262 else if (theXDisplay.IsNull())
264 throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined");
267 #if !defined(HAVE_EGL) && !defined(HAVE_GLES2)
269 if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
272 throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable");
277 Display* aDisp = myDisplay->GetDisplay();
279 XWindowAttributes aWinAttr;
280 XGetWindowAttributes (aDisp, myXWindow, &aWinAttr);
281 XVisualInfo aVisInfoTmp;
282 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
283 aVisInfoTmp.screen = DefaultScreen (aDisp);
285 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbItems);
286 if (aVisInfo == NULL)
288 throw Aspect_WindowDefinitionError("Xw_Window, Visual is unavailable");
296 // =======================================================================
297 // function : ~Xw_Window
299 // =======================================================================
300 Xw_Window::~Xw_Window()
302 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
304 XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
308 // =======================================================================
309 // function : XWindow
311 // =======================================================================
312 Window Xw_Window::XWindow() const
317 // =======================================================================
318 // function : IsMapped
320 // =======================================================================
321 Standard_Boolean Xw_Window::IsMapped() const
327 else if (IsVirtual())
329 return Standard_True;
332 XFlush (myDisplay->GetDisplay());
333 XWindowAttributes aWinAttr;
334 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
335 return aWinAttr.map_state == IsUnviewable
336 || aWinAttr.map_state == IsViewable;
339 // =======================================================================
342 // =======================================================================
343 void Xw_Window::Map() const
345 if (IsVirtual() || myXWindow == 0)
350 XMapWindow (myDisplay->GetDisplay(), myXWindow);
351 XFlush (myDisplay->GetDisplay());
354 // =======================================================================
357 // =======================================================================
358 void Xw_Window::Unmap() const
360 if (IsVirtual() || myXWindow == 0)
365 XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
368 // =======================================================================
369 // function : DoResize
371 // =======================================================================
372 Aspect_TypeOfResize Xw_Window::DoResize() const
376 return Aspect_TOR_UNKNOWN;
379 XFlush (myDisplay->GetDisplay());
380 XWindowAttributes aWinAttr;
381 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
382 if (aWinAttr.map_state == IsUnmapped)
384 return Aspect_TOR_UNKNOWN;
387 Standard_Integer aMask = 0;
388 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
390 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
391 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
392 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
393 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
396 case 0: aMode = Aspect_TOR_NO_BORDER; break;
397 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
398 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
399 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
400 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
401 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
402 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
403 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
404 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
408 *((Standard_Integer* )&myXLeft ) = aWinAttr.x;
409 *((Standard_Integer* )&myXRight ) = aWinAttr.x + aWinAttr.width;
410 *((Standard_Integer* )&myYTop ) = aWinAttr.y;
411 *((Standard_Integer* )&myYBottom ) = aWinAttr.y + aWinAttr.height;
415 // =======================================================================
416 // function : DoMapping
418 // =======================================================================
419 Standard_Boolean Xw_Window::DoMapping() const
421 return Standard_True; // IsMapped()
424 // =======================================================================
427 // =======================================================================
428 Standard_Real Xw_Window::Ratio() const
435 XFlush (myDisplay->GetDisplay());
436 XWindowAttributes aWinAttr;
437 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
438 return Standard_Real(aWinAttr.width) / Standard_Real(aWinAttr.height);
441 // =======================================================================
442 // function : Position
444 // =======================================================================
445 void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
446 Standard_Integer& X2, Standard_Integer& Y2) const
453 XFlush (myDisplay->GetDisplay());
454 XWindowAttributes anAttributes;
455 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
457 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
458 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
460 X1 = -anAttributes.x;
461 X2 = X1 + anAttributes.width;
462 Y1 = -anAttributes.y;
463 Y2 = Y1 + anAttributes.height;
466 // =======================================================================
469 // =======================================================================
470 void Xw_Window::Size (Standard_Integer& theWidth,
471 Standard_Integer& theHeight) const
478 XFlush (myDisplay->GetDisplay());
479 XWindowAttributes aWinAttr;
480 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
481 theWidth = aWinAttr.width;
482 theHeight = aWinAttr.height;
485 #endif // Win32 or Mac OS X