0024624: Lost word in license statement in source files
[occt.git] / src / Xw / Xw_Window.cxx
1 // Created on: 2013-04-06
2 // Created by: Kirill Gavrilov
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Xw_Window.hxx>
17
18 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
19
20 #include <Aspect_Convert.hxx>
21 #include <Aspect_WindowDefinitionError.hxx>
22
23 #include <GL/glx.h>
24
25 namespace
26 {
27
28   //! Search for RGBA double-buffered visual with stencil buffer.
29   //! Each size property should be a nonnegative minimum specification.
30   static int TheDoubleBuff[] =
31   {
32     GLX_RGBA,
33     GLX_DEPTH_SIZE, 16,
34     GLX_STENCIL_SIZE, 1,
35     GLX_DOUBLEBUFFER,
36     None
37   };
38
39 };
40
41 IMPLEMENT_STANDARD_HANDLE (Xw_Window, Aspect_Window)
42 IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window)
43
44 // =======================================================================
45 // function : Xw_Window
46 // purpose  :
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)
54 : Aspect_Window(),
55   myDisplay  (theXDisplay),
56   myXWindow  (0),
57   myXLeft    (thePxLeft),
58   myYTop     (thePxTop),
59   myXRight   (thePxLeft + thePxWidth),
60   myYBottom  (thePxTop + thePxHeight),
61   myIsOwnWin (Standard_True)
62 {
63   int aDummy = 0;
64   if (thePxWidth <= 0 || thePxHeight <= 0)
65   {
66     Aspect_WindowDefinitionError::Raise ("Xw_Window, Coordinate(s) out of range");
67   }
68   else if (theXDisplay.IsNull())
69   {
70     Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
71     return;
72   }
73   else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
74   {
75     Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
76     return;
77   }
78
79   Display* aDisp   = myDisplay->GetDisplay();
80   int      aScreen = DefaultScreen(aDisp);
81   Window   aParent = RootWindow   (aDisp, aScreen);
82
83   XVisualInfo* aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuff);
84   if (aVisInfo == NULL)
85   {
86     Aspect_WindowDefinitionError::Raise ("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)");
87     return;
88   }
89
90   unsigned long aMask = 0;
91   XSetWindowAttributes aWinAttr;
92   memset(&aWinAttr, 0, sizeof(XSetWindowAttributes));
93   aWinAttr.event_mask = ExposureMask | StructureNotifyMask;
94   aMask |= CWEventMask;
95   aWinAttr.colormap = XCreateColormap(aDisp, aParent, aVisInfo->visual, AllocNone);
96   aWinAttr.border_pixel = 0;
97   aWinAttr.override_redirect = False;
98
99   myXWindow = XCreateWindow(aDisp, aParent,
100                             myXLeft, myYTop, thePxWidth, thePxHeight,
101                             0, aVisInfo->depth,
102                             InputOutput,
103                             aVisInfo->visual,
104                             CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr);
105   XFree (aVisInfo); aVisInfo = NULL;
106   if (myXWindow == 0)
107   {
108     Aspect_WindowDefinitionError::Raise ("Xw_Window, Unable to create window");
109     return;
110   }
111
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);
122
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);*/
129
130   XFlush (aDisp);
131 }
132
133 // =======================================================================
134 // function : Xw_Window
135 // purpose  :
136 // =======================================================================
137 Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,
138                       const Window theXWin)
139 : Aspect_Window(),
140   myDisplay  (theXDisplay),
141   myXWindow  (theXWin),
142   myXLeft    (0),
143   myYTop     (0),
144   myXRight   (512),
145   myYBottom  (512),
146   myIsOwnWin (Standard_False)
147 {
148   int aDummy = 0;
149   if (theXWin == 0)
150   {
151     Aspect_WindowDefinitionError::Raise ("Xw_Window, given invalid X window");
152     return;
153   }
154   else if (theXDisplay.IsNull())
155   {
156     Aspect_WindowDefinitionError::Raise ("Xw_Window, X Display connection is undefined");
157     return;
158   }
159   else if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy))
160   {
161     myXWindow = 0;
162     Aspect_WindowDefinitionError::Raise ("Xw_Window, GLX extension is unavailable");
163     return;
164   }
165
166   Display* aDisp = myDisplay->GetDisplay();
167
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;
175   int aNbItems = 0;
176   XVisualInfo* aVisInfo = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfoTmp, &aNbItems);
177   if (aVisInfo == NULL)
178   {
179     Aspect_WindowDefinitionError::Raise ("Xw_Window, Visual is unavailable");
180     return;
181   }
182   XFree (aVisInfo);
183
184   DoResize();
185 }
186
187 // =======================================================================
188 // function : Destroy
189 // purpose  :
190 // =======================================================================
191 void Xw_Window::Destroy()
192 {
193   if (myIsOwnWin && myXWindow != 0 && !myDisplay.IsNull())
194   {
195     XDestroyWindow (myDisplay->GetDisplay(), myXWindow);
196   }
197 }
198
199 // =======================================================================
200 // function : XWindow
201 // purpose  :
202 // =======================================================================
203 Window Xw_Window::XWindow() const
204 {
205   return myXWindow;
206 }
207
208 // =======================================================================
209 // function : IsMapped
210 // purpose  :
211 // =======================================================================
212 Standard_Boolean Xw_Window::IsMapped() const
213 {
214   if (myXWindow == 0)
215   {
216     return false;
217   }
218   else if (IsVirtual())
219   {
220     return Standard_True;
221   }
222
223   XFlush (myDisplay->GetDisplay());
224   XWindowAttributes aWinAttr;
225   XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
226   return aWinAttr.map_state == IsUnviewable
227       || aWinAttr.map_state == IsViewable;
228 }
229
230 // =======================================================================
231 // function : Map
232 // purpose  :
233 // =======================================================================
234 void Xw_Window::Map() const
235 {
236   if (IsVirtual() || myXWindow == 0)
237   {
238     return;
239   }
240
241   XMapWindow (myDisplay->GetDisplay(), myXWindow);
242   XFlush (myDisplay->GetDisplay());
243 }
244
245 // =======================================================================
246 // function : Unmap
247 // purpose  :
248 // =======================================================================
249 void Xw_Window::Unmap() const
250 {
251   if (IsVirtual() || myXWindow == 0)
252   {
253     return;
254   }
255
256   XIconifyWindow (myDisplay->GetDisplay(), myXWindow, DefaultScreen(myDisplay->GetDisplay()));
257 }
258
259 // =======================================================================
260 // function : DoResize
261 // purpose  :
262 // =======================================================================
263 Aspect_TypeOfResize Xw_Window::DoResize() const
264 {
265   if (myXWindow == 0)
266   {
267     return Aspect_TOR_UNKNOWN;
268   }
269
270   XFlush (myDisplay->GetDisplay());
271   XWindowAttributes aWinAttr;
272   XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
273   if (aWinAttr.map_state == IsUnmapped)
274   {
275     return Aspect_TOR_UNKNOWN;
276   }
277
278   Standard_Integer aMask = 0;
279   Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
280
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;
285   switch (aMask)
286   {
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;
296     default: break;
297   }
298
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;
303   return aMode;
304 }
305
306 // =======================================================================
307 // function : DoMapping
308 // purpose  :
309 // =======================================================================
310 Standard_Boolean Xw_Window::DoMapping() const
311 {
312   return Standard_True; // IsMapped()
313 }
314
315 // =======================================================================
316 // function : Ratio
317 // purpose  :
318 // =======================================================================
319 Quantity_Ratio Xw_Window::Ratio() const
320 {
321   if (myXWindow == 0)
322   {
323     return 1.0;
324   }
325
326   XFlush (myDisplay->GetDisplay());
327   XWindowAttributes aWinAttr;
328   XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
329   return Quantity_Ratio(aWinAttr.width) / Quantity_Ratio(aWinAttr.height);
330 }
331
332 // =======================================================================
333 // function : Position
334 // purpose  :
335 // =======================================================================
336 void Xw_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
337                           Standard_Integer& X2, Standard_Integer& Y2) const
338 {
339   if (myXWindow == 0)
340   {
341     return;
342   }
343
344   XFlush (myDisplay->GetDisplay());
345   XWindowAttributes anAttributes;
346   XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &anAttributes);
347   Window aChild;
348   XTranslateCoordinates (myDisplay->GetDisplay(), anAttributes.root, myXWindow,
349                          0, 0, &anAttributes.x, &anAttributes.y, &aChild);
350
351   X1 = -anAttributes.x;
352   X2 = X1 + anAttributes.width;
353   Y1 = -anAttributes.y;
354   Y2 = Y1 + anAttributes.height;
355 }
356
357 // =======================================================================
358 // function : Size
359 // purpose  :
360 // =======================================================================
361 void Xw_Window::Size (Standard_Integer& theWidth,
362                       Standard_Integer& theHeight) const
363 {
364   if (myXWindow == 0)
365   {
366     return;
367   }
368
369   XFlush (myDisplay->GetDisplay());
370   XWindowAttributes aWinAttr;
371   XGetWindowAttributes (myDisplay->GetDisplay(), myXWindow, &aWinAttr);
372   theWidth  = aWinAttr.width;
373   theHeight = aWinAttr.height;
374 }
375
376 #endif //  Win32 or Mac OS X