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 |
29 | namespace |
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 | |
43 | IMPLEMENT_STANDARD_HANDLE (Xw_Window, Aspect_Window) |
44 | IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window) |
45 | |
46 | // ======================================================================= |
47 | // function : Xw_Window |
48 | // purpose : |
49 | // ======================================================================= |
50 | Xw_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 | // ======================================================================= |
139 | Xw_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 | // ======================================================================= |
193 | void 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 | // ======================================================================= |
205 | Window Xw_Window::XWindow() const |
7fd59977 |
206 | { |
ed97f43c |
207 | return myXWindow; |
7fd59977 |
208 | } |
209 | |
ed97f43c |
210 | // ======================================================================= |
211 | // function : IsMapped |
212 | // purpose : |
213 | // ======================================================================= |
214 | Standard_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 | // ======================================================================= |
236 | void 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 | // ======================================================================= |
251 | void 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 | // ======================================================================= |
265 | Aspect_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 | // ======================================================================= |
312 | Standard_Boolean Xw_Window::DoMapping() const |
313 | { |
314 | return Standard_True; // IsMapped() |
7fd59977 |
315 | } |
316 | |
ed97f43c |
317 | // ======================================================================= |
318 | // function : Ratio |
319 | // purpose : |
320 | // ======================================================================= |
321 | Quantity_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 | // ======================================================================= |
338 | void 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 | // ======================================================================= |
363 | void 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 |