Leaked source code of windows server 2003
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.

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