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>
25 IMPLEMENT_STANDARD_RTTIEXT(Xw_Window,Aspect_Window)
30 //! Search for RGBA double-buffered visual with stencil buffer.
31 static int TheDoubleBuffVisual[] =
40 //! Search for RGBA double-buffered visual with stencil buffer.
41 static int TheDoubleBuffFBConfig[] =
43 GLX_X_RENDERABLE, True,
44 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
45 GLX_RENDER_TYPE, GLX_RGBA_BIT,
46 GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
49 GLX_DOUBLEBUFFER, True,
55 // =======================================================================
56 // function : Xw_Window
58 // =======================================================================
59 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
60 const Standard_CString theTitle,
61 const Standard_Integer thePxLeft,
62 const Standard_Integer thePxTop,
63 const Standard_Integer thePxWidth,
64 const Standard_Integer thePxHeight,
65 const Aspect_FBConfig theFBConfig)
67 myDisplay (theXDisplay),
69 myFBConfig (theFBConfig),
72 myXRight (thePxLeft + thePxWidth),
73 myYBottom (thePxTop + thePxHeight),
74 myIsOwnWin (Standard_True)
77 if (thePxWidth <= 0 || thePxHeight <= 0)
79 Aspect_WindowDefinitionError::Raise ("Xw_Window, Coordinate(s) out of range");
81 else if (theXDisplay.IsNull())
83 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
86 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
88 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
92 Display* aDisp = myDisplay->GetDisplay();
93 int aScreen = DefaultScreen(aDisp);
94 Window aParent = RootWindow (aDisp, aScreen);
95 XVisualInfo* aVisInfo = NULL;
97 if (myFBConfig == NULL)
99 // FBConfigs were added in GLX version 1.3
102 const bool hasFBCfg = glXQueryVersion (aDisp, &aGlxMajor, &aGlxMinor)
103 && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1));
107 GLXFBConfig* aFBCfgList = NULL;
110 aFBCfgList = glXChooseFBConfig (aDisp, aScreen, TheDoubleBuffFBConfig, &aFBCount);
112 if(aFBCfgList != NULL
115 myFBConfig = aFBCfgList[0];
116 aVisInfo = glXGetVisualFromFBConfig (aDisp, myFBConfig);
122 if (aVisInfo == NULL)
124 aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuffVisual);
126 if (aVisInfo == NULL)
128 Aspect_WindowDefinitionError::Raise ("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
132 unsigned long aMask = 0;
133 XSetWindowAttributes aWinAttr;
134 memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
135 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
136 aMask |= CWEventMask;
137 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
138 aWinAttr.border_pixel = 0;
139 aWinAttr.override_redirect = False;
141 myXWindow = XCreateWindow(aDisp, aParent,
142 myXLeft, myYTop, thePxWidth, thePxHeight,
146 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
147 XFree (aVisInfo); aVisInfo = NULL;
150 Aspect_WindowDefinitionError::Raise ("Xw_Window, Unable to create window");
154 // if parent - desktop
155 XSizeHints aSizeHints;
156 aSizeHints.x = myXLeft;
157 aSizeHints.y = myYTop;
158 aSizeHints.flags = PPosition;
159 aSizeHints.width = thePxWidth;
160 aSizeHints.height = thePxHeight;
161 aSizeHints.flags |= PSize;
162 XSetStandardProperties (aDisp, myXWindow, theTitle, theTitle, None,
163 NULL, 0, &aSizeHints);
165 /*XTextProperty aTitleProperty;
166 aTitleProperty.encoding = None;
167 char* aTitle = (char* )theTitle;
168 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
169 XSetWMName (aDisp, myXWindow, &aTitleProperty);
170 XSetWMProperties(aDisp, myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
175 // =======================================================================
176 // function : Xw_Window
178 // =======================================================================
179 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
180 const Window theXWin,
181 const Aspect_FBConfig theFBConfig)
183 myDisplay (theXDisplay),
185 myFBConfig (theFBConfig),
190 myIsOwnWin (Standard_False)
195 Aspect_WindowDefinitionError::Raise ("Xw_Window, given invalid X window");
198 else if (theXDisplay.IsNull())
200 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
203 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
206 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
210 Display* aDisp = myDisplay->GetDisplay();
212 XWindowAttributes aWinAttr;
213 XGetWindowAttributes (aDisp, myXWindow, &aWinAttr);
214 const int aScreen = DefaultScreen (aDisp);
215 const long aVisInfoMask = VisualIDMask | VisualScreenMask;
216 XVisualInfo aVisInfoTmp;
217 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
218 aVisInfoTmp.screen = aScreen;
220 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfoTmp, &aNbItems);
221 if (aVisInfo == NULL)
223 Aspect_WindowDefinitionError::Raise ("Xw_Window, Visual is unavailable");
231 // =======================================================================
232 // function : Destroy
234 // =======================================================================
235 void Xw_Window::Destroy()
237 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
239 XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
243 // =======================================================================
244 // function : XWindow
246 // =======================================================================
247 Window Xw_Window::XWindow() const
252 // =======================================================================
253 // function : IsMapped
255 // =======================================================================
256 Standard_Boolean Xw_Window::IsMapped() const
262 else if (IsVirtual())
264 return Standard_True;
267 XFlush (myDisplay->GetDisplay());
268 XWindowAttributes aWinAttr;
269 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
270 return aWinAttr.map_state == IsUnviewable
271 || aWinAttr.map_state == IsViewable;
274 // =======================================================================
277 // =======================================================================
278 void Xw_Window::Map() const
280 if (IsVirtual() || myXWindow == 0)
285 XMapWindow (myDisplay->GetDisplay(), myXWindow);
286 XFlush (myDisplay->GetDisplay());
289 // =======================================================================
292 // =======================================================================
293 void Xw_Window::Unmap() const
295 if (IsVirtual() || myXWindow == 0)
300 XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
303 // =======================================================================
304 // function : DoResize
306 // =======================================================================
307 Aspect_TypeOfResize Xw_Window::DoResize() const
311 return Aspect_TOR_UNKNOWN;
314 XFlush (myDisplay->GetDisplay());
315 XWindowAttributes aWinAttr;
316 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
317 if (aWinAttr.map_state == IsUnmapped)
319 return Aspect_TOR_UNKNOWN;
322 Standard_Integer aMask = 0;
323 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
325 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
326 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
327 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
328 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
331 case 0: aMode = Aspect_TOR_NO_BORDER; break;
332 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
333 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
334 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
335 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
336 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
337 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
338 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
339 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
343 *((Standard_Integer* )&myXLeft ) = aWinAttr.x;
344 *((Standard_Integer* )&myXRight ) = aWinAttr.x + aWinAttr.width;
345 *((Standard_Integer* )&myYTop ) = aWinAttr.y;
346 *((Standard_Integer* )&myYBottom ) = aWinAttr.y + aWinAttr.height;
350 // =======================================================================
351 // function : DoMapping
353 // =======================================================================
354 Standard_Boolean Xw_Window::DoMapping() const
356 return Standard_True; // IsMapped()
359 // =======================================================================
362 // =======================================================================
363 Quantity_Ratio Xw_Window::Ratio() const
370 XFlush (myDisplay->GetDisplay());
371 XWindowAttributes aWinAttr;
372 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
373 return Quantity_Ratio(aWinAttr.width) / Quantity_Ratio(aWinAttr.height);
376 // =======================================================================
377 // function : Position
379 // =======================================================================
380 void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
381 Standard_Integer& X2, Standard_Integer& Y2) const
388 XFlush (myDisplay->GetDisplay());
389 XWindowAttributes anAttributes;
390 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
392 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
393 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
395 X1 = -anAttributes.x;
396 X2 = X1 + anAttributes.width;
397 Y1 = -anAttributes.y;
398 Y2 = Y1 + anAttributes.height;
401 // =======================================================================
404 // =======================================================================
405 void Xw_Window::Size (Standard_Integer& theWidth,
406 Standard_Integer& theHeight) const
413 XFlush (myDisplay->GetDisplay());
414 XWindowAttributes aWinAttr;
415 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
416 theWidth = aWinAttr.width;
417 theHeight = aWinAttr.height;
420 #endif // Win32 or Mac OS X