blob: c8498242cfdefca81edd5ab98eb6449e8dd16572 [file] [log] [blame]
Nanang Izzuddind4ec2812011-08-01 12:57:45 +00001#include "vidwin.h"
Nanang Izzuddin5325f572011-08-15 22:29:14 +00002#include <QEvent>
Nanang Izzuddind4ec2812011-08-01 12:57:45 +00003
4#define THIS_FILE "vidwin.cpp"
Nanang Izzuddin5325f572011-08-15 22:29:14 +00005#define TRACE_(...) PJ_LOG(4,(THIS_FILE, __VA_ARGS__))
Nanang Izzuddind4ec2812011-08-01 12:57:45 +00006
Nanang Izzuddin5325f572011-08-15 22:29:14 +00007VidWin::VidWin(const pjmedia_vid_dev_hwnd *hwnd_,
8 QWidget* parent,
9 Qt::WindowFlags f) :
10 QWidget(parent, f), orig_parent(NULL),
11 size_hint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000012{
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000013 setAttribute(Qt::WA_NativeWindow);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000014
15 /* Make this widget a bit "lighter" */
Nanang Izzuddin5325f572011-08-15 22:29:14 +000016 setAttribute(Qt::WA_UpdatesDisabled);
17 setAttribute(Qt::WA_PaintOnScreen);
18 setAttribute(Qt::WA_NoSystemBackground);
19 setAttribute(Qt::WA_PaintOutsidePaintEvent);
20 setUpdatesEnabled(false);
21
22 pj_bzero(&hwnd, sizeof(hwnd));
23 if (hwnd_) {
24 hwnd = *hwnd_;
25 }
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000026}
27
28
29VidWin::~VidWin()
30{
Nanang Izzuddin5325f572011-08-15 22:29:14 +000031 detach();
32 pj_bzero(&hwnd, sizeof(hwnd));
33 size_hint = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
34 destroy(true, false);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000035}
36
Nanang Izzuddin5325f572011-08-15 22:29:14 +000037bool VidWin::event(QEvent *e)
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000038{
Nanang Izzuddin5325f572011-08-15 22:29:14 +000039 switch(e->type()) {
40 case QEvent::Resize:
41 {
42 // revert to default size hint, make it resizable
43 setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
44 // resize now
45 set_size();
46 }
47 break;
48 case QEvent::ParentAboutToChange:
49 get_size();
50 setFixedSize(size_hint);
51 break;
52 case QEvent::ParentChange:
53 {
54 get_size();
55 /*
56 QRect qr = rect();
57 if (qr.width() > size_hint.width())
58 size_hint.setWidth(qr.width());
59 if (qr.height() > size_hint.height())
60 size_hint.setWidth(qr.height());
61 */
62 setFixedSize(size_hint);
63 attach();
64 }
65 break;
66 default:
67 break;
68 }
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000069
Nanang Izzuddin5325f572011-08-15 22:29:14 +000070 return QWidget::event(e);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000071}
72
73/* Platform specific code */
74
Nanang Izzuddin5325f572011-08-15 22:29:14 +000075#if defined(_WIN32) && !defined(_WIN32_WINCE)
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000076
77#include <windows.h>
78
Nanang Izzuddin5325f572011-08-15 22:29:14 +000079void VidWin::attach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000080{
Nanang Izzuddin5325f572011-08-15 22:29:14 +000081 if (!hwnd.info.win.hwnd) return;
82
83 HWND w = (HWND)hwnd.info.win.hwnd;
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000084 HWND new_parent = (HWND)winId();
Nanang Izzuddin5325f572011-08-15 22:29:14 +000085 orig_parent = GetParent(w);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000086
Nanang Izzuddin5325f572011-08-15 22:29:14 +000087 SetParent(w, new_parent);
88 SetWindowLong(w, GWL_STYLE, WS_CHILD);
89 ShowWindow(w, SW_SHOWNOACTIVATE);
90 TRACE_("%p new parent handle = %p", w, new_parent);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000091}
92
Nanang Izzuddin5325f572011-08-15 22:29:14 +000093void VidWin::detach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +000094{
Nanang Izzuddin5325f572011-08-15 22:29:14 +000095 if (!hwnd.info.win.hwnd) return;
96
97 HWND w = (HWND)hwnd.info.win.hwnd;
98 ShowWindow(w, SW_HIDE);
99 SetParent(w, (HWND)orig_parent);
100 TRACE_("%p revert parent handle to %p", w, orig_parent);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000101}
102
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000103void VidWin::set_size()
104{
105 if (!hwnd.info.win.hwnd) return;
106
107 HWND w = (HWND)hwnd.info.win.hwnd;
108 QRect qr = rect();
109 UINT swp_flag = SWP_NOACTIVATE;
110 SetWindowPos(w, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);
111 TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
112}
113
114void VidWin::get_size()
115{
116 if (!hwnd.info.win.hwnd) return;
117
118 HWND w = (HWND)hwnd.info.win.hwnd;
119 RECT r;
120 if (GetWindowRect(w, &r))
121 size_hint = QSize(r.right-r.left+1, r.bottom-r.top+1);
122 TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
123}
124
125#elif defined(__APPLE__)
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000126
127#import<Cocoa/Cocoa.h>
128
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000129void VidWin::attach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000130{
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000131 if (!hwnd.info.cocoa.window) return;
132
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000133 /* Embed hwnd to widget */
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000134 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
135 NSWindow *parent = [(NSView*)winId() window];
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000136 orig_parent = [w parentWindow];
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000137
138 //[w setStyleMask:NSBorderlessWindowMask];
139
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000140 //Can't use this, as sometime the video window may not get reparented.
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000141 //[w setParentWindow:parent];
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000142
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000143 [parent addChildWindow:w ordered:NSWindowAbove];
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000144 TRACE_("%p new parent handle = %p", w, parent);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000145}
146
147
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000148void VidWin::detach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000149{
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000150 if (!hwnd.info.cocoa.window) return;
151
152 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
153 NSWindow *parent = [(NSView*)winId() window];
154 [parent removeChildWindow:w];
155}
156
157
158void VidWin::set_size()
159{
160 if (!hwnd.info.cocoa.window) return;
161
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000162 /* Update position and size */
163 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
164 NSRect r;
165
166 NSView* v = (NSView*)winId();
167 r = [v bounds];
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000168 r = [v convertRectToBase:r];
169 r.origin = [[v window] convertBaseToScreen:r.origin];
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000170
171 QRect qr = rect();
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000172 [w setFrame:r display:NO];
173
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000174 TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000175}
176
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000177void VidWin::get_size()
178{
179 if (!hwnd.info.cocoa.window) return;
180
181 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
182
183 size_hint = QSize(300, 200);
184
185 TRACE_("%p size = %dx%d", 0, size_hint.width(), size_hint.height());
186}
187
188
189#elif defined(linux) || defined(__linux)
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000190
191#include <X11/Xlib.h>
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000192#include <X11/Xutil.h>
193#include <QX11Info>
194#include <stdio.h>
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000195
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000196void VidWin::attach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000197{
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000198 if (!hwnd.info.x11.window) return;
199
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000200 /* Embed hwnd to widget */
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000201
202 // Use Qt X11 display here, using window creator X11 display may cause
203 // the window failing to embed to this QWidget.
204 //Display *d = (Display*)hwnd.info.x11.display;
205 Display *d = QX11Info::display();
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000206 Window w = (Window)hwnd.info.x11.window;
207 Window parent = (Window)this->winId();
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000208 int err = XReparentWindow(d, w, parent, 0, 0);
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000209 TRACE_("%p new parent handle = %p, err = %d",
210 (void*)w,(void*)parent, err);
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000211}
212
213
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000214void VidWin::detach()
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000215{
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000216}
217
218
219void VidWin::set_size()
220{
221 if (!hwnd.info.x11.window) return;
222
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000223 /* Update position and size */
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000224 Display *d = QX11Info::display();
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000225 Window w = (Window)hwnd.info.x11.window;
226 QRect qr = rect();
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000227
Nanang Izzuddin5325f572011-08-15 22:29:14 +0000228 int err = XResizeWindow(d, w, qr.width(), qr.height());
229 TRACE_("[%p,%p] new size = %dx%d, err = %d",
230 (void*)d, (void*)w, qr.width(), qr.height(), err);
231}
232
233void VidWin::get_size()
234{
235 if (!hwnd.info.x11.window) return;
236
237 Display *d = QX11Info::display();
238 Window w = (Window)hwnd.info.x11.window;
239
240 XWindowAttributes attr;
241 XGetWindowAttributes(d, w, &attr);
242 size_hint = QSize(attr.width, attr.height);
243 TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
Nanang Izzuddind4ec2812011-08-01 12:57:45 +0000244}
245
246#endif
247