Index: pjproject/trunk/pjsip-apps/build/vidgui.vcproj
===================================================================
--- pjproject/trunk/pjsip-apps/build/vidgui.vcproj	(revision 3686)
+++ pjproject/trunk/pjsip-apps/build/vidgui.vcproj	(revision 3686)
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="vidgui"
+	ProjectGUID="{A8EFA6F7-5443-46FA-9D35-2AF2668232EA}"
+	RootNamespace="vidgui"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+				PreprocessorDefinitions="_CONSOLE;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="QtGui4.lib QtCore4.lib Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"
+				GenerateDebugInformation="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\vidgui\moc_vidgui.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\vidgui\moc_vidwin.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\vidgui\vidgui.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\src\vidgui\vidwin.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\vidgui\vidgui.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\vidgui\vidwin.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: pjproject/trunk/pjsip-apps/src/vidgui/Makefile
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/Makefile	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/Makefile	(revision 3686)
@@ -0,0 +1,271 @@
+#############################################################################
+# Makefile for building: vidgui.app/Contents/MacOS/vidgui
+# Generated by qmake (2.01a) (Qt 4.7.3) on: Fri Jul 29 19:21:47 2011
+# Project:  vidgui.pro
+# Template: app
+# Command: /usr/bin/qmake -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile vidgui.pro
+#############################################################################
+
+PJBASE=/Users/nanang/project/pj
+include $(PJBASE)/build.mak
+
+####### Compiler, tools and options
+
+CC            = gcc
+CXX           = g++
+DEFINES       = -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
+CFLAGS        = -ObjC -pipe -g -gdwarf-2 -Wall -W $(DEFINES) $(PJ_CFLAGS)
+CXXFLAGS      = -ObjC++ -pipe -g -gdwarf-2 -Wall -W $(DEFINES) $(PJ_CFLAGS)
+INCPATH       = -I/usr/local/Qt4.7/mkspecs/macx-g++ -I. -I/Library/Frameworks/QtCore.framework/Versions/4/Headers -I/usr/include/QtCore -I/Library/Frameworks/QtGui.framework/Versions/4/Headers -I/usr/include/QtGui -I/usr/include -I. -I. -F/Library/Frameworks
+LINK          = g++
+LFLAGS        = -headerpad_max_install_names
+LIBS          = $(SUBLIBS) $(PJ_LDFLAGS) $(PJ_LDLIBS) -F/Library/Frameworks -L/Library/Frameworks -framework QtGui -framework QtCore 
+AR            = ar cq
+RANLIB        = ranlib -s
+QMAKE         = /usr/bin/qmake
+TAR           = tar -cf
+COMPRESS      = gzip -9f
+COPY          = cp -f
+SED           = sed
+COPY_FILE     = cp -f
+COPY_DIR      = cp -f -R
+STRIP         = 
+INSTALL_FILE  = $(COPY_FILE)
+INSTALL_DIR   = $(COPY_DIR)
+INSTALL_PROGRAM = $(COPY_FILE)
+DEL_FILE      = rm -f
+SYMLINK       = ln -f -s
+DEL_DIR       = rmdir
+MOVE          = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR         = mkdir -p
+export MACOSX_DEPLOYMENT_TARGET = 10.4
+
+####### Output directory
+
+OBJECTS_DIR   = ./
+
+####### Files
+
+SOURCES       = vidgui.cpp \
+		vidwin.cpp moc_vidgui.cpp \
+		moc_vidwin.cpp
+OBJECTS       = vidgui.o \
+		vidwin.o \
+		moc_vidgui.o \
+		moc_vidwin.o
+DIST          = /usr/local/Qt4.7/mkspecs/common/unix.conf \
+		/usr/local/Qt4.7/mkspecs/common/mac.conf \
+		/usr/local/Qt4.7/mkspecs/common/mac-g++.conf \
+		/usr/local/Qt4.7/mkspecs/qconfig.pri \
+		/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri \
+		/usr/local/Qt4.7/mkspecs/features/qt_functions.prf \
+		/usr/local/Qt4.7/mkspecs/features/qt_config.prf \
+		/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf \
+		/usr/local/Qt4.7/mkspecs/features/default_pre.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf \
+		/usr/local/Qt4.7/mkspecs/features/debug.prf \
+		/usr/local/Qt4.7/mkspecs/features/default_post.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf \
+		/usr/local/Qt4.7/mkspecs/features/warn_on.prf \
+		/usr/local/Qt4.7/mkspecs/features/qt.prf \
+		/usr/local/Qt4.7/mkspecs/features/unix/thread.prf \
+		/usr/local/Qt4.7/mkspecs/features/moc.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/rez.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf \
+		/usr/local/Qt4.7/mkspecs/features/resources.prf \
+		/usr/local/Qt4.7/mkspecs/features/uic.prf \
+		/usr/local/Qt4.7/mkspecs/features/yacc.prf \
+		/usr/local/Qt4.7/mkspecs/features/lex.prf \
+		/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf \
+		vidgui.pro
+QMAKE_TARGET  = vidgui
+DESTDIR       = 
+TARGET        = vidgui.app/Contents/MacOS/vidgui
+
+####### Custom Compiler Variables
+QMAKE_COMP_QMAKE_OBJECTIVE_CFLAGS = -pipe \
+		-g \
+		-gdwarf-2 \
+		-Wall \
+		-W
+
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile vidgui.app/Contents/PkgInfo vidgui.app/Contents/Resources/empty.lproj vidgui.app/Contents/Info.plist $(TARGET)
+
+$(TARGET):  $(OBJECTS)  
+	@$(CHK_DIR_EXISTS) vidgui.app/Contents/MacOS/ || $(MKDIR) vidgui.app/Contents/MacOS/ 
+	$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
+
+Makefile: vidgui.pro  /usr/local/Qt4.7/mkspecs/macx-g++/qmake.conf /usr/local/Qt4.7/mkspecs/common/unix.conf \
+		/usr/local/Qt4.7/mkspecs/common/mac.conf \
+		/usr/local/Qt4.7/mkspecs/common/mac-g++.conf \
+		/usr/local/Qt4.7/mkspecs/qconfig.pri \
+		/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri \
+		/usr/local/Qt4.7/mkspecs/features/qt_functions.prf \
+		/usr/local/Qt4.7/mkspecs/features/qt_config.prf \
+		/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf \
+		/usr/local/Qt4.7/mkspecs/features/default_pre.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf \
+		/usr/local/Qt4.7/mkspecs/features/debug.prf \
+		/usr/local/Qt4.7/mkspecs/features/default_post.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf \
+		/usr/local/Qt4.7/mkspecs/features/warn_on.prf \
+		/usr/local/Qt4.7/mkspecs/features/qt.prf \
+		/usr/local/Qt4.7/mkspecs/features/unix/thread.prf \
+		/usr/local/Qt4.7/mkspecs/features/moc.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/rez.prf \
+		/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf \
+		/usr/local/Qt4.7/mkspecs/features/resources.prf \
+		/usr/local/Qt4.7/mkspecs/features/uic.prf \
+		/usr/local/Qt4.7/mkspecs/features/yacc.prf \
+		/usr/local/Qt4.7/mkspecs/features/lex.prf \
+		/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf \
+		/Library/Frameworks/QtGui.framework/QtGui.prl \
+		/Library/Frameworks/QtCore.framework/QtCore.prl
+	$(QMAKE) -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile vidgui.pro
+/usr/local/Qt4.7/mkspecs/common/unix.conf:
+/usr/local/Qt4.7/mkspecs/common/mac.conf:
+/usr/local/Qt4.7/mkspecs/common/mac-g++.conf:
+/usr/local/Qt4.7/mkspecs/qconfig.pri:
+/usr/local/Qt4.7/mkspecs/modules/qt_webkit_version.pri:
+/usr/local/Qt4.7/mkspecs/features/qt_functions.prf:
+/usr/local/Qt4.7/mkspecs/features/qt_config.prf:
+/usr/local/Qt4.7/mkspecs/features/exclusive_builds.prf:
+/usr/local/Qt4.7/mkspecs/features/default_pre.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/default_pre.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/dwarf2.prf:
+/usr/local/Qt4.7/mkspecs/features/debug.prf:
+/usr/local/Qt4.7/mkspecs/features/default_post.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/default_post.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/objective_c.prf:
+/usr/local/Qt4.7/mkspecs/features/warn_on.prf:
+/usr/local/Qt4.7/mkspecs/features/qt.prf:
+/usr/local/Qt4.7/mkspecs/features/unix/thread.prf:
+/usr/local/Qt4.7/mkspecs/features/moc.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/rez.prf:
+/usr/local/Qt4.7/mkspecs/features/mac/sdk.prf:
+/usr/local/Qt4.7/mkspecs/features/resources.prf:
+/usr/local/Qt4.7/mkspecs/features/uic.prf:
+/usr/local/Qt4.7/mkspecs/features/yacc.prf:
+/usr/local/Qt4.7/mkspecs/features/lex.prf:
+/usr/local/Qt4.7/mkspecs/features/include_source_dir.prf:
+/Library/Frameworks/QtGui.framework/QtGui.prl:
+/Library/Frameworks/QtCore.framework/QtCore.prl:
+qmake:  FORCE
+	@$(QMAKE) -spec /usr/local/Qt4.7/mkspecs/macx-g++ -o Makefile vidgui.pro
+
+vidgui.app/Contents/PkgInfo: 
+	@$(CHK_DIR_EXISTS) vidgui.app/Contents || $(MKDIR) vidgui.app/Contents 
+	@$(DEL_FILE) vidgui.app/Contents/PkgInfo
+	@echo "APPL????" >vidgui.app/Contents/PkgInfo
+vidgui.app/Contents/Resources/empty.lproj: 
+	@$(CHK_DIR_EXISTS) vidgui.app/Contents/Resources || $(MKDIR) vidgui.app/Contents/Resources 
+	@touch vidgui.app/Contents/Resources/empty.lproj
+	
+vidgui.app/Contents/Info.plist: 
+	@$(CHK_DIR_EXISTS) vidgui.app/Contents || $(MKDIR) vidgui.app/Contents 
+	@$(DEL_FILE) vidgui.app/Contents/Info.plist
+	@sed -e "s,@ICON@,,g" -e "s,@EXECUTABLE@,vidgui,g" -e "s,@TYPEINFO@,????,g" /usr/local/Qt4.7/mkspecs/macx-g++/Info.plist.app >vidgui.app/Contents/Info.plist
+dist: 
+	@$(CHK_DIR_EXISTS) .tmp/vidgui1.0.0 || $(MKDIR) .tmp/vidgui1.0.0 
+	$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/vidgui1.0.0/ && $(COPY_FILE) --parents vidgui.h vidwin.h .tmp/vidgui1.0.0/ && $(COPY_FILE) --parents vidgui.cpp vidwin.cpp .tmp/vidgui1.0.0/ && (cd `dirname .tmp/vidgui1.0.0` && $(TAR) vidgui1.0.0.tar vidgui1.0.0 && $(COMPRESS) vidgui1.0.0.tar) && $(MOVE) `dirname .tmp/vidgui1.0.0`/vidgui1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/vidgui1.0.0
+
+
+clean:compiler_clean 
+	-$(DEL_FILE) $(OBJECTS)
+	-$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+	-$(DEL_FILE) -r vidgui.app
+	-$(DEL_FILE) Makefile
+
+
+check: first
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_objective_c_make_all:
+compiler_objective_c_clean:
+compiler_moc_header_make_all: moc_vidgui.cpp moc_vidwin.cpp
+compiler_moc_header_clean:
+	-$(DEL_FILE) moc_vidgui.cpp moc_vidwin.cpp
+moc_vidgui.cpp: vidgui.h
+	/Developer/Tools/Qt/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ vidgui.h -o moc_vidgui.cpp
+
+moc_vidwin.cpp: vidwin.h
+	/Developer/Tools/Qt/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ vidwin.h -o moc_vidwin.cpp
+
+compiler_rcc_make_all:
+compiler_rcc_clean:
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+	-$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_rez_source_make_all:
+compiler_rez_source_clean:
+compiler_uic_make_all:
+compiler_uic_clean:
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean 
+
+####### Compile
+
+vidgui.o: vidgui.cpp vidgui.h \
+		vidwin.h
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o vidgui.o vidgui.cpp
+
+vidwin.o: vidwin.cpp vidwin.h
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o vidwin.o vidwin.cpp
+
+moc_vidgui.o: moc_vidgui.cpp 
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_vidgui.o moc_vidgui.cpp
+
+moc_vidwin.o: moc_vidwin.cpp 
+	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_vidwin.o moc_vidwin.cpp
+
+####### Install
+
+install:   FORCE
+
+uninstall:   FORCE
+
+FORCE:
+
Index: pjproject/trunk/pjsip-apps/src/vidgui/moc_vidgui.cpp
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/moc_vidgui.cpp	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/moc_vidgui.cpp	(revision 3686)
@@ -0,0 +1,86 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'vidgui.h'
+**
+** Created: Fri Jul 29 21:57:30 2011
+**      by: The Qt Meta Object Compiler version 62 (Qt 4.7.3)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "vidgui.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'vidgui.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.7.3. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_MainWin[] = {
+
+ // content:
+       5,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       4,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+ // slots: signature, parameters, type, tag, flags
+       9,    8,    8,    8, 0x0a,
+      19,    8,    8,    8, 0x0a,
+      26,    8,    8,    8, 0x0a,
+      35,    8,    8,    8, 0x0a,
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_MainWin[] = {
+    "MainWin\0\0preview()\0call()\0hangup()\0"
+    "quit()\0"
+};
+
+const QMetaObject MainWin::staticMetaObject = {
+    { &QWidget::staticMetaObject, qt_meta_stringdata_MainWin,
+      qt_meta_data_MainWin, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &MainWin::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *MainWin::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *MainWin::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_MainWin))
+        return static_cast<void*>(const_cast< MainWin*>(this));
+    return QWidget::qt_metacast(_clname);
+}
+
+int MainWin::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        switch (_id) {
+        case 0: preview(); break;
+        case 1: call(); break;
+        case 2: hangup(); break;
+        case 3: quit(); break;
+        default: ;
+        }
+        _id -= 4;
+    }
+    return _id;
+}
+QT_END_MOC_NAMESPACE
Index: pjproject/trunk/pjsip-apps/src/vidgui/moc_vidwin.cpp
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/moc_vidwin.cpp	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/moc_vidwin.cpp	(revision 3686)
@@ -0,0 +1,69 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'vidwin.h'
+**
+** Created: Fri Jul 29 21:57:33 2011
+**      by: The Qt Meta Object Compiler version 62 (Qt 4.7.3)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "vidwin.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'vidwin.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 62
+#error "This file was generated using the moc from 4.7.3. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_VidWin[] = {
+
+ // content:
+       5,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_VidWin[] = {
+    "VidWin\0"
+};
+
+const QMetaObject VidWin::staticMetaObject = {
+    { &QWidget::staticMetaObject, qt_meta_stringdata_VidWin,
+      qt_meta_data_VidWin, 0 }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &VidWin::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *VidWin::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *VidWin::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_VidWin))
+        return static_cast<void*>(const_cast< VidWin*>(this));
+    return QWidget::qt_metacast(_clname);
+}
+
+int VidWin::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+QT_END_MOC_NAMESPACE
Index: pjproject/trunk/pjsip-apps/src/vidgui/vidgui.cpp
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/vidgui.cpp	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/vidgui.cpp	(revision 3686)
@@ -0,0 +1,592 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include "vidgui.h"
+#include "vidwin.h"
+
+#include <assert.h>
+
+#define LOG_FILE		"vidgui.log"
+
+#define SIP_DOMAIN		NULL
+//#define SIP_DOMAIN		"pjsip.org"
+#define SIP_USERNAME		"vidgui"
+#define SIP_PASSWORD		"secret"
+#define SIP_PORT		5060
+
+//#define DEFAULT_CAP_DEV		PJMEDIA_VID_DEFAULT_CAPTURE_DEV
+#define DEFAULT_CAP_DEV		1
+#define DEFAULT_REND_DEV	PJMEDIA_VID_DEFAULT_RENDER_DEV
+
+MainWin *MainWin::theInstance_;
+
+MainWin::MainWin(QWidget *parent)
+: QWidget(parent), accountId_(-1), currentCall_(-1),
+  preview_on(false), video_(NULL), video_prev_(NULL)
+{
+    theInstance_ = this;
+
+    initLayout();
+    onCallReleased();
+}
+
+MainWin::~MainWin()
+{
+    theInstance_ = NULL;
+}
+
+MainWin *MainWin::instance()
+{
+    return theInstance_;
+}
+
+void MainWin::initLayout()
+{
+    //statusBar_ = new QStatusBar(this);
+
+    /* main layout */
+    QHBoxLayout *hbox_main = new QHBoxLayout;
+    //QVBoxLayout *vbox_left = new QVBoxLayout;
+    vbox_left = new QVBoxLayout;
+    QVBoxLayout *vbox_right = new QVBoxLayout;
+    hbox_main->addLayout(vbox_left);
+    hbox_main->addLayout(vbox_right);
+
+    /* Left pane */
+    QHBoxLayout *hbox_url = new QHBoxLayout;
+    hbox_url->addWidget(new QLabel(tr("Url:")));
+    hbox_url->addWidget(url_=new QLineEdit(tr("sip:")), 1);
+    vbox_left->addLayout(hbox_url);
+
+    /* Right pane */
+    vbox_right->addWidget((localUri_ = new QLabel));
+    vbox_right->addWidget((previewButton_=new QPushButton(tr("Start Preview"))));
+    vbox_right->addWidget((callButton_=new QPushButton(tr("Call"))));
+    vbox_right->addWidget((hangupButton_=new QPushButton(tr("Hangup"))));
+    vbox_right->addWidget((quitButton_=new QPushButton(tr("Quit"))));
+
+    /* Outest layout */
+    QVBoxLayout *vbox_outest = new QVBoxLayout;
+    vbox_outest->addLayout(hbox_main);
+    vbox_outest->addWidget((statusBar_ = new QLabel));
+
+    setLayout(vbox_outest);
+
+    connect(previewButton_, SIGNAL(clicked()), this, SLOT(preview()));
+    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()));
+}
+
+void MainWin::quit()
+{
+    pjsua_destroy();
+    qApp->quit();
+}
+
+void MainWin::showStatus(const char *msg)
+{
+    //statusBar_->showMessage(msg);
+    statusBar_->setText(msg);
+    PJ_LOG(3,("vidgui.cpp", "%s", msg));
+}
+
+void MainWin::showError(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    char errline[120];
+
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    snprintf(errline, sizeof(errline), "%s error: %s", title, errmsg);
+    showStatus(errline);
+}
+
+void MainWin::onNewCall(pjsua_call_id cid, bool incoming)
+{
+    pjsua_call_info ci;
+
+    pj_assert(currentCall_ == -1);
+    currentCall_ = cid;
+
+    pjsua_call_get_info(cid, &ci);
+    url_->setText(ci.remote_info.ptr);
+    url_->setEnabled(false);
+    hangupButton_->setEnabled(true);
+
+    if (incoming) {
+	callButton_->setText(tr("Answer"));
+	callButton_->setEnabled(true);
+    } else {
+	callButton_->setEnabled(false);
+    }
+
+    //video_->setText(ci.remote_contact.ptr);
+    //video_->setWindowTitle(ci.remote_contact.ptr);
+}
+
+void MainWin::onCallReleased()
+{
+    url_->setEnabled(true);
+    callButton_->setEnabled(true);
+    callButton_->setText(tr("Call"));
+    hangupButton_->setEnabled(false);
+    currentCall_ = -1;
+
+    delete video_;
+    video_ = NULL;
+}
+
+void MainWin::preview()
+{
+    if (preview_on) {
+	delete video_prev_;
+	video_prev_ = NULL;
+
+	pjsua_vid_preview_stop(DEFAULT_CAP_DEV);
+
+	previewButton_->setText(tr("Start Preview"));
+    } else {
+	pjsua_vid_win_id wid;
+	pjsua_vid_win_info wi;
+
+	pjsua_vid_preview_start(DEFAULT_CAP_DEV, NULL);
+	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);
+	vbox_left->addWidget(video_prev_, 1);
+
+	previewButton_->setText(tr("Stop Preview"));
+    }
+    preview_on = !preview_on;
+}
+
+
+void MainWin::call()
+{
+    if (callButton_->text() == "Answer") {
+	pj_assert(currentCall_ != -1);
+	pjsua_call_answer(currentCall_, 200, NULL, NULL);
+	callButton_->setEnabled(false);
+    } else {
+	pj_status_t status;
+	QString dst = url_->text();
+	const char *uri = dst.toAscii().data();
+	pj_str_t uri2 = pj_str((char*)uri);
+
+	pj_assert(currentCall_ == -1);
+
+	status = pjsua_call_make_call(accountId_, &uri2, 0,
+				      NULL, NULL, &currentCall_);
+	if (status != PJ_SUCCESS) {
+	    showError("make call", status);
+	    return;
+	}
+    }
+}
+
+void MainWin::hangup()
+{
+    pj_assert(currentCall_ != -1);
+    //pjsua_call_hangup(currentCall_, PJSIP_SC_BUSY_HERE, NULL, NULL);
+    pjsua_call_hangup_all();
+    onCallReleased();
+}
+
+
+void MainWin::init_video_window()
+{
+    pjsua_call_info ci;
+    unsigned i;
+
+    if (currentCall_ == -1)
+	return;
+
+    pjsua_call_get_info(currentCall_, &ci);
+    for (i = 0; i < ci.media_cnt; ++i) {
+	if ((ci.media[i].type == PJMEDIA_TYPE_VIDEO) &&
+	    (ci.media[i].dir & PJMEDIA_DIR_DECODING))
+	{
+	    pjsua_vid_win_info wi;
+	    pjsua_vid_win_get_info(ci.media[i].stream.vid.win_in, &wi);
+
+	    video_= new VidWin(&wi.hwnd);
+	    vbox_left->addWidget(video_, 1);
+
+	    break;
+	}
+    }
+}
+
+void MainWin::on_reg_state(pjsua_acc_id acc_id)
+{
+    pjsua_acc_info info;
+
+    pjsua_acc_get_info(acc_id, &info);
+
+    char reg_status[80];
+    char status[120];
+
+    if (!info.has_registration) {
+	pj_ansi_snprintf(reg_status, sizeof(reg_status), "%.*s",
+			 (int)info.status_text.slen,
+			 info.status_text.ptr);
+
+    } else {
+	pj_ansi_snprintf(reg_status, sizeof(reg_status),
+			 "%d/%.*s (expires=%d)",
+			 info.status,
+			 (int)info.status_text.slen,
+			 info.status_text.ptr,
+			 info.expires);
+
+    }
+
+    snprintf(status, sizeof(status),
+	     "%.*s: %s\n",
+	     (int)info.acc_uri.slen, info.acc_uri.ptr,
+	     reg_status);
+    showStatus(status);
+}
+
+void MainWin::on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    pjsua_call_info ci;
+
+    PJ_UNUSED_ARG(e);
+
+    pjsua_call_get_info(call_id, &ci);
+
+    if (currentCall_ == -1 && ci.state < PJSIP_INV_STATE_DISCONNECTED) {
+	onNewCall(call_id, false);
+    }
+
+    char status[80];
+    if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
+	snprintf(status, sizeof(status), "Call is %s (%s)",
+	         ci.state_text.ptr,
+	         ci.last_status_text.ptr);
+	showStatus(status);
+	onCallReleased();
+    } else {
+	snprintf(status, sizeof(status), "Call is %s", pjsip_inv_state_name(ci.state));
+	showStatus(status);
+    }
+}
+
+void MainWin::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+                               pjsip_rx_data *rdata)
+{
+    PJ_UNUSED_ARG(acc_id);
+    PJ_UNUSED_ARG(rdata);
+
+    if (currentCall_ != -1) {
+	pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, NULL, NULL);
+	return;
+    }
+
+    onNewCall(call_id, true);
+
+    pjsua_call_info ci;
+    char status[80];
+
+    pjsua_call_get_info(call_id, &ci);
+    snprintf(status, sizeof(status), "Incoming call from %.*s",
+             (int)ci.remote_info.slen, ci.remote_info.ptr);
+    showStatus(status);
+}
+
+void MainWin::on_call_media_state(pjsua_call_id call_id)
+{
+    pjsua_call_info ci;
+
+    pjsua_call_get_info(call_id, &ci);
+
+    for (unsigned i=0; i<ci.media_cnt; ++i) {
+	if (ci.media[i].type == PJMEDIA_TYPE_AUDIO) {
+	    switch (ci.media[i].status) {
+	    case PJSUA_CALL_MEDIA_ACTIVE:
+		pjsua_conf_connect(ci.media[i].stream.aud.conf_slot, 0);
+		pjsua_conf_connect(0, ci.media[i].stream.aud.conf_slot);
+		break;
+	    default:
+		break;
+	    }
+	} else if (ci.media[i].type == PJMEDIA_TYPE_VIDEO) {
+	    init_video_window();
+	}
+    }
+}
+
+//
+// pjsua callbacks
+//
+static void on_reg_state(pjsua_acc_id acc_id)
+{
+    MainWin::instance()->on_reg_state(acc_id);
+}
+
+static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
+{
+    MainWin::instance()->on_call_state(call_id, e);
+}
+
+static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
+                             pjsip_rx_data *rdata)
+{
+    MainWin::instance()->on_incoming_call(acc_id, call_id, rdata);
+}
+
+static void on_call_media_state(pjsua_call_id call_id)
+{
+    MainWin::instance()->on_call_media_state(call_id);
+}
+
+//
+// initStack()
+//
+bool MainWin::initStack()
+{
+    pj_status_t status;
+
+    //showStatus("Creating stack..");
+    status = pjsua_create();
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_create", status);
+	return false;
+    }
+
+    showStatus("Initializing stack..");
+
+    pjsua_config ua_cfg;
+    pjsua_config_default(&ua_cfg);
+    pjsua_callback ua_cb;
+    pj_bzero(&ua_cb, sizeof(ua_cb));
+    ua_cfg.cb.on_reg_state = &::on_reg_state;
+    ua_cfg.cb.on_call_state = &::on_call_state;
+    ua_cfg.cb.on_incoming_call = &::on_incoming_call;
+    ua_cfg.cb.on_call_media_state = &::on_call_media_state;
+
+    pjsua_logging_config log_cfg;
+    pjsua_logging_config_default(&log_cfg);
+    log_cfg.log_filename = pj_str((char*)LOG_FILE);
+
+    pjsua_media_config med_cfg;
+    pjsua_media_config_default(&med_cfg);
+
+    status = pjsua_init(&ua_cfg, &log_cfg, &med_cfg);
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_init", status);
+	goto on_error;
+    }
+
+    //
+    // Create UDP and TCP transports
+    //
+    pjsua_transport_config udp_cfg;
+    pjsua_transport_id udp_id;
+    pjsua_transport_config_default(&udp_cfg);
+    udp_cfg.port = SIP_PORT;
+
+    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
+                                    &udp_cfg, &udp_id);
+    if (status != PJ_SUCCESS) {
+	showError("UDP transport creation", status);
+	goto on_error;
+    }
+
+    pjsua_transport_info udp_info;
+    status = pjsua_transport_get_info(udp_id, &udp_info);
+    if (status != PJ_SUCCESS) {
+	showError("UDP transport info", status);
+	goto on_error;
+    }
+
+    pjsua_transport_config tcp_cfg;
+    pjsua_transport_config_default(&tcp_cfg);
+    tcp_cfg.port = 0;
+
+    status = pjsua_transport_create(PJSIP_TRANSPORT_TCP,
+                                    &tcp_cfg, NULL);
+    if (status != PJ_SUCCESS) {
+	showError("TCP transport creation", status);
+	goto on_error;
+    }
+
+    //
+    // Create account
+    //
+    pjsua_acc_config acc_cfg;
+    pjsua_acc_config_default(&acc_cfg);
+#if SIP_DOMAIN
+    acc_cfg.id = pj_str( "sip:" SIP_USERNAME "@" SIP_DOMAIN);
+    acc_cfg.reg_uri = pj_str((char*) ("sip:" SIP_DOMAIN));
+    acc_cfg.cred_count = 1;
+    acc_cfg.cred_info[0].realm = pj_str((char*)"*");
+    acc_cfg.cred_info[0].scheme = pj_str((char*)"digest");
+    acc_cfg.cred_info[0].username = pj_str((char*)SIP_USERNAME);
+    acc_cfg.cred_info[0].data = pj_str((char*)SIP_PASSWORD);
+#else
+    char sip_id[80];
+    snprintf(sip_id, sizeof(sip_id),
+	     "sip:%s@%.*s:%u", SIP_USERNAME,
+	     (int)udp_info.local_name.host.slen,
+	     udp_info.local_name.host.ptr,
+	     udp_info.local_name.port);
+    acc_cfg.id = pj_str(sip_id);
+#endif
+
+    acc_cfg.max_video_cnt = 1;
+    acc_cfg.vid_cap_dev = DEFAULT_CAP_DEV;
+    acc_cfg.vid_rend_dev = DEFAULT_REND_DEV;
+    acc_cfg.vid_in_auto_show = PJ_TRUE;
+    acc_cfg.vid_out_auto_transmit = PJ_TRUE;
+
+    status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &accountId_);
+    if (status != PJ_SUCCESS) {
+	showError("Account creation", status);
+	goto on_error;
+    }
+
+    localUri_->setText(acc_cfg.id.ptr);
+
+    //
+    // Start pjsua!
+    //
+    showStatus("Starting stack..");
+    status = pjsua_start();
+    if (status != PJ_SUCCESS) {
+	showError("pjsua_start", status);
+	goto on_error;
+    }
+
+    showStatus("Ready");
+
+    return true;
+
+on_error:
+    pjsua_destroy();
+    return false;
+}
+
+/*
+ * A simple registrar, invoked by default_mod_on_rx_request()
+ */
+static void simple_registrar(pjsip_rx_data *rdata)
+{
+    pjsip_tx_data *tdata;
+    const pjsip_expires_hdr *exp;
+    const pjsip_hdr *h;
+    unsigned cnt = 0;
+    pjsip_generic_string_hdr *srv;
+    pj_status_t status;
+
+    status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(),
+				 rdata, 200, NULL, &tdata);
+    if (status != PJ_SUCCESS)
+	return;
+
+    exp = (pjsip_expires_hdr*)
+	  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+
+    h = rdata->msg_info.msg->hdr.next;
+    while (h != &rdata->msg_info.msg->hdr) {
+	if (h->type == PJSIP_H_CONTACT) {
+	    const pjsip_contact_hdr *c = (const pjsip_contact_hdr*)h;
+	    int e = c->expires;
+
+	    if (e < 0) {
+		if (exp)
+		    e = exp->ivalue;
+		else
+		    e = 3600;
+	    }
+
+	    if (e > 0) {
+		pjsip_contact_hdr *nc = (pjsip_contact_hdr*)
+					pjsip_hdr_clone(tdata->pool, h);
+		nc->expires = e;
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)nc);
+		++cnt;
+	    }
+	}
+	h = h->next;
+    }
+
+    srv = pjsip_generic_string_hdr_create(tdata->pool, NULL, NULL);
+    srv->name = pj_str((char*)"Server");
+    srv->hvalue = pj_str((char*)"pjsua simple registrar");
+    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)srv);
+
+    pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(),
+                               rdata, tdata, NULL, NULL);
+}
+
+/* Notification on incoming request */
+static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata)
+{
+    /* Simple registrar */
+    if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+                         &pjsip_register_method) == 0)
+    {
+	simple_registrar(rdata);
+	return PJ_TRUE;
+    }
+
+    return PJ_FALSE;
+}
+
+/* The module instance. */
+static pjsip_module mod_default_handler =
+{
+    NULL, NULL,				/* prev, next.		*/
+    { (char*)"mod-default-handler", 19 },	/* Name.		*/
+    -1,					/* Id			*/
+    PJSIP_MOD_PRIORITY_APPLICATION+99,	/* Priority	        */
+    NULL,				/* load()		*/
+    NULL,				/* start()		*/
+    NULL,				/* stop()		*/
+    NULL,				/* unload()		*/
+    &default_mod_on_rx_request,		/* on_rx_request()	*/
+    NULL,				/* on_rx_response()	*/
+    NULL,				/* on_tx_request.	*/
+    NULL,				/* on_tx_response()	*/
+    NULL,				/* on_tsx_state()	*/
+
+};
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+    MainWin win;
+    win.show();
+
+    if (!win.initStack()) {
+	win.quit();
+	return 1;
+    }
+
+    /* Initialize our module to handle otherwise unhandled request */
+    pjsip_endpt_register_module(pjsua_get_pjsip_endpt(),
+				&mod_default_handler);
+
+    return app.exec();
+}
+
Index: pjproject/trunk/pjsip-apps/src/vidgui/vidgui.h
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/vidgui.h	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/vidgui.h	(revision 3686)
@@ -0,0 +1,93 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef VIDGUI_H_
+#define VIDGUI_H_
+
+#include <QApplication>
+#include <QFont>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMainWindow>
+#include <QObject>
+#include <QPushButton>
+#include <QStatusBar>
+#include <QTextEdit>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <pjsua.h>
+
+class VidWin;
+
+class MainWin : public QWidget
+{
+    Q_OBJECT
+
+public:
+    MainWin(QWidget *parent = 0);
+    virtual ~MainWin();
+
+    static MainWin *instance();
+
+    bool initStack();
+    void showError(const char *title, pj_status_t status);
+    void showStatus(const char *);
+
+public:
+    void on_reg_state(pjsua_acc_id acc_id);
+    void on_call_state(pjsua_call_id call_id, pjsip_event *e);
+    void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata);
+    void on_call_media_state(pjsua_call_id call_id);
+
+public slots:
+    void preview();
+    void call();
+    void hangup();
+    void quit();
+
+private:
+    static MainWin *theInstance_;
+    pjsua_acc_id accountId_;
+    pjsua_call_id currentCall_;
+    bool preview_on;
+
+    void onNewCall(pjsua_call_id cid, bool incoming);
+    void onCallReleased();
+
+private:
+    QPushButton *callButton_,
+		*hangupButton_,
+		*quitButton_,
+		*previewButton_;
+    QLineEdit *url_;
+    VidWin *video_;
+    VidWin *video_prev_;
+    //QStatusBar *statusBar_;
+    QLabel *statusBar_;
+    QLabel *localUri_;
+
+    QVBoxLayout *vbox_left;
+
+    void initLayout();
+    void init_video_window();
+};
+
+
+
+#endif /* VIDGUI_H_ */
Index: pjproject/trunk/pjsip-apps/src/vidgui/vidwin.cpp
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/vidwin.cpp	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/vidwin.cpp	(revision 3686)
@@ -0,0 +1,223 @@
+#include "vidwin.h"
+
+#define THIS_FILE	"vidwin.cpp"
+#define TIMER_EMBED	1
+#define TIMER_RESIZE	2
+
+void VidWin::timer_cb(pj_timer_heap_t *timer_heap,
+		      struct pj_timer_entry *entry)
+{
+    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);
+}
+
+
+VidWin::~VidWin()
+{
+    if (timer_entry.id) {
+	pjsua_cancel_timer(&timer_entry);
+	timer_entry.id = 0;
+    }
+}
+
+
+void VidWin::resizeEvent(QResizeEvent*)
+{
+    /* 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);
+}
+
+/* Platform specific code */
+
+#if defined(PJ_WIN32) && !defined(PJ_WIN32_WINCE)
+
+#include <windows.h>
+
+void VidWin::embed()
+{
+    /* Embed hwnd to widget */
+    pj_assert(hwnd.type == PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS);
+    HWND h = (HWND)hwnd.info.win.hwnd;
+    HWND new_parent = (HWND)winId();
+
+    //old_parent_hwnd.type = PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS;
+    //old_parent_hwnd.info.win.hwnd = GetParent(h);
+
+    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));
+}
+
+void VidWin::resize()
+{
+    /* Update position and size */
+    HWND h = (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()));
+}
+
+#elif defined(PJ_DARWINOS)
+
+#import<Cocoa/Cocoa.h>
+
+void VidWin::embed()
+{
+    /* 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];
+
+    //[w setStyleMask:NSBorderlessWindowMask];
+
+    //[w setParentWindow:parent];
+    [parent addChildWindow:w ordered:NSWindowAbove];
+    PJ_LOG(3, (THIS_FILE, "%p parent handle = %p", w, parent));
+}
+
+
+void VidWin::resize()
+{
+    /* 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()));
+}
+
+#elif defined(PJ_LINUX)
+
+#include <X11/Xlib.h>
+//#include <QX11Info>
+
+void VidWin::embed()
+{
+    /* 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();
+    Window w = (Window)hwnd.info.x11.window;
+    Window parent = (Window)this->winId();
+
+    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::resize()
+{
+    /* Update position and size */
+    Display *d = (Display*)hwnd.info.x11.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);
+}
+
+#endif
+
Index: pjproject/trunk/pjsip-apps/src/vidgui/vidwin.h
===================================================================
--- pjproject/trunk/pjsip-apps/src/vidgui/vidwin.h	(revision 3686)
+++ pjproject/trunk/pjsip-apps/src/vidgui/vidwin.h	(revision 3686)
@@ -0,0 +1,33 @@
+#ifndef VIDWIN_H
+#define VIDWIN_H
+
+#include <pjsua.h>
+#include <QWidget>
+
+class VidWin : public QWidget
+{
+    Q_OBJECT
+
+public:
+    // hwnd	    Handle of the video rendering window.
+    VidWin(pjmedia_vid_dev_hwnd *hwnd = NULL, 
+	   QWidget* parent = 0,
+	   Qt::WindowFlags f = 0);
+    virtual ~VidWin();
+
+protected:
+    void resizeEvent(QResizeEvent *e);
+
+private:
+    pjmedia_vid_dev_hwnd hwnd;
+    //pjmedia_vid_dev_hwnd old_parent_hwnd;
+    pj_timer_entry timer_entry;
+
+    static void timer_cb(pj_timer_heap_t *timer_heap,
+			 struct pj_timer_entry *entry);
+
+    void embed();
+    void resize();
+};
+
+#endif
