Changeset 3699 for pjproject/trunk/pjsip-apps/src/vidgui/vidwin.cpp
- Timestamp:
- Aug 15, 2011 10:29:14 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/vidgui/vidwin.cpp
r3686 r3699 1 1 #include "vidwin.h" 2 #include <QEvent> 2 3 3 4 #define THIS_FILE "vidwin.cpp" 4 #define TIMER_EMBED 1 5 #define TIMER_RESIZE 2 6 7 void VidWin::timer_cb(pj_timer_heap_t *timer_heap, 8 struct pj_timer_entry *entry) 9 { 10 VidWin *vw = (VidWin*)entry->user_data; 11 12 PJ_UNUSED_ARG(timer_heap); 13 14 switch(entry->id) { 15 case TIMER_EMBED: 16 vw->embed(); 17 vw->resize(); 18 break; 19 case TIMER_RESIZE: 20 vw->resize(); 5 #define TRACE_(...) PJ_LOG(4,(THIS_FILE, __VA_ARGS__)) 6 7 VidWin::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) 12 { 13 setAttribute(Qt::WA_NativeWindow); 14 15 /* Make this widget a bit "lighter" */ 16 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 } 26 } 27 28 29 VidWin::~VidWin() 30 { 31 detach(); 32 pj_bzero(&hwnd, sizeof(hwnd)); 33 size_hint = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); 34 destroy(true, false); 35 } 36 37 bool VidWin::event(QEvent *e) 38 { 39 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 } 21 65 break; 22 66 default: … … 24 68 } 25 69 26 entry->id = 0; 27 } 28 29 30 VidWin::VidWin(pjmedia_vid_dev_hwnd *hwnd_, QWidget* parent, Qt::WindowFlags f) : 31 QWidget(parent, f), hwnd(*hwnd_) 32 { 33 #if 0 34 // A proof that QWidget::create() change window proc! 35 // And that will cause SDL rendering not working. 36 HWND h = (HWND)hwnd->info.win.hwnd; 37 LONG wl; 38 39 wl = GetWindowLong(h, GWL_WNDPROC); 40 printf("%p old proc: %p\n", h, wl); 41 42 create(WId(hwnd->info.win.hwnd), false, true); 43 printf("%p qwidgetwid: %p\n", h, winId()); 44 45 wl = GetWindowLong(h, GWL_WNDPROC); 46 printf("%p new proc: %p\n", h, wl); 47 #endif 48 49 setAttribute(Qt::WA_NativeWindow); 50 setMinimumSize(320, 200); 51 52 /* Make this widget a bit "lighter" */ 53 //setAttribute(Qt::WA_UpdatesDisabled); 54 //setAttribute(Qt::WA_PaintOnScreen); 55 //setAttribute(Qt::WA_NoSystemBackground); 56 //setAttribute(Qt::WA_PaintOutsidePaintEvent); 57 //setUpdatesEnabled(false); 58 59 /* Schedule embed, as at this point widget initialization is not 60 * completely done yet (e.g: bad size). 61 */ 62 pj_timer_entry_init(&timer_entry, TIMER_EMBED, this, &timer_cb); 63 pj_time_val delay = {0, 100}; 64 pjsua_schedule_timer(&timer_entry, &delay); 65 } 66 67 68 VidWin::~VidWin() 69 { 70 if (timer_entry.id) { 71 pjsua_cancel_timer(&timer_entry); 72 timer_entry.id = 0; 73 } 74 } 75 76 77 void VidWin::resizeEvent(QResizeEvent*) 78 { 79 /* Resizing SDL window must be scheduled (via timer), 80 * as on Windows platform, the SDL resizing process 81 * will steal focus (SDL bug?). 82 */ 83 if (timer_entry.id && timer_entry.id != TIMER_RESIZE) 84 return; 85 86 if (timer_entry.id == TIMER_RESIZE) 87 pjsua_cancel_timer(&timer_entry); 88 89 timer_entry.id = TIMER_RESIZE; 90 timer_entry.cb = &timer_cb; 91 timer_entry.user_data = this; 92 93 pj_time_val delay = {0, 300}; 94 pjsua_schedule_timer(&timer_entry, &delay); 70 return QWidget::event(e); 95 71 } 96 72 97 73 /* Platform specific code */ 98 74 99 #if defined( PJ_WIN32) && !defined(PJ_WIN32_WINCE)75 #if defined(_WIN32) && !defined(_WIN32_WINCE) 100 76 101 77 #include <windows.h> 102 78 103 void VidWin::embed() 104 { 79 void VidWin::attach() 80 { 81 if (!hwnd.info.win.hwnd) return; 82 83 HWND w = (HWND)hwnd.info.win.hwnd; 84 HWND new_parent = (HWND)winId(); 85 orig_parent = GetParent(w); 86 87 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); 91 } 92 93 void VidWin::detach() 94 { 95 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); 101 } 102 103 void 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 114 void 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__) 126 127 #import<Cocoa/Cocoa.h> 128 129 void VidWin::attach() 130 { 131 if (!hwnd.info.cocoa.window) return; 132 105 133 /* Embed hwnd to widget */ 106 pj_assert(hwnd.type == PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);107 HWND h = (HWND)hwnd.info.win.hwnd;108 HWND new_parent = (HWND)winId();109 110 //old_parent_hwnd.type = PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS;111 //old_parent_hwnd.info.win.hwnd = GetParent(h);112 113 SetParent(h, new_parent);114 SetWindowLong(h, GWL_STYLE, WS_CHILD);115 ShowWindow(h, SW_SHOWNOACTIVATE);116 PJ_LOG(3, (THIS_FILE, "%p parent handle = %p", h, new_parent));117 }118 119 void VidWin::resize()120 {121 /* Update position and size */122 HWND h = (HWND)hwnd.info.win.hwnd;123 QRect qr = rect();124 UINT swp_flag = SWP_SHOWWINDOW | SWP_NOACTIVATE;125 SetWindowPos(h, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);126 PJ_LOG(3, (THIS_FILE, "%p new size = %d x %d", h, qr.width(), qr.height()));127 }128 129 #elif defined(PJ_DARWINOS)130 131 #import<Cocoa/Cocoa.h>132 133 void VidWin::embed()134 {135 /* Embed hwnd to widget */136 pj_assert(hwnd.type != PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);137 134 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window; 138 135 NSWindow *parent = [(NSView*)winId() window]; 136 orig_parent = [w parentWindow]; 139 137 140 138 //[w setStyleMask:NSBorderlessWindowMask]; 141 139 140 //Can't use this, as sometime the video window may not get reparented. 142 141 //[w setParentWindow:parent]; 142 143 143 [parent addChildWindow:w ordered:NSWindowAbove]; 144 PJ_LOG(3, (THIS_FILE, "%p parent handle = %p", w, parent)); 145 } 146 147 148 void VidWin::resize() 149 { 144 TRACE_("%p new parent handle = %p", w, parent); 145 } 146 147 148 void VidWin::detach() 149 { 150 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 158 void VidWin::set_size() 159 { 160 if (!hwnd.info.cocoa.window) return; 161 150 162 /* Update position and size */ 151 163 NSWindow *w = (NSWindow*)hwnd.info.cocoa.window; … … 154 166 NSView* v = (NSView*)winId(); 155 167 r = [v bounds]; 156 //PJ_LOG(3, (THIS_FILE, "before: (%d,%d) %dx%d", r.origin.x, r.origin.y, r.size.width, r.size.height));157 168 r = [v convertRectToBase:r]; 158 169 r.origin = [[v window] convertBaseToScreen:r.origin]; 159 //PJ_LOG(3, (THIS_FILE, "after: (%d,%d) %dx%d", r.origin.x, r.origin.y, r.size.width, r.size.height));160 170 161 171 QRect qr = rect(); 162 /*163 QPoint p = pos();164 QPoint pp = parentWidget()->pos();165 PJ_LOG(3, (THIS_FILE, "this pos: (%d,%d)", p.x(), p.y()));166 PJ_LOG(3, (THIS_FILE, "parent pos: (%d,%d)", pp.x(), pp.y()));167 168 //qr.setTopLeft(mapToGlobal(qr.topLeft()));169 r.origin.x = qr.x();170 r.origin.y = qr.y();171 r.size.width = qr.width();172 r.size.height = qr.height();173 //r.origin = [w convertBaseToScreen:r.origin];174 */175 172 [w setFrame:r display:NO]; 176 173 177 PJ_LOG(3, (THIS_FILE, "%p new size = %d x %d", w, qr.width(), qr.height())); 178 } 179 180 #elif defined(PJ_LINUX) 174 TRACE_("%p new size = %dx%d", w, qr.width(), qr.height()); 175 } 176 177 void 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) 181 190 182 191 #include <X11/Xlib.h> 183 //#include <QX11Info> 184 185 void VidWin::embed() 186 { 192 #include <X11/Xutil.h> 193 #include <QX11Info> 194 #include <stdio.h> 195 196 void VidWin::attach() 197 { 198 if (!hwnd.info.x11.window) return; 199 187 200 /* Embed hwnd to widget */ 188 pj_assert(hwnd.type != PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS); 189 Display *d = (Display*)hwnd.info.x11.display; 190 //Display *d = QX11Info::display(); 201 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(); 191 206 Window w = (Window)hwnd.info.x11.window; 192 207 Window parent = (Window)this->winId(); 193 194 XSetWindowBorderWidth(d, w, 0);195 196 208 int err = XReparentWindow(d, w, parent, 0, 0); 197 PJ_LOG(3, (THIS_FILE, "XReparentWindow() err = %d", err)); 198 //XRaiseWindow(d, w); 199 //XMapSubwindows(d, parent); 200 //XMapWindow(d, parent); 201 //XMapWindow(d, w); 202 //XSync(d, False); 203 204 PJ_LOG(3, (THIS_FILE, "[%p,%p] parent handle = %p", d, w, parent)); 205 } 206 207 208 void VidWin::resize() 209 { 209 TRACE_("%p new parent handle = %p, err = %d", 210 (void*)w,(void*)parent, err); 211 } 212 213 214 void VidWin::detach() 215 { 216 } 217 218 219 void VidWin::set_size() 220 { 221 if (!hwnd.info.x11.window) return; 222 210 223 /* Update position and size */ 211 Display *d = (Display*)hwnd.info.x11.display;224 Display *d = QX11Info::display(); 212 225 Window w = (Window)hwnd.info.x11.window; 213 226 QRect qr = rect(); 214 //XResizeWindow(d, w, qr.width(), qr.height()); 215 XMoveResizeWindow(d, w, 0, 0, qr.width(), qr.height()); 216 217 PJ_LOG(3, (THIS_FILE, "[%p,%p] new size = %d x %d", d, w, qr.width(), qr.height())); 218 //XSync(d, False); 219 XFlush(d); 227 228 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 233 void 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()); 220 244 } 221 245
Note: See TracChangeset
for help on using the changeset viewer.