Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2276 lines
45 KiB

  1. // File: confroom.cpp
  2. #include "precomp.h"
  3. #include "resource.h"
  4. #include "ConfPolicies.h"
  5. #include "ConfRoom.h"
  6. #include "ConfWnd.h"
  7. #include "cmd.h"
  8. #include "RoomList.h"
  9. #include "RToolbar.h"
  10. #include "TopWindow.h"
  11. #include "FloatBar.h"
  12. #include "StatBar.h"
  13. #include "DShowDlg.h"
  14. #include "SDialDlg.h"
  15. #include "UPropDlg.h"
  16. #include "PopupMsg.h"
  17. #include "splash.h"
  18. #include <version.h> // About Box
  19. #include <pbt.h>
  20. #include <EndSesn.h>
  21. #include "taskbar.h"
  22. #include "conf.h"
  23. #include "MenuUtil.h"
  24. #include "call.h"
  25. #include "ConfApi.h"
  26. #include "NmLdap.h"
  27. #include "VidView.h"
  28. #include "dbgMenu.h"
  29. #include "IndeoPal.h"
  30. #include "setupdd.h"
  31. #include "audiowiz.h"
  32. #include <help_ids.h>
  33. #include "cr.h"
  34. #include "audioctl.h"
  35. #include "particip.h"
  36. #include "confman.h"
  37. #include <nmremote.h>
  38. #include <tsecctrl.h>
  39. #include "t120type.h"
  40. #include "iappldr.h"
  41. #include "nmapp.h"
  42. #include "NmDispid.h"
  43. #include "FtHook.h"
  44. #include "NmManager.h"
  45. #include "dlgacd.h"
  46. #include "richaddr.h"
  47. #include "sdkinternal.h"
  48. #include "dlghost.h"
  49. static const TCHAR s_cszHtmlHelpFile[] = TEXT("conf.chm");
  50. //
  51. // GLOBAL CONFROOM
  52. //
  53. CConfRoom * g_pConfRoom;
  54. // ********************************************************
  55. // Initialize GUIDs
  56. //
  57. #pragma data_seg(".text")
  58. #define INITGUID
  59. #include <initguid.h>
  60. #include <CLinkId.h>
  61. #include <CNotifID.h>
  62. #include <confguid.h>
  63. #include <ilsguid.h>
  64. #undef INITGUID
  65. #pragma data_seg()
  66. INmConference2* GetActiveConference(void)
  67. {
  68. INmConference2* pConf = NULL;
  69. if(g_pConfRoom)
  70. {
  71. pConf = g_pConfRoom->GetActiveConference();
  72. }
  73. return pConf;
  74. }
  75. #ifdef DEBUG
  76. DWORD g_fDisplayViewStatus = 0; // Display the listview count in the status bar
  77. #endif
  78. DWORD g_dwPlaceCall = nmDlgCallNoFilter; // Place a Call options
  79. INmConference2* CConfRoom::GetActiveConference(void)
  80. {
  81. if (NULL != m_pInternalNmConference)
  82. {
  83. NM_CONFERENCE_STATE state;
  84. HRESULT hr = m_pInternalNmConference->GetState(&state);
  85. ASSERT(SUCCEEDED(hr));
  86. if (NM_CONFERENCE_IDLE != state)
  87. {
  88. return m_pInternalNmConference;
  89. }
  90. }
  91. // no active conference
  92. return NULL;
  93. }
  94. HRESULT CConfRoom::HostConference
  95. (
  96. LPCTSTR pcszName,
  97. LPCTSTR pcszPassword,
  98. BOOL fSecure,
  99. DWORD permitFlags,
  100. UINT maxParticipants
  101. )
  102. {
  103. HRESULT hr = E_FAIL;
  104. USES_CONVERSION;
  105. INmConference *pConf = GetActiveConference();
  106. if (NULL == pConf)
  107. {
  108. ULONG uchCaps;
  109. INmManager2 *pNmMgr = CConfMan::GetNmManager();
  110. ASSERT(NULL != pNmMgr);
  111. uchCaps = NMCH_DATA | NMCH_SHARE | NMCH_FT;
  112. if (fSecure)
  113. {
  114. uchCaps |= NMCH_SECURE;
  115. }
  116. else
  117. {
  118. uchCaps |= NMCH_AUDIO | NMCH_VIDEO;
  119. }
  120. hr = pNmMgr->CreateConferenceEx(&pConf, CComBSTR(pcszName), CComBSTR(pcszPassword),
  121. uchCaps, permitFlags, maxParticipants);
  122. if (SUCCEEDED(hr))
  123. {
  124. hr = pConf->Host();
  125. pConf->Release();
  126. }
  127. pNmMgr->Release();
  128. }
  129. return hr;
  130. }
  131. BOOL CConfRoom::LeaveConference(void)
  132. {
  133. BOOL fSuccess = TRUE;
  134. INmConference *pConf = GetActiveConference();
  135. if (NULL != pConf)
  136. {
  137. HCURSOR hCurPrev = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
  138. HRESULT hr = pConf->Leave();
  139. ::SetCursor(hCurPrev);
  140. fSuccess = SUCCEEDED(hr);
  141. }
  142. return fSuccess;
  143. }
  144. /* F H A S C H I L D N O D E S */
  145. /*-------------------------------------------------------------------------
  146. %%Function: FHasChildNodes
  147. Future: Check if ANY participants have this node as their parent.
  148. -------------------------------------------------------------------------*/
  149. BOOL CConfRoom::FHasChildNodes(void)
  150. {
  151. return m_fTopProvider;
  152. }
  153. /* G E T M A I N W I N D O W */
  154. /*-------------------------------------------------------------------------
  155. %%Function: GetMainWindow
  156. -------------------------------------------------------------------------*/
  157. HWND GetMainWindow(void)
  158. {
  159. CConfRoom* pcr = ::GetConfRoom();
  160. if (NULL == pcr)
  161. return NULL;
  162. return pcr->GetTopHwnd();
  163. }
  164. BOOL FIsConferenceActive(void)
  165. {
  166. CConfRoom *pcr = ::GetConfRoom();
  167. if (NULL != pcr)
  168. {
  169. return pcr->FIsConferenceActive();
  170. }
  171. return FALSE;
  172. }
  173. /****************************************************************************
  174. *
  175. * FUNCTION: UpdateUI(DWORD dwUIMask)
  176. *
  177. * PURPOSE: Updates the UI (flags in cr.h)
  178. *
  179. ****************************************************************************/
  180. VOID UpdateUI(DWORD dwUIMask, BOOL fPostMsg)
  181. {
  182. CConfRoom* pcr;
  183. if (NULL != (pcr = ::GetConfRoom()))
  184. {
  185. if (fPostMsg)
  186. {
  187. FORWARD_WM_COMMAND(pcr->GetTopHwnd(), ID_PRIVATE_UPDATE_UI, NULL, dwUIMask, ::PostMessage);
  188. }
  189. else
  190. {
  191. pcr->UpdateUI(dwUIMask);
  192. }
  193. }
  194. if (CRUI_TASKBARICON & dwUIMask)
  195. {
  196. ::RefreshTaskbarIcon(::GetHiddenWindow());
  197. }
  198. }
  199. //
  200. // Start/Stop App Sharing
  201. //
  202. VOID CConfRoom::StartAppSharing()
  203. {
  204. HRESULT hr;
  205. ASSERT(!m_pAS);
  206. hr = CreateASObject(this, 0, &m_pAS);
  207. if (FAILED(hr))
  208. {
  209. ERROR_OUT(("CConfRoom: unable to start App Sharing"));
  210. }
  211. }
  212. VOID CConfRoom::TerminateAppSharing()
  213. {
  214. if (m_pAS)
  215. {
  216. m_pAS->Release();
  217. m_pAS = NULL;
  218. }
  219. }
  220. /****************************************************************************
  221. *
  222. * FUNCTION: UIEndSession(BOOL fLogoff)
  223. *
  224. * PURPOSE: Handles the WM_ENDSESSION at the UI level
  225. *
  226. ****************************************************************************/
  227. VOID CConfRoom::UIEndSession(BOOL fLogoff)
  228. {
  229. DebugEntry(UIEndSession);
  230. CConfRoom* pcr;
  231. if (NULL != (pcr = ::GetConfRoom()))
  232. {
  233. TRACE_OUT(("UIEndSession: calling SaveSettings()"));
  234. pcr->SaveSettings();
  235. if (fLogoff)
  236. {
  237. pcr->TerminateAppSharing();
  238. }
  239. }
  240. DebugExitVOID(UIEndSession);
  241. }
  242. /****************************************************************************
  243. *
  244. * FUNCTION: ConfRoomInit(HANDLE hInstance)
  245. *
  246. * PURPOSE: Initializes window data and registers window class
  247. *
  248. ****************************************************************************/
  249. BOOL ConfRoomInit(HANDLE hInstance)
  250. {
  251. // Ensure the common controls are loaded
  252. INITCOMMONCONTROLSEX icc;
  253. icc.dwSize = sizeof(icc);
  254. icc.dwICC = ICC_WIN95_CLASSES | ICC_COOL_CLASSES | ICC_USEREX_CLASSES;
  255. InitCommonControlsEx(&icc);
  256. // Fill out the standard window class settings
  257. WNDCLASSEX wc;
  258. ClearStruct(&wc);
  259. wc.cbSize = sizeof(wc);
  260. wc.cbWndExtra = (int) sizeof(LPVOID);
  261. wc.hInstance = _Module.GetModuleInstance();
  262. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  263. wc.hIcon = LoadIcon((HINSTANCE) hInstance, MAKEINTRESOURCE(IDI_CONFROOM));
  264. // Floating Toolbar
  265. wc.lpfnWndProc = (WNDPROC) CFloatToolbar::FloatWndProc;
  266. wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
  267. wc.lpszClassName = g_szFloatWndClass;
  268. RegisterClassEx(&wc);
  269. // Popup Messages
  270. wc.lpfnWndProc = (WNDPROC) CPopupMsg::PMWndProc;
  271. wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
  272. wc.lpszClassName = g_szPopupMsgWndClass;
  273. RegisterClassEx(&wc);
  274. // Make sure no one changed these on us
  275. ASSERT(wc.cbSize == sizeof(wc));
  276. ASSERT(wc.style == 0);
  277. ASSERT(wc.cbClsExtra == 0);
  278. ASSERT(wc.cbWndExtra == (int) sizeof(LPVOID));
  279. ASSERT(wc.hInstance == _Module.GetModuleInstance());
  280. ASSERT(wc.hCursor == LoadCursor(NULL, IDC_ARROW));
  281. return TRUE;
  282. }
  283. /* C R E A T E C O N F R O O M W I N D O W */
  284. /*-------------------------------------------------------------------------
  285. %%Function: CreateConfRoomWindow
  286. -------------------------------------------------------------------------*/
  287. BOOL CreateConfRoomWindow(BOOL fShowUI)
  288. {
  289. if (!g_pConfRoom)
  290. {
  291. g_pConfRoom = new CConfRoom;
  292. if (NULL == g_pConfRoom)
  293. {
  294. return FALSE;
  295. }
  296. }
  297. if (g_pConfRoom->FIsClosing())
  298. {
  299. return FALSE;
  300. }
  301. CTopWindow * pWnd = g_pConfRoom->GetTopWindow();
  302. if (NULL == pWnd)
  303. {
  304. g_pConfRoom->Init();
  305. HWND hwnd = g_pConfRoom->Create(fShowUI);
  306. if (NULL == hwnd)
  307. {
  308. return FALSE;
  309. }
  310. g_pConfRoom->UpdateUI(CRUI_TITLEBAR);
  311. }
  312. else if (fShowUI)
  313. {
  314. // Bring the window to the front
  315. g_pConfRoom->BringToFront();
  316. }
  317. return TRUE;
  318. }
  319. /****************************************************************************
  320. *
  321. * CLASS: CConfRoom
  322. *
  323. * MEMBER: CConfRoom()
  324. *
  325. * PURPOSE: Constructor - initializes variables
  326. *
  327. ****************************************************************************/
  328. CConfRoom::CConfRoom():
  329. m_pTopWindow (NULL),
  330. m_pAudioControl (NULL),
  331. m_cParticipants (0),
  332. m_pPartLocal (NULL),
  333. m_fTopProvider (FALSE),
  334. m_dwConfCookie (0),
  335. m_pInternalNmConference (NULL),
  336. m_pAS (NULL)
  337. {
  338. DbgMsg(iZONE_OBJECTS, "Obj: %08X created CConfRoom", this);
  339. if (!SysPol::AllowAddingServers())
  340. {
  341. g_dwPlaceCall |= nmDlgCallNoServerEdit;
  342. }
  343. StartAppSharing();
  344. //
  345. // Initialize meeting settings to good defaults
  346. //
  347. m_fGetPermissions = FALSE;
  348. m_settings = NM_PERMIT_ALL;
  349. m_attendeePermissions = NM_PERMIT_ALL;
  350. }
  351. /****************************************************************************
  352. *
  353. * CLASS: CConfRoom
  354. *
  355. * MEMBER: ~CConfRoom()
  356. *
  357. * PURPOSE: Destructor
  358. *
  359. ****************************************************************************/
  360. CConfRoom::~CConfRoom()
  361. {
  362. FreeDbgMenu();
  363. FreePartList();
  364. CleanUp();
  365. // Close the app...
  366. ::PostThreadMessage(_Module.m_dwThreadID, WM_QUIT, 0, 0);
  367. if (NULL != m_pTopWindow)
  368. {
  369. // Make sure we do not try this multiple times
  370. CTopWindow *pTopWindow = m_pTopWindow;
  371. m_pTopWindow = NULL;
  372. pTopWindow->Release();
  373. }
  374. if (!_Module.IsSDKCallerRTC() && m_pAudioControl)
  375. {
  376. delete m_pAudioControl;
  377. m_pAudioControl = NULL;
  378. }
  379. g_pConfRoom = NULL;
  380. DbgMsg(iZONE_OBJECTS, "Obj: %08X destroyed CConfRoom", this);
  381. }
  382. VOID CConfRoom::FreePartList(void)
  383. {
  384. // Free any remaining participants
  385. while (0 != m_PartList.GetSize())
  386. {
  387. ASSERT(m_PartList[0]);
  388. OnPersonLeft(m_PartList[0]->GetINmMember());
  389. }
  390. }
  391. /****************************************************************************
  392. *
  393. * CLASS: CConfRoom
  394. *
  395. * MEMBER: UpdateUI(DWORD dwUIMask)
  396. *
  397. * PURPOSE: Updates the appropriate pieces of the UI
  398. *
  399. ****************************************************************************/
  400. VOID CConfRoom::UpdateUI(DWORD dwUIMask)
  401. {
  402. CTopWindow *pWnd = GetTopWindow();
  403. if (NULL == pWnd)
  404. {
  405. return;
  406. }
  407. pWnd->UpdateUI(dwUIMask);
  408. }
  409. /****************************************************************************
  410. *
  411. * CLASS: CConfRoom
  412. *
  413. * MEMBER: Create()
  414. *
  415. * PURPOSE: Creates a window
  416. *
  417. ****************************************************************************/
  418. HWND CConfRoom::Create(BOOL fShowUI)
  419. {
  420. ASSERT(NULL == m_pTopWindow);
  421. m_pTopWindow = new CTopWindow();
  422. if (NULL == m_pTopWindow)
  423. {
  424. return(NULL);
  425. }
  426. m_pTopWindow->Create(this, fShowUI);
  427. return(m_pTopWindow->GetWindow());
  428. }
  429. VOID CConfRoom::CleanUp()
  430. {
  431. if (NULL != m_pInternalNmConference)
  432. {
  433. NmUnadvise(m_pInternalNmConference, IID_INmConferenceNotify2, m_dwConfCookie);
  434. m_pInternalNmConference->Release();
  435. m_pInternalNmConference = NULL;
  436. }
  437. }
  438. /****************************************************************************
  439. *
  440. * CLASS: CConfRoom
  441. *
  442. * MEMBER: SaveSettings()
  443. *
  444. * PURPOSE: Saves UI settings in the registry
  445. *
  446. ****************************************************************************/
  447. VOID CConfRoom::SaveSettings()
  448. {
  449. DebugEntry(CConfRoom::SaveSettings);
  450. RegEntry reConf(UI_KEY, HKEY_CURRENT_USER);
  451. if (NULL != m_pTopWindow)
  452. {
  453. m_pTopWindow->SaveSettings();
  454. }
  455. // Save window elements to the registry:
  456. reConf.SetValue(REGVAL_SHOW_STATUSBAR, CheckMenu_ViewStatusBar(NULL));
  457. // NOTE: CMainUI saves its settings in its destructor
  458. DebugExitVOID(CConfRoom::SaveSettings);
  459. }
  460. /****************************************************************************
  461. *
  462. * CLASS: CConfRoom
  463. *
  464. * MEMBER: BringToFront()
  465. *
  466. * PURPOSE: Restores the window (if minimized) and brings it to the front
  467. *
  468. ****************************************************************************/
  469. BOOL CConfRoom::BringToFront()
  470. {
  471. CTopWindow *pWnd = GetTopWindow();
  472. if (NULL == pWnd)
  473. {
  474. return(FALSE);
  475. }
  476. return(pWnd->BringToFront());
  477. }
  478. /****************************************************************************
  479. *
  480. * CLASS: CConfRoom
  481. *
  482. * MEMBER: ForceWindowResize()
  483. *
  484. * PURPOSE: Handles redrawing the window after something changed
  485. *
  486. ****************************************************************************/
  487. VOID CConfRoom::ForceWindowResize()
  488. {
  489. CTopWindow *pWnd = GetTopWindow();
  490. if (NULL == pWnd)
  491. {
  492. return;
  493. }
  494. pWnd->ForceWindowResize();
  495. }
  496. /****************************************************************************
  497. *
  498. * CLASS: CConfRoom
  499. *
  500. * MEMBER: OnCommand(WPARAM, LPARAM)
  501. *
  502. * PURPOSE: Handles command messages
  503. *
  504. ****************************************************************************/
  505. void CConfRoom::OnCommand(HWND hwnd, int wCommand, HWND hwndCtl, UINT codeNotify)
  506. {
  507. switch(wCommand)
  508. {
  509. case IDM_FILE_HANGUP:
  510. {
  511. OnHangup(hwnd);
  512. break;
  513. }
  514. case ID_TB_SHARING:
  515. {
  516. CmdShowSharing();
  517. break;
  518. }
  519. case ID_TB_NEWWHITEBOARD:
  520. {
  521. CmdShowNewWhiteboard(NULL);
  522. break;
  523. }
  524. case ID_TB_WHITEBOARD:
  525. {
  526. CmdShowOldWhiteboard(NULL);
  527. break;
  528. }
  529. case ID_TB_FILETRANSFER:
  530. {
  531. CmdShowFileTransfer();
  532. break;
  533. }
  534. case ID_TB_CHAT:
  535. {
  536. CmdShowChat();
  537. break;
  538. }
  539. case ID_TB_NEW_CALL:
  540. {
  541. CDlgAcd::newCall( hwnd, this );
  542. }
  543. break;
  544. case IDM_CALL_MEETINGSETTINGS:
  545. {
  546. CmdShowMeetingSettings(hwnd);
  547. break;
  548. }
  549. }
  550. }
  551. HRESULT CConfRoom::FreeAddress(
  552. RichAddressInfo **ppAddr)
  553. {
  554. return CEnumMRU::FreeAddress(ppAddr);
  555. }
  556. HRESULT CConfRoom::CopyAddress(
  557. RichAddressInfo *pAddrIn,
  558. RichAddressInfo **ppAddrOut)
  559. {
  560. return CEnumMRU::CopyAddress(pAddrIn, ppAddrOut);
  561. }
  562. HRESULT CConfRoom::GetRecentAddresses(
  563. IEnumRichAddressInfo **ppEnum)
  564. {
  565. return CEnumMRU::GetRecentAddresses(ppEnum);
  566. }
  567. /****************************************************************************
  568. *
  569. * CLASS: CConfRoom
  570. *
  571. * FUNCTION: OnCallStarted()
  572. *
  573. * PURPOSE: Handles the call started event
  574. *
  575. ****************************************************************************/
  576. VOID CConfRoom::OnCallStarted()
  577. {
  578. DebugEntry(CConfRoom::OnCallStarted);
  579. // notify ULS
  580. if(g_pLDAP)
  581. {
  582. g_pLDAP->OnCallStarted();
  583. }
  584. g_pHiddenWnd->OnCallStarted();
  585. EnterCriticalSection(&dialogListCriticalSection);
  586. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  587. LeaveCriticalSection(&dialogListCriticalSection);
  588. // BUGBUG georgep: I guess one of these things could go away after
  589. // we get the list, but I doubt it will ever happen
  590. for( int i = 0; i < tempList.GetSize(); ++i )
  591. {
  592. IConferenceChangeHandler *pHandler = tempList[i];
  593. ASSERT( NULL != pHandler );
  594. pHandler->OnCallStarted();
  595. }
  596. DebugExitVOID(CConfRoom::OnCallStarted);
  597. }
  598. /****************************************************************************
  599. *
  600. * CLASS: CConfRoom
  601. *
  602. * FUNCTION: OnCallEnded()
  603. *
  604. * PURPOSE: Handles the call ended event
  605. *
  606. ****************************************************************************/
  607. VOID CConfRoom::OnCallEnded()
  608. {
  609. DebugEntry(CConfRoom::OnCallEnded);
  610. if(g_pLDAP)
  611. {
  612. g_pLDAP->OnCallEnded();
  613. }
  614. g_pHiddenWnd->OnCallEnded();
  615. EnterCriticalSection(&dialogListCriticalSection);
  616. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  617. LeaveCriticalSection(&dialogListCriticalSection);
  618. // BUGBUG georgep: I guess one of these things could go away after
  619. // we get the list, but I doubt it will ever happen
  620. for( int i = 0; i < tempList.GetSize(); ++i )
  621. {
  622. IConferenceChangeHandler *pHandler = tempList[i];
  623. ASSERT( NULL != pHandler );
  624. pHandler->OnCallEnded();
  625. }
  626. DebugExitVOID(CConfRoom::OnCallEnded);
  627. }
  628. void CConfRoom::OnChangeParticipant(CParticipant *pPart, NM_MEMBER_NOTIFY uNotify)
  629. {
  630. EnterCriticalSection(&dialogListCriticalSection);
  631. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  632. LeaveCriticalSection(&dialogListCriticalSection);
  633. // BUGBUG georgep: I guess one of these things could go away after
  634. // we get the list, but I doubt it will ever happen
  635. for( int i = 0; i < tempList.GetSize(); ++i )
  636. {
  637. IConferenceChangeHandler *pHandler = tempList[i];
  638. ASSERT( NULL != pHandler );
  639. pHandler->OnChangeParticipant(pPart, uNotify);
  640. }
  641. }
  642. void CConfRoom::OnChangePermissions()
  643. {
  644. EnterCriticalSection(&dialogListCriticalSection);
  645. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  646. LeaveCriticalSection(&dialogListCriticalSection);
  647. // BUGBUG georgep: I guess one of these things could go away after
  648. // we get the list, but I doubt it will ever happen
  649. for( int i = 0; i < tempList.GetSize(); ++i )
  650. {
  651. IConferenceChangeHandler *pHandler = tempList[i];
  652. ASSERT( NULL != pHandler );
  653. pHandler->OnChangePermissions();
  654. }
  655. }
  656. /****************************************************************************
  657. *
  658. * CLASS: CConfRoom
  659. *
  660. * FUNCTION: OnHangup(BOOL fNeedConfirm)
  661. *
  662. * PURPOSE: Handles the action after a user chooses to hang up
  663. *
  664. ****************************************************************************/
  665. BOOL CConfRoom::OnHangup(HWND hwndParent, BOOL fNeedConfirm)
  666. {
  667. DebugEntry(CConfRoom::OnHangup);
  668. BOOL bRet = FALSE;
  669. CancelAllCalls();
  670. if (FIsConferenceActive())
  671. {
  672. if (T120_NO_ERROR == T120_QueryApplet(APPLET_ID_FT, APPLET_QUERY_SHUTDOWN))
  673. {
  674. if ((FALSE == fNeedConfirm) ||
  675. ( ((GetMemberCount() <= 2) ||
  676. (FALSE == FHasChildNodes()))) ||
  677. (IDYES == ::ConfMsgBox( hwndParent,
  678. (LPCTSTR) IDS_HANGUP_ATTEMPT,
  679. MB_YESNO | MB_ICONQUESTION)))
  680. {
  681. // BUGBUG: Should we wait for the async response?
  682. bRet = (0 == LeaveConference());
  683. }
  684. }
  685. }
  686. DebugExitBOOL(CConfRoom::OnHangup, bRet);
  687. return bRet;
  688. }
  689. /* C H E C K T O P P R O V I D E R */
  690. /*-------------------------------------------------------------------------
  691. %%Function: CheckTopProvider
  692. -------------------------------------------------------------------------*/
  693. VOID CConfRoom::CheckTopProvider(void)
  694. {
  695. if ((NULL == m_pInternalNmConference) || (NULL == m_pPartLocal))
  696. return;
  697. INmMember * pMember;
  698. if (S_OK != m_pInternalNmConference->GetTopProvider(&pMember))
  699. return;
  700. ASSERT(NULL != pMember);
  701. if (m_pPartLocal->GetINmMember() == pMember)
  702. {
  703. m_fTopProvider = TRUE;
  704. }
  705. if (m_fGetPermissions)
  706. {
  707. ASSERT(m_settings == NM_PERMIT_ALL);
  708. ASSERT(m_attendeePermissions == NM_PERMIT_ALL);
  709. m_fGetPermissions = FALSE;
  710. //
  711. // Get the meeting settings from the top provider
  712. //
  713. PBYTE pb = NULL;
  714. ULONG cb = 0;
  715. if (pMember->GetUserData(g_csguidMeetingSettings, &pb, &cb) == S_OK)
  716. {
  717. ASSERT(cb == sizeof(NM30_MTG_PERMISSIONS));
  718. CopyMemory(&m_settings, pb, min(cb, sizeof(m_settings)));
  719. CoTaskMemFree(pb);
  720. WARNING_OUT(("CONF: Meeting host set permissions 0%08lx",
  721. m_settings));
  722. if (!m_fTopProvider)
  723. {
  724. //
  725. // The meeting settings are permissions for everybody else
  726. // besides the top provider.
  727. //
  728. m_attendeePermissions = m_settings;
  729. if (m_attendeePermissions != NM_PERMIT_ALL)
  730. {
  731. OnChangePermissions();
  732. // Bring up meeting settings
  733. PostMessage(GetTopHwnd(), WM_COMMAND, IDM_CALL_MEETINGSETTINGS, 0);
  734. }
  735. }
  736. }
  737. }
  738. }
  739. /****************************************************************************
  740. *
  741. * CLASS: CConfRoom
  742. *
  743. * FUNCTION: OnPersonJoined(PPARTICIPANT pPart)
  744. *
  745. * PURPOSE: Notification - new person has joined the call
  746. *
  747. ****************************************************************************/
  748. BOOL CConfRoom::OnPersonJoined(INmMember * pMember)
  749. {
  750. CParticipant * pPart = new CParticipant(pMember);
  751. if (NULL == pPart)
  752. {
  753. WARNING_OUT(("CConfRoom::OnPersonJoined - Unable to create participant"));
  754. return FALSE;
  755. }
  756. m_PartList.Add(pPart);
  757. ++m_cParticipants;
  758. if (1 == m_cParticipants)
  759. {
  760. OnCallStarted();
  761. }
  762. TRACE_OUT(("CConfRoom::OnPersonJoined - Added participant=%08X", pPart));
  763. OnChangeParticipant(pPart, NM_MEMBER_ADDED);
  764. // Popup a notification (if it isn't us)
  765. if (!pPart->FLocal())
  766. {
  767. TCHAR szSound[256];
  768. //
  769. // Play the "somebody joined" sound
  770. //
  771. ::LoadString(::GetInstanceHandle(), IDS_PERSON_JOINED_SOUND,
  772. szSound, CCHMAX(szSound));
  773. if (!::PlaySound(szSound, NULL,
  774. SND_APPLICATION | SND_ALIAS | SND_ASYNC | SND_NOWAIT))
  775. {
  776. // Use the computer speaker to beep:
  777. TRACE_OUT(("PlaySound() failed, trying MessageBeep()"));
  778. ::MessageBeep(0xFFFFFFFF);
  779. }
  780. }
  781. else
  782. {
  783. m_pPartLocal = pPart;
  784. CheckTopProvider();
  785. }
  786. // Title bar shows number of people in conference
  787. UpdateUI(CRUI_TITLEBAR);
  788. return TRUE;
  789. }
  790. /****************************************************************************
  791. *
  792. * CLASS: CConfRoom
  793. *
  794. * FUNCTION: OnPersonLeft(PPARTICIPANT pPart)
  795. *
  796. * PURPOSE: Notification - person has left the call
  797. *
  798. ****************************************************************************/
  799. BOOL CConfRoom::OnPersonLeft(INmMember * pMember)
  800. {
  801. // Find the macthing participant
  802. CParticipant* pPart = NULL;
  803. for( int i = 0; i < m_PartList.GetSize(); i++ )
  804. {
  805. pPart = m_PartList[i];
  806. ASSERT(pPart);
  807. if( pPart->GetINmMember() == pMember )
  808. {
  809. m_PartList.RemoveAt(i);
  810. --m_cParticipants;
  811. if (0 == m_cParticipants)
  812. {
  813. OnCallEnded();
  814. }
  815. break;
  816. }
  817. }
  818. if (NULL == pPart)
  819. {
  820. WARNING_OUT(("Unable to find participant for INmMember=%08X", pMember));
  821. return FALSE;
  822. }
  823. OnChangeParticipant(pPart, NM_MEMBER_REMOVED);
  824. // Popup a notification (if it isn't us)
  825. if (!pPart->FLocal())
  826. {
  827. TCHAR szSound[256];
  828. //
  829. // Play the "somebody left" sound
  830. //
  831. ::LoadString(::GetInstanceHandle(), IDS_PERSON_LEFT_SOUND,
  832. szSound, CCHMAX(szSound));
  833. if (!::PlaySound(szSound, NULL,
  834. SND_APPLICATION | SND_ALIAS | SND_ASYNC | SND_NOWAIT))
  835. {
  836. // Use the computer speaker to beep:
  837. TRACE_OUT(("PlaySound() failed, trying MessageBeep()"));
  838. ::MessageBeep(0xFFFFFFFF);
  839. }
  840. }
  841. else
  842. {
  843. m_pPartLocal = NULL;
  844. m_fTopProvider = FALSE;
  845. }
  846. // Title bar shows number of people in conference
  847. UpdateUI(CRUI_TITLEBAR);
  848. // Finally, release the object
  849. TRACE_OUT(("CConfRoom::OnPersonLeft - Removed participant=%08X", pPart));
  850. pPart->Release();
  851. return TRUE;
  852. }
  853. /* O N P E R S O N C H A N G E D */
  854. /*-------------------------------------------------------------------------
  855. %%Function: OnPersonChanged
  856. Notification - a person's information has changed
  857. -------------------------------------------------------------------------*/
  858. VOID CConfRoom::OnPersonChanged(INmMember * pMember)
  859. {
  860. DBGENTRY(CConfRoom::OnPersonChanged);
  861. CParticipant * pPart = ParticipantFromINmMember(pMember);
  862. if (NULL == pPart)
  863. return;
  864. pPart->AddRef();
  865. pPart->Update();
  866. if (m_fTopProvider && !pPart->FData())
  867. {
  868. // Can't be the top provider if there are no data caps
  869. m_fTopProvider = FALSE;
  870. }
  871. if (pPart->FLocal() && !m_fTopProvider)
  872. {
  873. // if H.323-only adds T.120, then we may be the top provider
  874. CheckTopProvider();
  875. }
  876. OnChangeParticipant(pPart, NM_MEMBER_UPDATED);
  877. pPart->Release();
  878. }
  879. /****************************************************************************
  880. *
  881. * CLASS: CConfRoom
  882. *
  883. * MEMBER: Init()
  884. *
  885. * PURPOSE: Object initialization function
  886. *
  887. ****************************************************************************/
  888. BOOL CConfRoom::Init()
  889. {
  890. if (!_Module.IsSDKCallerRTC())
  891. {
  892. m_pAudioControl = new CAudioControl(GetHiddenWindow());
  893. }
  894. if (NULL != m_pAudioControl)
  895. {
  896. m_pAudioControl->RegisterAudioEventHandler(this);
  897. }
  898. return (TRUE);
  899. }
  900. VOID CConfRoom::SetSpeakerVolume(DWORD dwLevel)
  901. {
  902. if (NULL != m_pAudioControl)
  903. {
  904. m_pAudioControl->SetSpeakerVolume(dwLevel);
  905. m_pAudioControl->RefreshMixer();
  906. }
  907. }
  908. VOID CConfRoom::SetRecorderVolume(DWORD dwLevel)
  909. {
  910. if (NULL != m_pAudioControl)
  911. {
  912. m_pAudioControl->SetRecorderVolume(dwLevel);
  913. m_pAudioControl->RefreshMixer();
  914. }
  915. }
  916. VOID CConfRoom::MuteSpeaker(BOOL fMute)
  917. {
  918. if (NULL != m_pAudioControl)
  919. {
  920. m_pAudioControl->MuteAudio(TRUE /* fSpeaker */, fMute);
  921. }
  922. }
  923. VOID CConfRoom::MuteMicrophone(BOOL fMute)
  924. {
  925. if (NULL != m_pAudioControl)
  926. {
  927. m_pAudioControl->MuteAudio(FALSE /* fSpeaker */, fMute);
  928. }
  929. }
  930. VOID CConfRoom::OnAudioDeviceChanged()
  931. {
  932. if (NULL != m_pAudioControl)
  933. {
  934. m_pAudioControl->OnDeviceChanged();
  935. }
  936. }
  937. VOID CConfRoom::OnAGC_Changed()
  938. {
  939. if (NULL != m_pAudioControl)
  940. {
  941. m_pAudioControl->OnAGC_Changed();
  942. }
  943. }
  944. VOID CConfRoom::OnSilenceLevelChanged()
  945. {
  946. if (NULL != m_pAudioControl)
  947. {
  948. m_pAudioControl->OnSilenceLevelChanged();
  949. }
  950. }
  951. DWORD CConfRoom::GetConferenceStatus(LPTSTR pszStatus, int cchMax, UINT * puID)
  952. {
  953. ASSERT(NULL != pszStatus);
  954. ASSERT(NULL != puID);
  955. ASSERT(cchMax > 0);
  956. // Check global conference status
  957. if ( INmConference *pConf = GetActiveConference() )
  958. {
  959. // We are in a call. Find out if it's secure.
  960. DWORD dwCaps;
  961. if ( S_OK == pConf->GetNmchCaps(&dwCaps) &&
  962. ( NMCH_SECURE & dwCaps ) )
  963. {
  964. *puID = IDS_STATUS_IN_SECURE_CALL;
  965. }
  966. else
  967. {
  968. *puID = IDS_STATUS_IN_CALL;
  969. }
  970. }
  971. else if (::FDoNotDisturb())
  972. {
  973. *puID = IDS_STATUS_DO_NOT_DISTURB;
  974. }
  975. else
  976. {
  977. *puID = IDS_STATUS_NOT_IN_CALL;
  978. }
  979. #if FALSE
  980. // We may need to find a new way of doing this if this is still useful info
  981. #ifdef DEBUG
  982. if (g_fDisplayViewStatus)
  983. {
  984. int iCount = (NULL == m_pView) ? LB_ERR :
  985. ListView_GetItemCount(m_pView->GetHwnd());
  986. wsprintf(pszStatus, TEXT("%d items"), iCount);
  987. ASSERT(lstrlen(pszStatus) < cchMax);
  988. }
  989. else
  990. #endif /* DEBUG */
  991. #endif // FALSE
  992. if (0 == ::LoadString(::GetInstanceHandle(), *puID, pszStatus, cchMax))
  993. {
  994. WARNING_OUT(("Unable to load string resource=%d", *puID));
  995. *pszStatus = _T('\0');
  996. }
  997. return 0;
  998. }
  999. /* P A R T I C I P A N T F R O M I N M M E M B E R */
  1000. /*-------------------------------------------------------------------------
  1001. %%Function: ParticipantFromINmMember
  1002. -------------------------------------------------------------------------*/
  1003. CParticipant * CConfRoom::ParticipantFromINmMember(INmMember * pMember)
  1004. {
  1005. CParticipant *pRet = NULL;
  1006. for( int i = 0; i < m_PartList.GetSize(); i++ )
  1007. {
  1008. ASSERT( m_PartList[i] );
  1009. if( m_PartList[i]->GetINmMember() == pMember )
  1010. {
  1011. pRet = m_PartList[i];
  1012. break;
  1013. }
  1014. else
  1015. {
  1016. pRet = NULL;
  1017. }
  1018. }
  1019. return pRet;
  1020. }
  1021. /* G E T H 3 2 3 R E M O T E */
  1022. /*-------------------------------------------------------------------------
  1023. %%Function: GetH323Remote
  1024. Get the matching H.323 remote user, if there is one
  1025. -------------------------------------------------------------------------*/
  1026. CParticipant * CConfRoom::GetH323Remote(void)
  1027. {
  1028. CParticipant *pRet = NULL;
  1029. for( int i = 0; i < m_PartList.GetSize(); i++ )
  1030. {
  1031. pRet = m_PartList[i];
  1032. ASSERT( pRet );
  1033. if (!pRet->FLocal() && pRet->FH323())
  1034. {
  1035. break;
  1036. }
  1037. else
  1038. {
  1039. pRet = NULL;
  1040. }
  1041. }
  1042. return pRet;
  1043. }
  1044. STDMETHODIMP_(ULONG) CConfRoom::AddRef(void)
  1045. {
  1046. return RefCount::AddRef();
  1047. }
  1048. STDMETHODIMP_(ULONG) CConfRoom::Release(void)
  1049. {
  1050. return RefCount::Release();
  1051. }
  1052. STDMETHODIMP CConfRoom::QueryInterface(REFIID riid, PVOID *ppv)
  1053. {
  1054. HRESULT hr = S_OK;
  1055. if ((riid == IID_INmConferenceNotify) || (riid == IID_INmConferenceNotify2) ||
  1056. (riid == IID_IUnknown))
  1057. {
  1058. *ppv = (INmConferenceNotify2 *)this;
  1059. ApiDebugMsg(("CConfRoom::QueryInterface()"));
  1060. }
  1061. else
  1062. {
  1063. hr = E_NOINTERFACE;
  1064. *ppv = NULL;
  1065. ApiDebugMsg(("CConfRoom::QueryInterface(): Called on unknown interface."));
  1066. }
  1067. if (S_OK == hr)
  1068. {
  1069. AddRef();
  1070. }
  1071. return hr;
  1072. }
  1073. STDMETHODIMP CConfRoom::NmUI(CONFN uNotify)
  1074. {
  1075. return S_OK;
  1076. }
  1077. STDMETHODIMP CConfRoom::OnConferenceCreated(INmConference *pConference)
  1078. {
  1079. HRESULT hr = S_OK;
  1080. DBGENTRY(CConfRoom::OnConferenceCreated);
  1081. if (NULL != m_pInternalNmConference)
  1082. {
  1083. NmUnadvise(m_pInternalNmConference, IID_INmConferenceNotify2, m_dwConfCookie);
  1084. m_pInternalNmConference->Release();
  1085. }
  1086. pConference->QueryInterface(IID_INmConference2, (void**)&m_pInternalNmConference);
  1087. NmAdvise(m_pInternalNmConference, (INmConferenceNotify2*)this, IID_INmConferenceNotify2, &m_dwConfCookie);
  1088. DBGEXIT_HR(CConfRoom::OnConferenceCreated,hr);
  1089. return hr;
  1090. }
  1091. STDMETHODIMP CConfRoom::StateChanged(NM_CONFERENCE_STATE uState)
  1092. {
  1093. static BOOL s_fInConference = FALSE;
  1094. UpdateUI(CRUI_DEFAULT);
  1095. switch (uState)
  1096. {
  1097. case NM_CONFERENCE_IDLE:
  1098. {
  1099. if (s_fInConference)
  1100. {
  1101. CNetMeetingObj::Broadcast_ConferenceEnded();
  1102. s_fInConference = FALSE;
  1103. //
  1104. // Reset meeting settings
  1105. //
  1106. m_fGetPermissions = FALSE;
  1107. m_settings = NM_PERMIT_ALL;
  1108. m_attendeePermissions = NM_PERMIT_ALL;
  1109. OnChangePermissions();
  1110. //
  1111. // If the call ends, kill the host properties if they are up.
  1112. //
  1113. CDlgHostSettings::KillHostSettings();
  1114. }
  1115. UpdateUI(CRUI_STATUSBAR);
  1116. break;
  1117. }
  1118. case NM_CONFERENCE_INITIALIZING:
  1119. break;
  1120. case NM_CONFERENCE_WAITING:
  1121. case NM_CONFERENCE_ACTIVE:
  1122. default:
  1123. {
  1124. if (!s_fInConference)
  1125. {
  1126. // Start a new conference session
  1127. CFt::StartNewConferenceSession();
  1128. CNetMeetingObj::Broadcast_ConferenceStarted();
  1129. s_fInConference = TRUE;
  1130. m_fGetPermissions = TRUE;
  1131. }
  1132. break;
  1133. }
  1134. }
  1135. return S_OK;
  1136. }
  1137. STDMETHODIMP CConfRoom::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
  1138. {
  1139. switch (uNotify)
  1140. {
  1141. case NM_MEMBER_ADDED:
  1142. OnPersonJoined(pMember);
  1143. break;
  1144. case NM_MEMBER_REMOVED:
  1145. OnPersonLeft(pMember);
  1146. break;
  1147. case NM_MEMBER_UPDATED:
  1148. OnPersonChanged(pMember);
  1149. break;
  1150. }
  1151. return S_OK;
  1152. }
  1153. STDMETHODIMP CConfRoom::ChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
  1154. {
  1155. ULONG nmch;
  1156. if (SUCCEEDED(pChannel->GetNmch(&nmch)))
  1157. {
  1158. TRACE_OUT(("CConfRoom:ChannelChanged type=%08X", nmch));
  1159. switch (nmch)
  1160. {
  1161. case NMCH_AUDIO:
  1162. if (NULL != m_pAudioControl)
  1163. {
  1164. m_pAudioControl->OnChannelChanged(uNotify, pChannel);
  1165. // Notify the Manager object of the audio channels active state
  1166. CNmManagerObj::AudioChannelActiveState(S_OK == pChannel->IsActive(), S_OK == com_cast<INmChannelAudio>(pChannel)->IsIncoming());
  1167. }
  1168. break;
  1169. case NMCH_VIDEO:
  1170. {
  1171. EnterCriticalSection(&dialogListCriticalSection);
  1172. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  1173. LeaveCriticalSection(&dialogListCriticalSection);
  1174. // BUGBUG georgep: I guess one of these things could go away after
  1175. // we get the list, but I doubt it will ever happen
  1176. for( int i = 0; i < tempList.GetSize(); ++i )
  1177. {
  1178. IConferenceChangeHandler *pHandler = tempList[i];
  1179. ASSERT( NULL != pHandler );
  1180. pHandler->OnVideoChannelChanged(uNotify, pChannel);
  1181. }
  1182. break;
  1183. }
  1184. default:
  1185. break;
  1186. }
  1187. }
  1188. return S_OK;
  1189. }
  1190. HRESULT STDMETHODCALLTYPE CConfRoom::StreamEvent(
  1191. /* [in] */ NM_STREAMEVENT uEvent,
  1192. /* [in] */ UINT uSubCode,
  1193. /* [in] */ INmChannel __RPC_FAR *pChannel)
  1194. {
  1195. return S_OK;
  1196. }
  1197. /* C M D S H O W C H A T */
  1198. /*-------------------------------------------------------------------------
  1199. %%Function: CmdShowChat
  1200. -------------------------------------------------------------------------*/
  1201. VOID CmdShowChat(void)
  1202. {
  1203. T120_LoadApplet(APPLET_ID_CHAT, TRUE , 0, FALSE, NULL);
  1204. }
  1205. //
  1206. // CmdShowFileTransfer()
  1207. //
  1208. void CConfRoom::CmdShowFileTransfer(void)
  1209. {
  1210. ::T120_LoadApplet(APPLET_ID_FT, TRUE, 0, FALSE, NULL);
  1211. }
  1212. //
  1213. // CmdShowSharing()
  1214. //
  1215. void CConfRoom::CmdShowSharing()
  1216. {
  1217. LaunchHostUI();
  1218. }
  1219. /* C M D S H O W N E W W H I T E B O A R D */
  1220. /*-------------------------------------------------------------------------
  1221. %%Function: CmdShowNewWhiteboard
  1222. -------------------------------------------------------------------------*/
  1223. BOOL CmdShowNewWhiteboard(LPCTSTR szFile)
  1224. {
  1225. return ::T120_LoadApplet(APPLET_ID_WB, TRUE , 0, FALSE, (LPSTR)szFile);
  1226. }
  1227. /* C M D S H O W W H I T E B O A R D */
  1228. /*-------------------------------------------------------------------------
  1229. %%Function: CmdShowOldWhiteboard
  1230. -------------------------------------------------------------------------*/
  1231. extern "C" { BOOL WINAPI StartStopOldWB(LPCTSTR lpsz); }
  1232. BOOL CmdShowOldWhiteboard(LPCTSTR szFile)
  1233. {
  1234. return(StartStopOldWB(szFile));
  1235. }
  1236. //
  1237. // CmdShowMeetingSettings()
  1238. //
  1239. void CConfRoom::CmdShowMeetingSettings(HWND hwnd)
  1240. {
  1241. INmConference2 * pConf;
  1242. pConf = GetActiveConference();
  1243. if (pConf)
  1244. {
  1245. DWORD caps;
  1246. HRESULT hr;
  1247. BSTR bstrName;
  1248. LPTSTR pszName = NULL;
  1249. caps = 0;
  1250. pConf->GetNmchCaps(&caps);
  1251. bstrName = NULL;
  1252. hr = pConf->GetName(&bstrName);
  1253. if (SUCCEEDED(hr))
  1254. {
  1255. BSTR_to_LPTSTR(&pszName, bstrName);
  1256. SysFreeString(bstrName);
  1257. }
  1258. CDlgHostSettings dlgSettings(FTopProvider(), pszName, caps, m_settings);
  1259. dlgSettings.DoModal(hwnd);
  1260. delete pszName;
  1261. }
  1262. }
  1263. ///////////////////////////////////////////////////////////////////////////
  1264. /* F T O P P R O V I D E R */
  1265. /*-------------------------------------------------------------------------
  1266. %%Function: FTopProvider
  1267. -------------------------------------------------------------------------*/
  1268. BOOL FTopProvider(void)
  1269. {
  1270. CConfRoom * pConfRoom = ::GetConfRoom();
  1271. if (NULL == pConfRoom)
  1272. return FALSE;
  1273. return pConfRoom->FTopProvider();
  1274. }
  1275. BOOL FRejectIncomingCalls(void)
  1276. {
  1277. BOOL bReject = TRUE;
  1278. if (!FDoNotDisturb())
  1279. {
  1280. CConfRoom * pConfRoom = ::GetConfRoom();
  1281. if( ( NULL == pConfRoom ) ||
  1282. ((pConfRoom->GetMeetingPermissions() & NM_PERMIT_INCOMINGCALLS) &&
  1283. !pConfRoom->FIsClosing()))
  1284. {
  1285. bReject = FALSE;
  1286. }
  1287. }
  1288. return bReject;
  1289. }
  1290. BOOL CConfRoom::FIsClosing()
  1291. {
  1292. return(NULL == m_pTopWindow ? FALSE : m_pTopWindow->FIsClosing());
  1293. }
  1294. BOOL FIsConfRoomClosing(void)
  1295. {
  1296. CConfRoom * pConfRoom = ::GetConfRoom();
  1297. if (NULL == pConfRoom)
  1298. return FALSE;
  1299. return pConfRoom->FIsClosing();
  1300. }
  1301. /*static*/ HRESULT CConfRoom::HangUp(BOOL bUserPrompt)
  1302. {
  1303. DBGENTRY(CConfRoom::HangUp);
  1304. HRESULT hr = S_OK;
  1305. if(g_pConfRoom)
  1306. {
  1307. g_pConfRoom->OnHangup(g_pConfRoom->GetTopHwnd(), bUserPrompt);
  1308. }
  1309. DBGEXIT_HR(CConfRoom::HangUp,hr);
  1310. return hr;
  1311. }
  1312. BOOL AllowingControl()
  1313. {
  1314. BOOL bRet = FALSE;
  1315. if(g_pConfRoom)
  1316. {
  1317. bRet = g_pConfRoom->FIsControllable();
  1318. }
  1319. return bRet;
  1320. }
  1321. HRESULT AllowControl(bool bAllowControl)
  1322. {
  1323. HRESULT hr = S_OK;
  1324. if(g_pConfRoom)
  1325. {
  1326. hr = g_pConfRoom->AllowControl(bAllowControl);
  1327. }
  1328. else
  1329. {
  1330. hr = E_UNEXPECTED;
  1331. }
  1332. return hr;
  1333. }
  1334. bool IsSpeakerMuted()
  1335. {
  1336. if(g_pConfRoom && g_pConfRoom->m_pAudioControl)
  1337. {
  1338. return g_pConfRoom->m_pAudioControl->IsSpkMuted() ? true : false;
  1339. }
  1340. return true;
  1341. }
  1342. bool IsMicMuted()
  1343. {
  1344. if(g_pConfRoom && g_pConfRoom->m_pAudioControl)
  1345. {
  1346. return g_pConfRoom->m_pAudioControl->IsRecMuted() ? true : false;
  1347. }
  1348. return true;
  1349. }
  1350. CVideoWindow* GetLocalVideo()
  1351. {
  1352. if(g_pConfRoom && g_pConfRoom->m_pTopWindow)
  1353. {
  1354. return g_pConfRoom->m_pTopWindow->GetLocalVideo();
  1355. }
  1356. return NULL;
  1357. }
  1358. CVideoWindow* GetRemoteVideo()
  1359. {
  1360. if(g_pConfRoom && g_pConfRoom->m_pTopWindow)
  1361. {
  1362. return g_pConfRoom->m_pTopWindow->GetRemoteVideo();
  1363. }
  1364. return NULL;
  1365. }
  1366. HRESULT SetCameraDialog(ULONG ul)
  1367. {
  1368. if(GetLocalVideo())
  1369. {
  1370. return GetLocalVideo()->SetCameraDialog(ul);
  1371. }
  1372. return E_FAIL;
  1373. }
  1374. HRESULT GetCameraDialog(ULONG* pul)
  1375. {
  1376. if(GetLocalVideo())
  1377. {
  1378. return GetLocalVideo()->GetCameraDialog(pul);
  1379. }
  1380. return E_FAIL;
  1381. }
  1382. HRESULT GetImageQuality(ULONG* pul, BOOL bIncoming)
  1383. {
  1384. if(bIncoming)
  1385. {
  1386. if(GetRemoteVideo())
  1387. {
  1388. *pul = GetRemoteVideo()->GetImageQuality();
  1389. return S_OK;
  1390. }
  1391. }
  1392. else
  1393. {
  1394. if(GetLocalVideo())
  1395. {
  1396. *pul = GetLocalVideo()->GetImageQuality();
  1397. return S_OK;
  1398. }
  1399. }
  1400. return E_FAIL;
  1401. }
  1402. HRESULT SetImageQuality(ULONG ul, BOOL bIncoming)
  1403. {
  1404. if(bIncoming)
  1405. {
  1406. if(GetRemoteVideo())
  1407. {
  1408. return GetRemoteVideo()->SetImageQuality(ul);
  1409. }
  1410. }
  1411. else
  1412. {
  1413. if(GetLocalVideo())
  1414. {
  1415. return GetLocalVideo()->SetImageQuality(ul);
  1416. }
  1417. }
  1418. return E_FAIL;
  1419. }
  1420. BOOL IsLocalVideoPaused()
  1421. {
  1422. if(GetLocalVideo())
  1423. {
  1424. return GetLocalVideo()->IsPaused();
  1425. }
  1426. return true;
  1427. }
  1428. BOOL IsRemoteVideoPaused()
  1429. {
  1430. if(GetRemoteVideo())
  1431. {
  1432. return GetRemoteVideo()->IsPaused();
  1433. }
  1434. return true;
  1435. }
  1436. void PauseLocalVideo(BOOL fPause)
  1437. {
  1438. if(GetLocalVideo())
  1439. {
  1440. GetLocalVideo()->Pause(fPause);
  1441. }
  1442. }
  1443. void PauseRemoteVideo(BOOL fPause)
  1444. {
  1445. if(GetRemoteVideo())
  1446. {
  1447. GetRemoteVideo()->Pause(fPause);
  1448. }
  1449. }
  1450. HRESULT GetRemoteVideoState(NM_VIDEO_STATE *puState)
  1451. {
  1452. if(GetRemoteVideo())
  1453. {
  1454. return GetRemoteVideo()->GetVideoState(puState);
  1455. }
  1456. return E_FAIL;
  1457. }
  1458. HRESULT GetLocalVideoState(NM_VIDEO_STATE *puState)
  1459. {
  1460. if(GetLocalVideo())
  1461. {
  1462. return GetLocalVideo()->GetVideoState(puState);
  1463. }
  1464. return E_FAIL;
  1465. }
  1466. void MuteSpeaker(BOOL fMute)
  1467. {
  1468. if(g_pConfRoom)
  1469. {
  1470. g_pConfRoom->MuteSpeaker(fMute);
  1471. }
  1472. }
  1473. void MuteMicrophone(BOOL fMute)
  1474. {
  1475. if(g_pConfRoom)
  1476. {
  1477. g_pConfRoom->MuteMicrophone(fMute);
  1478. }
  1479. }
  1480. DWORD GetRecorderVolume()
  1481. {
  1482. if(g_pConfRoom && g_pConfRoom->m_pAudioControl)
  1483. {
  1484. return g_pConfRoom->m_pAudioControl->GetRecorderVolume();
  1485. }
  1486. return 0;
  1487. }
  1488. DWORD GetSpeakerVolume()
  1489. {
  1490. if(g_pConfRoom && g_pConfRoom->m_pAudioControl)
  1491. {
  1492. return g_pConfRoom->m_pAudioControl->GetSpeakerVolume();
  1493. }
  1494. return 0;
  1495. }
  1496. void SetRecorderVolume(DWORD dw)
  1497. {
  1498. if(g_pConfRoom)
  1499. {
  1500. g_pConfRoom->SetRecorderVolume(dw);
  1501. }
  1502. }
  1503. void SetSpeakerVolume(DWORD dw)
  1504. {
  1505. if(g_pConfRoom)
  1506. {
  1507. g_pConfRoom->SetSpeakerVolume(dw);
  1508. }
  1509. }
  1510. HRESULT RevokeControl(UINT gccID)
  1511. {
  1512. HRESULT hr = S_OK;
  1513. if(g_pConfRoom)
  1514. {
  1515. hr = g_pConfRoom->RevokeControl(gccID);
  1516. }
  1517. else
  1518. {
  1519. hr = E_UNEXPECTED;
  1520. }
  1521. return hr;
  1522. }
  1523. HRESULT GetShareableApps(IAS_HWND_ARRAY** ppList)
  1524. {
  1525. HRESULT hr = S_OK;
  1526. if(g_pConfRoom)
  1527. {
  1528. hr = g_pConfRoom->GetShareableApps(ppList);
  1529. }
  1530. else
  1531. {
  1532. hr = E_UNEXPECTED;
  1533. }
  1534. return hr;
  1535. }
  1536. HRESULT FreeShareableApps(IAS_HWND_ARRAY * pList)
  1537. {
  1538. HRESULT hr = S_OK;
  1539. if(g_pConfRoom)
  1540. {
  1541. g_pConfRoom->FreeShareableApps(pList);
  1542. }
  1543. else
  1544. {
  1545. hr = E_UNEXPECTED;
  1546. }
  1547. return hr;
  1548. }
  1549. HRESULT ShareWindow(HWND hWnd)
  1550. {
  1551. HRESULT hr = E_UNEXPECTED;
  1552. if(g_pConfRoom)
  1553. {
  1554. if(g_pConfRoom->GetAppSharing())
  1555. {
  1556. hr = g_pConfRoom->CmdShare(hWnd);
  1557. }
  1558. }
  1559. return hr;
  1560. }
  1561. HRESULT UnShareWindow(HWND hWnd)
  1562. {
  1563. HRESULT hr = E_UNEXPECTED;
  1564. if(g_pConfRoom)
  1565. {
  1566. if(g_pConfRoom->GetAppSharing())
  1567. {
  1568. hr = g_pConfRoom->CmdUnshare(hWnd);
  1569. }
  1570. }
  1571. return hr;
  1572. }
  1573. HRESULT GetWindowState(NM_SHAPP_STATE* pState, HWND hWnd)
  1574. {
  1575. HRESULT hr = E_FAIL;
  1576. // We don't do error checking, the caller must check for valid ptr.
  1577. ASSERT(pState);
  1578. if(g_pConfRoom)
  1579. {
  1580. IAppSharing* pAS = g_pConfRoom->GetAppSharing();
  1581. if(pAS)
  1582. {
  1583. if (pAS->IsWindowShared(hWnd))
  1584. *pState = NM_SHAPP_SHARED;
  1585. else
  1586. *pState = NM_SHAPP_NOT_SHARED;
  1587. hr = S_OK;
  1588. }
  1589. }
  1590. return hr;
  1591. }
  1592. CVideoWindow* CConfRoom::GetLocalVideo()
  1593. {
  1594. CTopWindow *pMainUI = GetTopWindow();
  1595. return (pMainUI ? pMainUI->GetLocalVideo() : NULL);
  1596. }
  1597. CVideoWindow* CConfRoom::GetRemoteVideo()
  1598. {
  1599. CTopWindow *pMainUI = GetTopWindow();
  1600. return (pMainUI ? pMainUI->GetRemoteVideo() : NULL);
  1601. }
  1602. VOID CConfRoom::AddConferenceChangeHandler(IConferenceChangeHandler *pch)
  1603. {
  1604. EnterCriticalSection(&dialogListCriticalSection);
  1605. m_CallHandlerList.Add(pch);
  1606. LeaveCriticalSection(&dialogListCriticalSection);
  1607. }
  1608. VOID CConfRoom::RemoveConferenceChangeHandler(IConferenceChangeHandler *pch)
  1609. {
  1610. EnterCriticalSection(&dialogListCriticalSection);
  1611. m_CallHandlerList.Remove(pch);
  1612. LeaveCriticalSection(&dialogListCriticalSection);
  1613. }
  1614. void CConfRoom::OnLevelChange(BOOL fSpeaker, DWORD dwVolume)
  1615. {
  1616. EnterCriticalSection(&dialogListCriticalSection);
  1617. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  1618. LeaveCriticalSection(&dialogListCriticalSection);
  1619. // BUGBUG georgep: I guess one of these things could go away after
  1620. // we get the list, but I doubt it will ever happen
  1621. for( int i = 0; i < tempList.GetSize(); ++i )
  1622. {
  1623. IConferenceChangeHandler *pHandler = tempList[i];
  1624. ASSERT( NULL != pHandler );
  1625. pHandler->OnAudioLevelChange(fSpeaker, dwVolume);
  1626. }
  1627. }
  1628. void CConfRoom::OnMuteChange(BOOL fSpeaker, BOOL fMute)
  1629. {
  1630. EnterCriticalSection(&dialogListCriticalSection);
  1631. CCopyableArray<IConferenceChangeHandler*> tempList = m_CallHandlerList;
  1632. LeaveCriticalSection(&dialogListCriticalSection);
  1633. // BUGBUG georgep: I guess one of these things could go away after
  1634. // we get the list, but I doubt it will ever happen
  1635. for( int i = 0; i < tempList.GetSize(); ++i )
  1636. {
  1637. IConferenceChangeHandler *pHandler = tempList[i];
  1638. ASSERT( NULL != pHandler );
  1639. pHandler->OnAudioMuteChange(fSpeaker, fMute);
  1640. }
  1641. }
  1642. BOOL CConfRoom::CanCloseChat(HWND hwndMain)
  1643. {
  1644. BOOL fClosing = TRUE;
  1645. if(GCC_APPLET_CANCEL_EXIT == T120_CloseApplet(APPLET_ID_CHAT, TRUE, TRUE, 1000))
  1646. {
  1647. fClosing = FALSE;
  1648. }
  1649. return(fClosing);
  1650. }
  1651. // Check to see if WB can close
  1652. BOOL CConfRoom::CanCloseWhiteboard(HWND hwndMain)
  1653. {
  1654. BOOL fClosing = TRUE;
  1655. if(GCC_APPLET_CANCEL_EXIT == T120_CloseApplet(APPLET_ID_WB, TRUE, TRUE, 1000))
  1656. {
  1657. fClosing = FALSE;
  1658. }
  1659. return(fClosing);
  1660. }
  1661. // Check to see if WB can close
  1662. BOOL CConfRoom::CanCloseFileTransfer(HWND hwndMain)
  1663. {
  1664. BOOL fClosing = TRUE;
  1665. if(GCC_APPLET_CANCEL_EXIT == T120_CloseApplet(APPLET_ID_FT, TRUE, TRUE, 1000))
  1666. {
  1667. fClosing = FALSE;
  1668. }
  1669. return(fClosing);
  1670. }
  1671. void CConfRoom::ToggleLdapLogon()
  1672. {
  1673. if(NULL == g_pLDAP)
  1674. {
  1675. InitNmLdapAndLogon();
  1676. }
  1677. else
  1678. {
  1679. if(g_pLDAP->IsLoggedOn() || g_pLDAP->IsBusy())
  1680. {
  1681. g_pLDAP->Logoff();
  1682. }
  1683. else
  1684. {
  1685. g_pLDAP->LogonAsync();
  1686. }
  1687. }
  1688. }
  1689. HWND CConfRoom::GetTopHwnd()
  1690. {
  1691. CTopWindow *pTopWindow = GetTopWindow();
  1692. return(NULL==pTopWindow ? NULL : pTopWindow->GetWindow());
  1693. }
  1694. HPALETTE CConfRoom::GetPalette()
  1695. {
  1696. return(CGenWindow::GetStandardPalette());
  1697. }
  1698. DWORD CConfRoom::GetCallFlags()
  1699. {
  1700. DWORD dwFlags = g_dwPlaceCall;
  1701. INmConference *pConf = GetActiveConference();
  1702. //
  1703. // If we have an active conference, use its security caps. And they
  1704. // can not be altered by anyone.
  1705. //
  1706. if ( NULL != pConf )
  1707. {
  1708. ULONG ulchCaps;
  1709. if ( S_OK == pConf->GetNmchCaps(&ulchCaps))
  1710. {
  1711. if ( NMCH_SECURE & ulchCaps )
  1712. {
  1713. dwFlags |= nmDlgCallSecurityOn;
  1714. }
  1715. }
  1716. }
  1717. else if (NULL != g_pNmSysInfo)
  1718. {
  1719. switch (ConfPolicies::GetSecurityLevel())
  1720. {
  1721. case DISABLED_POL_SECURITY:
  1722. //
  1723. // Security off, and user can't change checkbox
  1724. //
  1725. break;
  1726. case REQUIRED_POL_SECURITY:
  1727. //
  1728. // Security on, and user can't change checkbox
  1729. //
  1730. dwFlags |= nmDlgCallSecurityOn;
  1731. break;
  1732. default:
  1733. //
  1734. // User can change it.
  1735. dwFlags |= nmDlgCallSecurityAlterable;
  1736. //
  1737. // Default depends on OUTGOING_PREFFERED
  1738. //
  1739. if (ConfPolicies::OutgoingSecurityPreferred())
  1740. {
  1741. dwFlags |= nmDlgCallSecurityOn;
  1742. }
  1743. break;
  1744. }
  1745. }
  1746. return(dwFlags);
  1747. }
  1748. BOOL CConfRoom::IsSharingAllowed()
  1749. {
  1750. //
  1751. // No app sharing, no RDS.
  1752. //
  1753. if (!FIsSharingAvailable())
  1754. {
  1755. return(FALSE);
  1756. }
  1757. else if (!(GetMeetingPermissions() & NM_PERMIT_SHARE))
  1758. {
  1759. return(FALSE);
  1760. }
  1761. return(TRUE);
  1762. }
  1763. BOOL CConfRoom::IsNewWhiteboardAllowed()
  1764. {
  1765. if (ConfPolicies::IsNewWhiteboardEnabled())
  1766. {
  1767. if (GetMeetingPermissions() & NM_PERMIT_STARTWB)
  1768. {
  1769. return(TRUE);
  1770. }
  1771. }
  1772. return(FALSE);
  1773. }
  1774. BOOL CConfRoom::IsOldWhiteboardAllowed()
  1775. {
  1776. if (ConfPolicies::IsOldWhiteboardEnabled())
  1777. {
  1778. if (GetMeetingPermissions() & NM_PERMIT_STARTOLDWB)
  1779. {
  1780. return(TRUE);
  1781. }
  1782. }
  1783. return(FALSE);
  1784. }
  1785. BOOL CConfRoom::IsChatAllowed()
  1786. {
  1787. if (ConfPolicies::IsChatEnabled())
  1788. {
  1789. if (GetMeetingPermissions() & NM_PERMIT_STARTCHAT)
  1790. {
  1791. return(TRUE);
  1792. }
  1793. }
  1794. return(FALSE);
  1795. }
  1796. BOOL CConfRoom::IsFileTransferAllowed()
  1797. {
  1798. if (ConfPolicies::IsFileTransferEnabled())
  1799. {
  1800. if (GetMeetingPermissions() & NM_PERMIT_SENDFILES)
  1801. {
  1802. return(TRUE);
  1803. }
  1804. }
  1805. return(FALSE);
  1806. }
  1807. BOOL CConfRoom::IsNewCallAllowed()
  1808. {
  1809. if (GetMeetingPermissions() & NM_PERMIT_OUTGOINGCALLS)
  1810. {
  1811. return(TRUE);
  1812. }
  1813. return(FALSE);
  1814. }
  1815. //--------------------------------------------------------------------------//
  1816. // CConfRoom::get_securitySettings. //
  1817. //--------------------------------------------------------------------------//
  1818. void
  1819. CConfRoom::get_securitySettings
  1820. (
  1821. bool & userAlterable,
  1822. bool & secure
  1823. ){
  1824. INmConference * activeConference = (g_pConfRoom != NULL)? g_pConfRoom->GetActiveConference(): NULL;
  1825. if( activeConference != NULL )
  1826. {
  1827. ULONG conferenceCaps;
  1828. if( activeConference->GetNmchCaps( &conferenceCaps ) == S_OK )
  1829. {
  1830. secure = ((conferenceCaps & NMCH_SECURE) != 0);
  1831. }
  1832. else
  1833. {
  1834. ERROR_OUT( ("Bad conference") );
  1835. secure = false; // Is there really a reasonable default???
  1836. }
  1837. userAlterable = false;
  1838. }
  1839. else
  1840. {
  1841. switch( ConfPolicies::GetSecurityLevel() )
  1842. {
  1843. case DISABLED_POL_SECURITY:
  1844. {
  1845. secure = false;
  1846. userAlterable = false;
  1847. }
  1848. break;
  1849. case REQUIRED_POL_SECURITY:
  1850. {
  1851. secure = true;
  1852. userAlterable = false;
  1853. }
  1854. break;
  1855. default:
  1856. {
  1857. secure = ConfPolicies::OutgoingSecurityPreferred();
  1858. userAlterable = true;
  1859. }
  1860. break;
  1861. }
  1862. }
  1863. } // End of CConfRoom::get_securitySettings.