blob: 3e38b6cdc5933e48cb8fe98db2d3b46ba88d54d5 [file] [log] [blame]
Alexandre Lision67916dd2014-01-24 13:33:04 -05001/* $Id$ */
2/*
3 * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "vidwin.h"
20#include <QEvent>
21
22#define THIS_FILE "vidwin.cpp"
23#define TRACE_(...) PJ_LOG(4,(THIS_FILE, __VA_ARGS__))
24
25VidWin::VidWin(const pjmedia_vid_dev_hwnd *hwnd_,
26 QWidget* parent,
27 Qt::WindowFlags f) :
28 QWidget(parent, f), orig_parent(NULL),
29 size_hint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
30{
31 setAttribute(Qt::WA_NativeWindow);
32
33 /* Make this widget a bit "lighter" */
34 setAttribute(Qt::WA_UpdatesDisabled);
35 setAttribute(Qt::WA_PaintOnScreen);
36 setAttribute(Qt::WA_NoSystemBackground);
37 setAttribute(Qt::WA_PaintOutsidePaintEvent);
38 setUpdatesEnabled(false);
39
40 pj_bzero(&hwnd, sizeof(hwnd));
41 if (hwnd_) {
42 hwnd = *hwnd_;
43 }
44}
45
46
47VidWin::~VidWin()
48{
49 show_sdl(false);
50 detach();
51}
52
53void VidWin::putIntoLayout(QBoxLayout *box)
54{
55 box->addWidget(this, 1);
56 show();
57 activateWindow();
58}
59
60bool VidWin::event(QEvent *e)
61{
62 switch(e->type()) {
63
64 case QEvent::Resize:
65 set_size();
66 break;
67
68 case QEvent::ParentChange:
69 get_size();
70 if (0) {
71 QRect qr = rect();
72 if (qr.width() > size_hint.width())
73 size_hint.setWidth(qr.width());
74 if (qr.height() > size_hint.height())
75 size_hint.setWidth(qr.height());
76 }
77 setFixedSize(size_hint);
78 attach();
79 break;
80
81 case QEvent::Show:
82 show_sdl(true);
83 // revert to default size hint, make it resizable
84 setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
85 break;
86
87 case QEvent::Hide:
88 show_sdl(false);
89 break;
90
91 default:
92 break;
93 }
94
95 return QWidget::event(e);
96}
97
98/* Platform specific code */
99
100#if defined(_WIN32) && !defined(_WIN32_WINCE)
101
102#include <windows.h>
103
104void VidWin::attach()
105{
106 if (!hwnd.info.win.hwnd) return;
107
108 HWND w = (HWND)hwnd.info.win.hwnd;
109 HWND new_parent = (HWND)winId();
110 orig_parent = GetParent(w);
111
112 //SetWindowLong(w, GWL_STYLE, WS_CHILD);
113 SetParent(w, new_parent);
114 TRACE_("%p new parent handle = %p", w, new_parent);
115}
116
117void VidWin::detach()
118{
119 if (!hwnd.info.win.hwnd) return;
120
121 HWND w = (HWND)hwnd.info.win.hwnd;
122 SetParent(w, (HWND)orig_parent);
123 TRACE_("%p revert parent handle to %p", w, orig_parent);
124}
125
126void VidWin::set_size()
127{
128 if (!hwnd.info.win.hwnd) return;
129
130 HWND w = (HWND)hwnd.info.win.hwnd;
131 QRect qr = rect();
132 UINT swp_flag = SWP_NOACTIVATE;
133 SetWindowPos(w, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);
134 TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
135}
136
137void VidWin::get_size()
138{
139 if (!hwnd.info.win.hwnd) return;
140
141 HWND w = (HWND)hwnd.info.win.hwnd;
142 RECT r;
143 if (GetWindowRect(w, &r))
144 size_hint = QSize(r.right-r.left+1, r.bottom-r.top+1);
145 TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
146}
147
148void VidWin::show_sdl(bool visible)
149{
150 if (!hwnd.info.win.hwnd) return;
151
152 HWND w = (HWND)hwnd.info.win.hwnd;
153 ShowWindow(w, visible ? SW_SHOW : SW_HIDE);
154}
155
156#elif defined(__APPLE__)
157
158#import<Cocoa/Cocoa.h>
159
160void VidWin::attach()
161{
162 if (!hwnd.info.cocoa.window) return;
163
164 /* Embed hwnd to widget */
165 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
166 NSWindow *parent = [(NSView*)winId() window];
167 orig_parent = [w parentWindow];
168
169 //[w setStyleMask:NSBorderlessWindowMask];
170
171 //Can't use this, as sometime the video window may not get reparented.
172 //[w setParentWindow:parent];
173
174 [parent addChildWindow:w ordered:NSWindowAbove];
175 TRACE_("%p new parent handle = %p", w, parent);
176}
177
178
179void VidWin::detach()
180{
181 if (!hwnd.info.cocoa.window) return;
182
183 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
184 NSWindow *parent = [(NSView*)winId() window];
185 [parent removeChildWindow:w];
186}
187
188
189void VidWin::set_size()
190{
191 if (!hwnd.info.cocoa.window) return;
192
193 /* Update position and size */
194 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
195 NSRect r;
196
197 NSView* v = (NSView*)winId();
198 r = [v bounds];
199 r = [v convertRectToBase:r];
200 r.origin = [[v window] convertBaseToScreen:r.origin];
201
202 QRect qr = rect();
203 [w setFrame:r display:NO];
204
205 TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
206}
207
208void VidWin::get_size()
209{
210 if (!hwnd.info.cocoa.window) return;
211
212 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
213
214 size_hint = QSize(300, 200);
215
216 TRACE_("%p size = %dx%d", 0, size_hint.width(), size_hint.height());
217}
218
219void VidWin::show_sdl(bool visible)
220{
221 if (!hwnd.info.cocoa.window) return;
222
223 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
224
225 if (visible) {
226 [[w contentView]setHidden:NO];
227 } else {
228 [[w contentView]setHidden:YES];
229 }
230}
231
232#elif defined(linux) || defined(__linux)
233
234#include <X11/Xlib.h>
235#include <X11/Xutil.h>
236#include <QX11Info>
237#include <stdio.h>
238
239#define GET_DISPLAY() QX11Info::display()
240//#define GET_DISPLAY() (Display*)hwnd.info.x11.display
241
242void VidWin::attach()
243{
244 if (!hwnd.info.x11.window) return;
245
246 /* Embed hwnd to widget */
247
248 // Use Qt X11 display here, using window creator X11 display may cause
249 // the window failing to embed to this QWidget.
250 //Display *d = (Display*)hwnd.info.x11.display;
251 Display *d = GET_DISPLAY();
252 Window w = (Window)hwnd.info.x11.window;
253 Window parent = (Window)this->winId();
254 int err = XReparentWindow(d, w, parent, 0, 0);
255 TRACE_("%p new parent handle = %p, err = %d",
256 (void*)w,(void*)parent, err);
257}
258
259
260void VidWin::detach()
261{
262}
263
264
265void VidWin::set_size()
266{
267 if (!hwnd.info.x11.window) return;
268
269 /* Update position and size */
270 Display *d = GET_DISPLAY();
271 Window w = (Window)hwnd.info.x11.window;
272 QRect qr = rect();
273
274 int err = XResizeWindow(d, w, qr.width(), qr.height());
275 TRACE_("[%p,%p] new size = %dx%d, err = %d",
276 (void*)d, (void*)w, qr.width(), qr.height(), err);
277}
278
279void VidWin::get_size()
280{
281 if (!hwnd.info.x11.window) return;
282
283 Display *d = GET_DISPLAY();
284 Window w = (Window)hwnd.info.x11.window;
285
286 XWindowAttributes attr;
287 XGetWindowAttributes(d, w, &attr);
288 size_hint = QSize(attr.width, attr.height);
289 TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
290}
291
292void VidWin::show_sdl(bool visible)
293{
294 if (!hwnd.info.x11.window) return;
295
296 Display *d = GET_DISPLAY();
297 Window w = (Window)hwnd.info.x11.window;
298
299 if (visible) {
300 XMapRaised(d, w);
301 } else {
302 XUnmapWindow(d, w);
303 }
304
305 XFlush(d);
306}
307
308#endif
309