summaryrefslogtreecommitdiff
path: root/pjsip-apps
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2011-08-15 22:29:14 +0000
committerNanang Izzuddin <nanang@teluu.com>2011-08-15 22:29:14 +0000
commitc025a52704d7f98d47a39ff51bc3f4b9f4e13f23 (patch)
tree0172b2423051baf626a4a67e56e7e42397fc5132 /pjsip-apps
parent2f5438b0eab01ab38093964d9658331aaac3aea2 (diff)
Re #1327, some fixes on the simple GUI app:
- Removed timer usage in resizing window, window resizing can be done real-time now (see r3698). - Fixed linking problem on Windows platform: undefined 'main' function. - Fixed build problem on Mac, compiling .cpp file containing objective C/C++ codes with g++ needs '-ObjC++' flag. - Minor changes in vidgui, e.g: function/variable rename, cleaning up unused/junk lines. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3699 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip-apps')
-rw-r--r--pjsip-apps/src/vidgui/vidgui.cpp16
-rw-r--r--pjsip-apps/src/vidgui/vidgui.pro5
-rw-r--r--pjsip-apps/src/vidgui/vidwin.cpp302
-rw-r--r--pjsip-apps/src/vidgui/vidwin.h20
4 files changed, 189 insertions, 154 deletions
diff --git a/pjsip-apps/src/vidgui/vidgui.cpp b/pjsip-apps/src/vidgui/vidgui.cpp
index ca638634..4615ccdb 100644
--- a/pjsip-apps/src/vidgui/vidgui.cpp
+++ b/pjsip-apps/src/vidgui/vidgui.cpp
@@ -19,6 +19,10 @@
#include "vidgui.h"
#include "vidwin.h"
+#if defined(PJ_WIN32)
+# define SDL_MAIN_HANDLED
+#endif
+
#include <SDL.h>
#include <assert.h>
#include <QMessageBox>
@@ -50,6 +54,7 @@ MainWin::MainWin(QWidget *parent)
MainWin::~MainWin()
{
+ quit();
theInstance_ = NULL;
}
@@ -94,7 +99,7 @@ void MainWin::initLayout()
connect(callButton_, SIGNAL(clicked()), this, SLOT(call()));
connect(hangupButton_, SIGNAL(clicked()), this, SLOT(hangup()));
connect(quitButton_, SIGNAL(clicked()), this, SLOT(quit()));
- connect(this, SIGNAL(close()), this, SLOT(quit()));
+ //connect(this, SIGNAL(close()), this, SLOT(quit()));
}
void MainWin::quit()
@@ -167,9 +172,13 @@ void MainWin::preview()
} else {
pjsua_vid_win_id wid;
pjsua_vid_win_info wi;
+ pjsua_vid_preview_param pre_param;
pj_status_t status;
- status = pjsua_vid_preview_start(DEFAULT_CAP_DEV, NULL);
+ pj_bzero(&pre_param, sizeof(pre_param));
+ pre_param.rend_id = DEFAULT_REND_DEV;
+
+ status = pjsua_vid_preview_start(DEFAULT_CAP_DEV, &pre_param);
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
@@ -179,8 +188,7 @@ void MainWin::preview()
wid = pjsua_vid_preview_get_win(DEFAULT_CAP_DEV);
pjsua_vid_win_get_info(wid, &wi);
- video_prev_= new VidWin(&wi.hwnd);
- video_prev_->setMinimumSize(320,200);
+ video_prev_ = new VidWin(&wi.hwnd);
vbox_left->addWidget(video_prev_, 1);
previewButton_->setText(tr("Stop Preview"));
diff --git a/pjsip-apps/src/vidgui/vidgui.pro b/pjsip-apps/src/vidgui/vidgui.pro
index 5bf74ca8..eba5baf9 100644
--- a/pjsip-apps/src/vidgui/vidgui.pro
+++ b/pjsip-apps/src/vidgui/vidgui.pro
@@ -19,8 +19,11 @@ win32 {
} else {
LIBS += $$system(make -f pj-pkgconfig.mak ldflags)
QMAKE_CXXFLAGS += $$system(make -f pj-pkgconfig.mak cflags)
-}
+ macx {
+ QMAKE_CXXFLAGS += -ObjC++
+ }
+}
TEMPLATE = app
CONFIG += thread debug
diff --git a/pjsip-apps/src/vidgui/vidwin.cpp b/pjsip-apps/src/vidgui/vidwin.cpp
index 8e207e4e..c8498242 100644
--- a/pjsip-apps/src/vidgui/vidwin.cpp
+++ b/pjsip-apps/src/vidgui/vidwin.cpp
@@ -1,222 +1,246 @@
#include "vidwin.h"
+#include <QEvent>
#define THIS_FILE "vidwin.cpp"
-#define TIMER_EMBED 1
-#define TIMER_RESIZE 2
+#define TRACE_(...) PJ_LOG(4,(THIS_FILE, __VA_ARGS__))
-void VidWin::timer_cb(pj_timer_heap_t *timer_heap,
- struct pj_timer_entry *entry)
+VidWin::VidWin(const pjmedia_vid_dev_hwnd *hwnd_,
+ QWidget* parent,
+ Qt::WindowFlags f) :
+ QWidget(parent, f), orig_parent(NULL),
+ size_hint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
{
- VidWin *vw = (VidWin*)entry->user_data;
-
- PJ_UNUSED_ARG(timer_heap);
-
- switch(entry->id) {
- case TIMER_EMBED:
- vw->embed();
- vw->resize();
- break;
- case TIMER_RESIZE:
- vw->resize();
- break;
- default:
- break;
- }
-
- entry->id = 0;
-}
-
-
-VidWin::VidWin(pjmedia_vid_dev_hwnd *hwnd_, QWidget* parent, Qt::WindowFlags f) :
- QWidget(parent, f), hwnd(*hwnd_)
-{
-#if 0
- // A proof that QWidget::create() change window proc!
- // And that will cause SDL rendering not working.
- HWND h = (HWND)hwnd->info.win.hwnd;
- LONG wl;
-
- wl = GetWindowLong(h, GWL_WNDPROC);
- printf("%p old proc: %p\n", h, wl);
-
- create(WId(hwnd->info.win.hwnd), false, true);
- printf("%p qwidgetwid: %p\n", h, winId());
-
- wl = GetWindowLong(h, GWL_WNDPROC);
- printf("%p new proc: %p\n", h, wl);
-#endif
-
setAttribute(Qt::WA_NativeWindow);
- setMinimumSize(320, 200);
/* Make this widget a bit "lighter" */
- //setAttribute(Qt::WA_UpdatesDisabled);
- //setAttribute(Qt::WA_PaintOnScreen);
- //setAttribute(Qt::WA_NoSystemBackground);
- //setAttribute(Qt::WA_PaintOutsidePaintEvent);
- //setUpdatesEnabled(false);
-
- /* Schedule embed, as at this point widget initialization is not
- * completely done yet (e.g: bad size).
- */
- pj_timer_entry_init(&timer_entry, TIMER_EMBED, this, &timer_cb);
- pj_time_val delay = {0, 100};
- pjsua_schedule_timer(&timer_entry, &delay);
+ setAttribute(Qt::WA_UpdatesDisabled);
+ setAttribute(Qt::WA_PaintOnScreen);
+ setAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_PaintOutsidePaintEvent);
+ setUpdatesEnabled(false);
+
+ pj_bzero(&hwnd, sizeof(hwnd));
+ if (hwnd_) {
+ hwnd = *hwnd_;
+ }
}
VidWin::~VidWin()
{
- if (timer_entry.id) {
- pjsua_cancel_timer(&timer_entry);
- timer_entry.id = 0;
- }
+ detach();
+ pj_bzero(&hwnd, sizeof(hwnd));
+ size_hint = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ destroy(true, false);
}
-
-void VidWin::resizeEvent(QResizeEvent*)
+bool VidWin::event(QEvent *e)
{
- /* Resizing SDL window must be scheduled (via timer),
- * as on Windows platform, the SDL resizing process
- * will steal focus (SDL bug?).
- */
- if (timer_entry.id && timer_entry.id != TIMER_RESIZE)
- return;
-
- if (timer_entry.id == TIMER_RESIZE)
- pjsua_cancel_timer(&timer_entry);
-
- timer_entry.id = TIMER_RESIZE;
- timer_entry.cb = &timer_cb;
- timer_entry.user_data = this;
-
- pj_time_val delay = {0, 300};
- pjsua_schedule_timer(&timer_entry, &delay);
+ switch(e->type()) {
+ case QEvent::Resize:
+ {
+ // revert to default size hint, make it resizable
+ setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ // resize now
+ set_size();
+ }
+ break;
+ case QEvent::ParentAboutToChange:
+ get_size();
+ setFixedSize(size_hint);
+ break;
+ case QEvent::ParentChange:
+ {
+ get_size();
+ /*
+ QRect qr = rect();
+ if (qr.width() > size_hint.width())
+ size_hint.setWidth(qr.width());
+ if (qr.height() > size_hint.height())
+ size_hint.setWidth(qr.height());
+ */
+ setFixedSize(size_hint);
+ attach();
+ }
+ break;
+ default:
+ break;
+ }
+
+ return QWidget::event(e);
}
/* Platform specific code */
-#if defined(PJ_WIN32) && !defined(PJ_WIN32_WINCE)
+#if defined(_WIN32) && !defined(_WIN32_WINCE)
#include <windows.h>
-void VidWin::embed()
+void VidWin::attach()
{
- /* Embed hwnd to widget */
- pj_assert(hwnd.type == PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);
- HWND h = (HWND)hwnd.info.win.hwnd;
+ if (!hwnd.info.win.hwnd) return;
+
+ HWND w = (HWND)hwnd.info.win.hwnd;
HWND new_parent = (HWND)winId();
+ orig_parent = GetParent(w);
+
+ SetParent(w, new_parent);
+ SetWindowLong(w, GWL_STYLE, WS_CHILD);
+ ShowWindow(w, SW_SHOWNOACTIVATE);
+ TRACE_("%p new parent handle = %p", w, new_parent);
+}
- //old_parent_hwnd.type = PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS;
- //old_parent_hwnd.info.win.hwnd = GetParent(h);
+void VidWin::detach()
+{
+ if (!hwnd.info.win.hwnd) return;
- SetParent(h, new_parent);
- SetWindowLong(h, GWL_STYLE, WS_CHILD);
- ShowWindow(h, SW_SHOWNOACTIVATE);
- PJ_LOG(3, (THIS_FILE, "%p parent handle = %p", h, new_parent));
+ HWND w = (HWND)hwnd.info.win.hwnd;
+ ShowWindow(w, SW_HIDE);
+ SetParent(w, (HWND)orig_parent);
+ TRACE_("%p revert parent handle to %p", w, orig_parent);
}
-void VidWin::resize()
+void VidWin::set_size()
{
- /* Update position and size */
- HWND h = (HWND)hwnd.info.win.hwnd;
+ if (!hwnd.info.win.hwnd) return;
+
+ HWND w = (HWND)hwnd.info.win.hwnd;
QRect qr = rect();
- UINT swp_flag = SWP_SHOWWINDOW | SWP_NOACTIVATE;
- SetWindowPos(h, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);
- PJ_LOG(3, (THIS_FILE, "%p new size = %d x %d", h, qr.width(), qr.height()));
+ UINT swp_flag = SWP_NOACTIVATE;
+ SetWindowPos(w, HWND_TOP, 0, 0, qr.width(), qr.height(), swp_flag);
+ TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
}
-#elif defined(PJ_DARWINOS)
+void VidWin::get_size()
+{
+ if (!hwnd.info.win.hwnd) return;
+
+ HWND w = (HWND)hwnd.info.win.hwnd;
+ RECT r;
+ if (GetWindowRect(w, &r))
+ size_hint = QSize(r.right-r.left+1, r.bottom-r.top+1);
+ TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
+}
+
+#elif defined(__APPLE__)
#import<Cocoa/Cocoa.h>
-void VidWin::embed()
+void VidWin::attach()
{
+ if (!hwnd.info.cocoa.window) return;
+
/* Embed hwnd to widget */
- pj_assert(hwnd.type != PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);
NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
NSWindow *parent = [(NSView*)winId() window];
+ orig_parent = [w parentWindow];
//[w setStyleMask:NSBorderlessWindowMask];
+ //Can't use this, as sometime the video window may not get reparented.
//[w setParentWindow:parent];
+
[parent addChildWindow:w ordered:NSWindowAbove];
- PJ_LOG(3, (THIS_FILE, "%p parent handle = %p", w, parent));
+ TRACE_("%p new parent handle = %p", w, parent);
}
-void VidWin::resize()
+void VidWin::detach()
{
+ if (!hwnd.info.cocoa.window) return;
+
+ NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+ NSWindow *parent = [(NSView*)winId() window];
+ [parent removeChildWindow:w];
+}
+
+
+void VidWin::set_size()
+{
+ if (!hwnd.info.cocoa.window) return;
+
/* Update position and size */
NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
NSRect r;
NSView* v = (NSView*)winId();
r = [v bounds];
- //PJ_LOG(3, (THIS_FILE, "before: (%d,%d) %dx%d", r.origin.x, r.origin.y, r.size.width, r.size.height));
r = [v convertRectToBase:r];
r.origin = [[v window] convertBaseToScreen:r.origin];
- //PJ_LOG(3, (THIS_FILE, "after: (%d,%d) %dx%d", r.origin.x, r.origin.y, r.size.width, r.size.height));
QRect qr = rect();
-/*
- QPoint p = pos();
- QPoint pp = parentWidget()->pos();
- PJ_LOG(3, (THIS_FILE, "this pos: (%d,%d)", p.x(), p.y()));
- PJ_LOG(3, (THIS_FILE, "parent pos: (%d,%d)", pp.x(), pp.y()));
-
- //qr.setTopLeft(mapToGlobal(qr.topLeft()));
- r.origin.x = qr.x();
- r.origin.y = qr.y();
- r.size.width = qr.width();
- r.size.height = qr.height();
- //r.origin = [w convertBaseToScreen:r.origin];
-*/
[w setFrame:r display:NO];
- PJ_LOG(3, (THIS_FILE, "%p new size = %d x %d", w, qr.width(), qr.height()));
+ TRACE_("%p new size = %dx%d", w, qr.width(), qr.height());
}
-#elif defined(PJ_LINUX)
+void VidWin::get_size()
+{
+ if (!hwnd.info.cocoa.window) return;
+
+ NSWindow *w = (NSWindow*)hwnd.info.cocoa.window;
+
+ size_hint = QSize(300, 200);
+
+ TRACE_("%p size = %dx%d", 0, size_hint.width(), size_hint.height());
+}
+
+
+#elif defined(linux) || defined(__linux)
#include <X11/Xlib.h>
-//#include <QX11Info>
+#include <X11/Xutil.h>
+#include <QX11Info>
+#include <stdio.h>
-void VidWin::embed()
+void VidWin::attach()
{
+ if (!hwnd.info.x11.window) return;
+
/* Embed hwnd to widget */
- pj_assert(hwnd.type != PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);
- Display *d = (Display*)hwnd.info.x11.display;
- //Display *d = QX11Info::display();
+
+ // Use Qt X11 display here, using window creator X11 display may cause
+ // the window failing to embed to this QWidget.
+ //Display *d = (Display*)hwnd.info.x11.display;
+ Display *d = QX11Info::display();
Window w = (Window)hwnd.info.x11.window;
Window parent = (Window)this->winId();
+ int err = XReparentWindow(d, w, parent, 0, 0);
+ TRACE_("%p new parent handle = %p, err = %d",
+ (void*)w,(void*)parent, err);
+}
- XSetWindowBorderWidth(d, w, 0);
- int err = XReparentWindow(d, w, parent, 0, 0);
- PJ_LOG(3, (THIS_FILE, "XReparentWindow() err = %d", err));
- //XRaiseWindow(d, w);
- //XMapSubwindows(d, parent);
- //XMapWindow(d, parent);
- //XMapWindow(d, w);
- //XSync(d, False);
-
- PJ_LOG(3, (THIS_FILE, "[%p,%p] parent handle = %p", d, w, parent));
+void VidWin::detach()
+{
}
-void VidWin::resize()
+void VidWin::set_size()
{
+ if (!hwnd.info.x11.window) return;
+
/* Update position and size */
- Display *d = (Display*)hwnd.info.x11.display;
+ Display *d = QX11Info::display();
Window w = (Window)hwnd.info.x11.window;
QRect qr = rect();
- //XResizeWindow(d, w, qr.width(), qr.height());
- XMoveResizeWindow(d, w, 0, 0, qr.width(), qr.height());
- PJ_LOG(3, (THIS_FILE, "[%p,%p] new size = %d x %d", d, w, qr.width(), qr.height()));
- //XSync(d, False);
- XFlush(d);
+ int err = XResizeWindow(d, w, qr.width(), qr.height());
+ TRACE_("[%p,%p] new size = %dx%d, err = %d",
+ (void*)d, (void*)w, qr.width(), qr.height(), err);
+}
+
+void VidWin::get_size()
+{
+ if (!hwnd.info.x11.window) return;
+
+ Display *d = QX11Info::display();
+ Window w = (Window)hwnd.info.x11.window;
+
+ XWindowAttributes attr;
+ XGetWindowAttributes(d, w, &attr);
+ size_hint = QSize(attr.width, attr.height);
+ TRACE_("%p size = %dx%d", w, size_hint.width(), size_hint.height());
}
#endif
diff --git a/pjsip-apps/src/vidgui/vidwin.h b/pjsip-apps/src/vidgui/vidwin.h
index 629a960e..de6e2753 100644
--- a/pjsip-apps/src/vidgui/vidwin.h
+++ b/pjsip-apps/src/vidgui/vidwin.h
@@ -9,25 +9,25 @@ class VidWin : public QWidget
Q_OBJECT
public:
- // hwnd Handle of the video rendering window.
- VidWin(pjmedia_vid_dev_hwnd *hwnd = NULL,
+ VidWin(const pjmedia_vid_dev_hwnd *hwnd,
QWidget* parent = 0,
Qt::WindowFlags f = 0);
virtual ~VidWin();
+ QSize sizeHint() const { return size_hint; }
protected:
- void resizeEvent(QResizeEvent *e);
+ virtual bool event(QEvent *e);
private:
pjmedia_vid_dev_hwnd hwnd;
- //pjmedia_vid_dev_hwnd old_parent_hwnd;
- pj_timer_entry timer_entry;
+ void *orig_parent;
+ QSize size_hint;
- static void timer_cb(pj_timer_heap_t *timer_heap,
- struct pj_timer_entry *entry);
-
- void embed();
- void resize();
+ void attach();
+ void detach();
+ void set_size();
+ void get_size();
};
#endif
+