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))
20 #include <Aspect_Convert.hxx>
21 #include <Aspect_WindowDefinitionError.hxx>
28 //! Search for RGBA double-buffered visual with stencil buffer.
29 //! Each size property should be a nonnegative minimum specification.
30 static int TheDoubleBuff[] =
41 IMPLEMENT_STANDARD_HANDLE (Xw_Window, Aspect_Window)
42 IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
44 // =======================================================================
45 // function : Xw_Window
47 // =======================================================================
48 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
49 const Standard_CString theTitle,
50 const Standard_Integer thePxLeft,
51 const Standard_Integer thePxTop,
52 const Standard_Integer thePxWidth,
53 const Standard_Integer thePxHeight)
55 myDisplay (theXDisplay),
59 myXRight (thePxLeft + thePxWidth),
60 myYBottom (thePxTop + thePxHeight),
61 myIsOwnWin (Standard_True)
64 if (thePxWidth <= 0 || thePxHeight <= 0)
66 Aspect_WindowDefinitionError::Raise ("Xw_Window, Coordinate(s) out of range");
68 else if (theXDisplay.IsNull())
70 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
73 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
75 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
79 Display* aDisp = myDisplay->GetDisplay();
80 int aScreen = DefaultScreen(aDisp);
81 Window aParent = RootWindow (aDisp, aScreen);
83 XVisualInfo* aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuff);
86 Aspect_WindowDefinitionError::Raise ("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
90 unsigned long aMask = 0;
91 XSetWindowAttributes aWinAttr;
92 memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
93 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
95 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
96 aWinAttr.border_pixel = 0;
97 aWinAttr.override_redirect = False;
99 myXWindow = XCreateWindow(aDisp, aParent,
100 myXLeft, myYTop, thePxWidth, thePxHeight,
104 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
105 XFree (aVisInfo); aVisInfo = NULL;
108 Aspect_WindowDefinitionError::Raise ("Xw_Window, Unable to create window");
112 // if parent - desktop
113 XSizeHints aSizeHints;
114 aSizeHints.x = myXLeft;
115 aSizeHints.y = myYTop;
116 aSizeHints.flags = PPosition;
117 aSizeHints.width = thePxWidth;
118 aSizeHints.height = thePxHeight;
119 aSizeHints.flags |= PSize;
120 XSetStandardProperties (aDisp, myXWindow, theTitle, theTitle, None,
121 NULL, 0, &aSizeHints);
123 /*XTextProperty aTitleProperty;
124 aTitleProperty.encoding = None;
125 char* aTitle = (char* )theTitle;
126 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
127 XSetWMName (aDisp, myXWindow, &aTitleProperty);
128 XSetWMProperties(aDisp, myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
133 // =======================================================================
134 // function : Xw_Window
136 // =======================================================================
137 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
138 const Window theXWin)
140 myDisplay (theXDisplay),
146 myIsOwnWin (Standard_False)
151 Aspect_WindowDefinitionError::Raise ("Xw_Window, given invalid X window");
154 else if (theXDisplay.IsNull())
156 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
159 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
162 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
166 Display* aDisp = myDisplay->GetDisplay();
168 XWindowAttributes aWinAttr;
169 XGetWindowAttributes (aDisp, myXWindow, &aWinAttr);
170 const int aScreen = DefaultScreen (aDisp);
171 const long aVisInfoMask = VisualIDMask | VisualScreenMask;
172 XVisualInfo aVisInfoTmp;
173 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
174 aVisInfoTmp.screen = aScreen;
176 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfoTmp, &aNbItems);
177 if (aVisInfo == NULL)
179 Aspect_WindowDefinitionError::Raise ("Xw_Window, Visual is unavailable");
187 // =======================================================================
188 // function : Destroy
190 // =======================================================================
191 void Xw_Window::Destroy()
193 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
195 XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
199 // =======================================================================
200 // function : XWindow
202 // =======================================================================
203 Window Xw_Window::XWindow() const
208 // =======================================================================
209 // function : IsMapped
211 // =======================================================================
212 Standard_Boolean Xw_Window::IsMapped() const
218 else if (IsVirtual())
220 return Standard_True;
223 XFlush (myDisplay->GetDisplay());
224 XWindowAttributes aWinAttr;
225 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
226 return aWinAttr.map_state == IsUnviewable
227 || aWinAttr.map_state == IsViewable;
230 // =======================================================================
233 // =======================================================================
234 void Xw_Window::Map() const
236 if (IsVirtual() || myXWindow == 0)
241 XMapWindow (myDisplay->GetDisplay(), myXWindow);
242 XFlush (myDisplay->GetDisplay());
245 // =======================================================================
248 // =======================================================================
249 void Xw_Window::Unmap() const
251 if (IsVirtual() || myXWindow == 0)
256 XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
259 // =======================================================================
260 // function : DoResize
262 // =======================================================================
263 Aspect_TypeOfResize Xw_Window::DoResize() const
267 return Aspect_TOR_UNKNOWN;
270 XFlush (myDisplay->GetDisplay());
271 XWindowAttributes aWinAttr;
272 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
273 if (aWinAttr.map_state == IsUnmapped)
275 return Aspect_TOR_UNKNOWN;
278 Standard_Integer aMask = 0;
279 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
281 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
282 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
283 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
284 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
287 case 0: aMode = Aspect_TOR_NO_BORDER; break;
288 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
289 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
290 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
291 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
292 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
293 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
294 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
295 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
299 *((Standard_Integer* )&myXLeft ) = aWinAttr.x;
300 *((Standard_Integer* )&myXRight ) = aWinAttr.x + aWinAttr.width;
301 *((Standard_Integer* )&myYTop ) = aWinAttr.y;
302 *((Standard_Integer* )&myYBottom ) = aWinAttr.y + aWinAttr.height;
306 // =======================================================================
307 // function : DoMapping
309 // =======================================================================
310 Standard_Boolean Xw_Window::DoMapping() const
312 return Standard_True; // IsMapped()
315 // =======================================================================
318 // =======================================================================
319 Quantity_Ratio Xw_Window::Ratio() const
326 XFlush (myDisplay->GetDisplay());
327 XWindowAttributes aWinAttr;
328 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
329 return Quantity_Ratio(aWinAttr.width) / Quantity_Ratio(aWinAttr.height);
332 // =======================================================================
333 // function : Position
335 // =======================================================================
336 void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
337 Standard_Integer& X2, Standard_Integer& Y2) const
344 XFlush (myDisplay->GetDisplay());
345 XWindowAttributes anAttributes;
346 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
348 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
349 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
351 X1 = -anAttributes.x;
352 X2 = X1 + anAttributes.width;
353 Y1 = -anAttributes.y;
354 Y2 = Y1 + anAttributes.height;
357 // =======================================================================
360 // =======================================================================
361 void Xw_Window::Size (Standard_Integer& theWidth,
362 Standard_Integer& theHeight) const
369 XFlush (myDisplay->GetDisplay());
370 XWindowAttributes aWinAttr;
371 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
372 theWidth = aWinAttr.width;
373 theHeight = aWinAttr.height;
376 #endif // Win32 or Mac OS X