0023670: Support for multiple 3D views: edited commands: vinit; added commands: vclos...
[occt.git] / src / Xw / Xw_Window.cxx
CommitLineData
ed97f43c 1// Created on: 2013-04-06
2// Created by: Kirill Gavrilov
3// Copyright (c) 2013 OPEN CASCADE SAS
b311480e 4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
ed97f43c 20#include <Xw_Window.hxx>
7fd59977 21
ed97f43c 22#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 23
7fd59977 24#include <Aspect_Convert.hxx>
ed97f43c 25#include <Aspect_WindowDefinitionError.hxx>
7fd59977 26
ed97f43c 27#include <GL/glx.h>
7fd59977 28
ed97f43c 29namespace
30{
7fd59977 31
ed97f43c 32 //! Search for RGBA double-buffered visual
33 static int TheDoubleBuff[] =
34 {
35 GLX_RGBA,
36 GLX_DEPTH_SIZE, 16,
37 GLX_DOUBLEBUFFER,
38 None
39 };
40
41};
42
43IMPLEMENT_STANDARD_HANDLE (Xw_Window, Aspect_Window)
44IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
45
46// =======================================================================
47// function : Xw_Window
48// purpose :
49// =======================================================================
50Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
51 const Standard_CString theTitle,
52 const Standard_Integer thePxLeft,
53 const Standard_Integer thePxTop,
54 const Standard_Integer thePxWidth,
55 const Standard_Integer thePxHeight)
56: Aspect_Window(),
57 myDisplay (theXDisplay),
58 myXWindow (0),
59 myXLeft (thePxLeft),
60 myYTop (thePxTop),
61 myXRight (thePxLeft + thePxWidth),
62 myYBottom (thePxTop + thePxHeight),
63 myIsOwnWin (Standard_True)
7fd59977 64{
ed97f43c 65 int aDummy = 0;
66 if (thePxWidth <= 0 || thePxHeight <= 0)
67 {
68 Aspect_WindowDefinitionError::Raise ("Xw_Window, Coordinate(s) out of range");
69 }
70 else if (theXDisplay.IsNull())
71 {
72 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
73 return;
74 }
75 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
76 {
77 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
78 return;
7fd59977 79 }
80
ed97f43c 81 Display* aDisp = myDisplay->GetDisplay();
82 int aScreen = DefaultScreen(aDisp);
83 Window aParent = RootWindow (aDisp, aScreen);
7fd59977 84
ed97f43c 85 XVisualInfo* aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuff);
86 if (aVisInfo == NULL)
87 {
88 Aspect_WindowDefinitionError::Raise ("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
89 return;
90 }
7fd59977 91
ed97f43c 92 unsigned long aMask = 0;
93 XSetWindowAttributes aWinAttr;
94 memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
95 aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
96 aMask |= CWEventMask;
97 aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
98 aWinAttr.border_pixel = 0;
99 aWinAttr.override_redirect = False;
100
101 myXWindow = XCreateWindow(aDisp, aParent,
102 myXLeft, myYTop, thePxWidth, thePxHeight,
103 0, aVisInfo->depth,
104 InputOutput,
105 aVisInfo->visual,
106 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
107 XFree (aVisInfo); aVisInfo = NULL;
108 if (myXWindow == 0)
109 {
110 Aspect_WindowDefinitionError::Raise ("Xw_Window, Unable to create window");
111 return;
112 }
7fd59977 113
ed97f43c 114 // if parent - desktop
115 XSizeHints aSizeHints;
116 aSizeHints.x = myXLeft;
117 aSizeHints.y = myYTop;
118 aSizeHints.flags = PPosition;
119 aSizeHints.width = thePxWidth;
120 aSizeHints.height = thePxHeight;
121 aSizeHints.flags |= PSize;
122 XSetStandardProperties (aDisp, myXWindow, theTitle, theTitle, None,
123 NULL, 0, &aSizeHints);
124
125 /*XTextProperty aTitleProperty;
126 aTitleProperty.encoding = None;
127 char* aTitle = (char* )theTitle;
128 Xutf8TextListToTextProperty(aDisp, &aTitle, 1, XUTF8StringStyle, &aTitleProperty);
129 XSetWMName (aDisp, myXWindow, &aTitleProperty);
130 XSetWMProperties(aDisp, myXWindow, &aTitleProperty, &aTitleProperty, NULL, 0, NULL, NULL, NULL);*/
131
132 XFlush (aDisp);
7fd59977 133}
134
ed97f43c 135// =======================================================================
136// function : Xw_Window
137// purpose :
138// =======================================================================
139Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
140 const Window theXWin)
dc3fe572 141: Aspect_Window(),
ed97f43c 142 myDisplay (theXDisplay),
143 myXWindow (theXWin),
144 myXLeft (0),
145 myYTop (0),
146 myXRight (512),
147 myYBottom (512),
148 myIsOwnWin (Standard_False)
7fd59977 149{
ed97f43c 150 int aDummy = 0;
151 if (theXWin == 0)
152 {
153 Aspect_WindowDefinitionError::Raise ("Xw_Window, given invalid X window");
154 return;
155 }
156 else if (theXDisplay.IsNull())
157 {
158 Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
159 return;
160 }
161 else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
162 {
163 myXWindow = 0;
164 Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
165 return;
166 }
7fd59977 167
ed97f43c 168 Display* aDisp = myDisplay->GetDisplay();
169
170 XWindowAttributes aWinAttr;
171 XGetWindowAttributes (aDisp, myXWindow, &aWinAttr);
172 const int aScreen = DefaultScreen (aDisp);
173 const long aVisInfoMask = VisualIDMask | VisualScreenMask;
174 XVisualInfo aVisInfoTmp;
175 aVisInfoTmp.visualid = aWinAttr.visual->visualid;
176 aVisInfoTmp.screen = aScreen;
177 int aNbItems = 0;
178 XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfoTmp, &aNbItems);
179 if (aVisInfo == NULL)
180 {
181 Aspect_WindowDefinitionError::Raise ("Xw_Window, Visual is unavailable");
182 return;
183 }
184 XFree (aVisInfo);
7fd59977 185
ed97f43c 186 DoResize();
7fd59977 187}
188
ed97f43c 189// =======================================================================
190// function : Destroy
191// purpose :
192// =======================================================================
193void Xw_Window::Destroy()
7fd59977 194{
ed97f43c 195 if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
7fd59977 196 {
ed97f43c 197 XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
7fd59977 198 }
7fd59977 199}
200
ed97f43c 201// =======================================================================
202// function : XWindow
203// purpose :
204// =======================================================================
205Window Xw_Window::XWindow() const
7fd59977 206{
ed97f43c 207 return myXWindow;
7fd59977 208}
209
ed97f43c 210// =======================================================================
211// function : IsMapped
212// purpose :
213// =======================================================================
214Standard_Boolean Xw_Window::IsMapped() const
7fd59977 215{
ed97f43c 216 if (myXWindow == 0)
217 {
218 return false;
dc3fe572 219 }
ed97f43c 220 else if (IsVirtual())
221 {
222 return Standard_True;
7fd59977 223 }
dc3fe572 224
ed97f43c 225 XFlush (myDisplay->GetDisplay());
226 XWindowAttributes aWinAttr;
227 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
228 return aWinAttr.map_state == IsUnviewable
229 || aWinAttr.map_state == IsViewable;
7fd59977 230}
231
ed97f43c 232// =======================================================================
233// function : Map
234// purpose :
235// =======================================================================
236void Xw_Window::Map() const
7fd59977 237{
ed97f43c 238 if (IsVirtual() || myXWindow == 0)
239 {
240 return;
7fd59977 241 }
242
ed97f43c 243 XMapWindow (myDisplay->GetDisplay(), myXWindow);
244 XFlush (myDisplay->GetDisplay());
7fd59977 245}
246
ed97f43c 247// =======================================================================
248// function : Unmap
249// purpose :
250// =======================================================================
251void Xw_Window::Unmap() const
252{
253 if (IsVirtual() || myXWindow == 0)
254 {
255 return;
7fd59977 256 }
7fd59977 257
ed97f43c 258 XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
7fd59977 259}
260
ed97f43c 261// =======================================================================
262// function : DoResize
263// purpose :
264// =======================================================================
265Aspect_TypeOfResize Xw_Window::DoResize() const
266{
267 if (myXWindow == 0)
268 {
269 return Aspect_TOR_UNKNOWN;
270 }
7fd59977 271
ed97f43c 272 XFlush (myDisplay->GetDisplay());
273 XWindowAttributes aWinAttr;
274 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
275 if (aWinAttr.map_state == IsUnmapped)
276 {
277 return Aspect_TOR_UNKNOWN;
278 }
7fd59977 279
ed97f43c 280 Standard_Integer aMask = 0;
281 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
7fd59977 282
ed97f43c 283 if (Abs (aWinAttr.x - myXLeft ) > 2) aMask |= 1;
284 if (Abs ((aWinAttr.x + aWinAttr.width) - myXRight ) > 2) aMask |= 2;
285 if (Abs (aWinAttr.y - myYTop ) > 2) aMask |= 4;
286 if (Abs ((aWinAttr.y + aWinAttr.height) - myYBottom) > 2) aMask |= 8;
287 switch (aMask)
288 {
289 case 0: aMode = Aspect_TOR_NO_BORDER; break;
290 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
291 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
292 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
293 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
294 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
295 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
296 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
297 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
298 default: break;
299 }
7fd59977 300
ed97f43c 301 *((Standard_Integer* )&myXLeft ) = aWinAttr.x;
302 *((Standard_Integer* )&myXRight ) = aWinAttr.x + aWinAttr.width;
303 *((Standard_Integer* )&myYTop ) = aWinAttr.y;
304 *((Standard_Integer* )&myYBottom ) = aWinAttr.y + aWinAttr.height;
305 return aMode;
7fd59977 306}
7fd59977 307
ed97f43c 308// =======================================================================
309// function : DoMapping
310// purpose :
311// =======================================================================
312Standard_Boolean Xw_Window::DoMapping() const
313{
314 return Standard_True; // IsMapped()
7fd59977 315}
316
ed97f43c 317// =======================================================================
318// function : Ratio
319// purpose :
320// =======================================================================
321Quantity_Ratio Xw_Window::Ratio() const
322{
323 if (myXWindow == 0)
324 {
325 return 1.0;
326 }
7fd59977 327
ed97f43c 328 XFlush (myDisplay->GetDisplay());
329 XWindowAttributes aWinAttr;
330 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
331 return Quantity_Ratio(aWinAttr.width) / Quantity_Ratio(aWinAttr.height);
7fd59977 332}
333
ed97f43c 334// =======================================================================
335// function : Position
336// purpose :
337// =======================================================================
338void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
339 Standard_Integer& X2, Standard_Integer& Y2) const
340{
18d715bd 341 if (myXWindow == 0)
342 {
343 return;
344 }
345
346 XFlush (myDisplay->GetDisplay());
347 XWindowAttributes anAttributes;
348 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
349 Window aChild;
350 XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
351 0, 0, &anAttributes.x, &anAttributes.y, &aChild);
352
353 X1 = -anAttributes.x;
354 X2 = X1 + anAttributes.width;
355 Y1 = -anAttributes.y;
356 Y2 = Y1 + anAttributes.height;
7fd59977 357}
358
ed97f43c 359// =======================================================================
360// function : Size
361// purpose :
362// =======================================================================
363void Xw_Window::Size (Standard_Integer& theWidth,
364 Standard_Integer& theHeight) const
365{
366 if (myXWindow == 0)
367 {
368 return;
369 }
7fd59977 370
ed97f43c 371 XFlush (myDisplay->GetDisplay());
372 XWindowAttributes aWinAttr;
373 XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
374 theWidth = aWinAttr.width;
375 theHeight = aWinAttr.height;
7fd59977 376}
377
ed97f43c 378#endif // Win32 or Mac OS X