CMEMB.CPP

//**************************************************************************** 
// Module: NMUI.EXE
// File: CMEMB.CPP
// Content: INmMember Routines
//
//
// Copyright (c) Microsoft Corporation 1995-1997
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//****************************************************************************

#include "precomp.h"

COBLIST * g_pListUser = (COBLIST *) NULL;

UINT gcUsers = 0;


//****************************************************************************
//
// PUSER PUserFromINmMember(INmMember * pMember)
//
//****************************************************************************

PUSER PUserFromINmMember(INmMember * pMember)
{
if (NULL != g_pListUser)
{
POSITION pos = g_pListUser->GetHeadPosition();
while (NULL != pos)
{
PUSER pUser = (PUSER) g_pListUser->GetNext(pos);
if (pMember == pUser->pMember)
return pUser;
}
}

return NULL;
}


//****************************************************************************
//
// int ItemFromPUser(PUSER pUser)
//
//****************************************************************************

int ItemFromPUser(PUSER pUser)
{
if (NULL == ghwndLView)
return -1;

LV_FINDINFO findInfo;
ClearStruct(&findInfo);
findInfo.flags = LVFI_PARAM;
findInfo.lParam = (LPARAM) pUser;
return ListView_FindItem(ghwndLView, -1, &findInfo);
}


//****************************************************************************
//
// PUSER PUserLocal()
//
// Return a pointer to the local user information
//
//****************************************************************************

PUSER PUserLocal()
{
if (NULL != g_pListUser)
{
POSITION pos = g_pListUser->GetHeadPosition();
while (NULL != pos)
{
PUSER pUser = (PUSER) g_pListUser->GetNext(pos);
if (pUser->fLocal)
return pUser;
}
}

return NULL;
}

//****************************************************************************
//
// VOID UpdateUserDisplay(PUSER pUser)
//
//****************************************************************************

VOID UpdateUserDisplay(PUSER pUser)
{
int iItem = ItemFromPUser(pUser);
TCHAR sz[MAX_PATH];

ASSERT(NULL != ghwndLView);

wsprintf(sz, "%d", pUser->uVersion);
ListView_SetItemText(ghwndLView, iItem, ILV_VERSION, sz);

wsprintf(sz, "%d", pUser->fMcu);
ListView_SetItemText(ghwndLView, iItem, ILV_MCU, sz);

wsprintf(sz, "%d", pUser->fLocal);
ListView_SetItemText(ghwndLView, iItem, ILV_LOCAL, sz);

wsprintf(sz, "%X", pUser->m_pChannelAudio);
ListView_SetItemText(ghwndLView, iItem, ILV_AUDIO, sz);

wsprintf(sz, "%X", pUser->m_pChannelVideo);
ListView_SetItemText(ghwndLView, iItem, ILV_VIDEO, sz);

wsprintf(sz, "%X", pUser->m_pChannelAs);
ListView_SetItemText(ghwndLView, iItem, ILV_AS, sz);

wsprintf(sz, "%X", pUser->m_pChannelFt);
ListView_SetItemText(ghwndLView, iItem, ILV_FT, sz);

wsprintf(sz, "%08X", pUser->uchCaps);
ListView_SetItemText(ghwndLView, iItem, ILV_CAPS, sz);

ListView_SetItemText(ghwndLView, iItem, ILV_ADDR,
(NULL == pUser->pszAddr) ? TEXT("?") : pUser->pszAddr);

wsprintf(sz, "%08X", pUser->uId);
ListView_SetItemText(ghwndLView, iItem, ILV_ID, sz);

}

//****************************************************************************
//
// VOID UpdateUserCount(void)
//
//****************************************************************************

VOID UpdateUserCount(void)
{
TCHAR sz[MAX_PATH];

if (1 == gcUsers)
lstrcpy(sz, TEXT("1 user"));
else
wsprintf(sz, TEXT("%d users"), gcUsers);

UpdateStatusBar(sz, IDSBP_USERCOUNT, 0);
}


//****************************************************************************
//
// PUSER AllocUser(INmMember * pMember)
//
//****************************************************************************

PUSER AllocUser(INmMember * pMember)
{
HRESULT hr;
BSTR bstr;
INmConference * pConference;

PUSER pUser = new USER;
if (NULL == pUser)
{
return NULL;
}
ClearStruct(pUser);
pUser->pMember = pMember;
pMember->AddRef();

hr = pMember->GetName(&bstr);
if (FAILED(hr))
{
WARN_MSG("Problem with GetName");
}
else
{
pUser->pszName = PszFromBstr(bstr);
SysFreeString(bstr);
}

hr = pMember->GetAddr(&bstr, &pUser->uType);
if (FAILED(hr))
{
WARN_MSG("Problem with GetAddr");
}
else
{
pUser->pszAddr = PszFromBstr(bstr);
SysFreeString(bstr);
}

hr = pMember->GetNmchCaps(&pUser->uchCaps);
if (FAILED(hr))
{
WARN_MSG("Problem with GetNmchCaps");
pUser->uchCaps = 0;
}

hr = pMember->GetNmVersion(&pUser->uVersion);
if (FAILED(hr))
{
WARN_MSG("Problem with GetNmVersion");
pUser->uVersion = 0;
}

hr = pMember->GetID(&pUser->uId);
if (FAILED(hr))
{
WARN_MSG("Problem with GetID");
pUser->uId = 0;
}

pUser->fLocal = S_OK == pMember->IsSelf();
pUser->fMcu = S_OK == pMember->IsMCU();
pUser->fTop = FALSE;
hr = pMember->GetConference(&pConference);
if (FAILED(hr))
{
WARN_MSG("Problem with GetConference");
}
else
{
INmMember * pMemberTop;
if (SUCCEEDED(pConference->GetTopProvider(&pMemberTop)))
{
pUser->fTop = (pMember == pMemberTop);
pMemberTop->Release();
}
pConference->Release();
}

return pUser;
}

//****************************************************************************
//
// VOID FreeUser(PUSER pUser)
//
//****************************************************************************

VOID FreeUser(PUSER pUser)
{
ASSERT(NULL != pUser);

FreePlpv(&pUser->pszName);
FreePlpv(&pUser->pszAddr);

if (NULL != pUser->pMember)
{
OBJECT_MSG("[%08X] member released", pUser->pMember);
pUser->pMember->Release();
}
}


//****************************************************************************
//
// VOID FreeAllUsers(void)
//
//****************************************************************************

VOID FreeAllUsers(void)
{
if (NULL != g_pListUser)
{
while (!g_pListUser->IsEmpty())
{
RemoveMember(((PUSER) g_pListUser->GetHead())->pMember);
}
}
}

//****************************************************************************
//
// VOID AddMember(INmMember * pMember)
//
//****************************************************************************

VOID AddMember(INmMember * pMember)
{
PUSER pUser = AllocUser(pMember);
if (NULL == pUser)
{
return;
}

AddNode(pUser, &g_pListUser);

LV_ITEM lvItem;
ClearStruct(&lvItem);
lvItem.iItem = gcUsers;
lvItem.mask = LVIF_PARAM | LVIF_TEXT;
lvItem.pszText = pUser->pszName;
lvItem.cchTextMax = lstrlen(pUser->pszName);
lvItem.lParam = (LPARAM) pUser;
ListView_InsertItem(ghwndLView, &lvItem);

gcUsers++;
UpdateUserCount();
UpdateUserDisplay(pUser);

AddUserToUList(pUser, ghwndUList, FALSE);
}

//****************************************************************************
//
// VOID RemoveMember(INmMember * pMember)
//
//****************************************************************************

VOID RemoveMember(INmMember * pMember)
{
if (NULL == g_pListUser)
return;

POSITION pos = g_pListUser->GetHeadPosition();
while (NULL != pos)
{
POSITION posSav = pos;
PUSER pUser = (PUSER) g_pListUser->GetNext(pos);
if (pMember == pUser->pMember)
{
RemoveUserFromUList(pUser, ghwndUList);
ListView_DeleteItem(ghwndLView, ItemFromPUser(pUser));
FreeUser(pUser);
g_pListUser->RemoveAt(posSav);

gcUsers--;
UpdateUserCount();
return;
}
}
}

//****************************************************************************
//
// VOID UpdateUserChannel(PUSER pUser, INmChannel * pChannel, NM_MEMBER_NOTIFY uNotify)
//
//****************************************************************************

VOID UpdateUserChannel(PUSER pUser, INmChannel * pChannel, NM_MEMBER_NOTIFY uNotify)
{
ULONG uch;
PVOID *ppChannel = NULL;

ASSERT(NULL != pChannel);

if (FAILED(pChannel->GetNmch(&uch)))
{
return;
}

if (NM_MEMBER_ADDED == uNotify)
{
switch (uch)
{
case NMCH_AUDIO:
{
INmChannelAudio * pChannelAudio;
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelAudio, (PVOID *) &pChannelAudio)))
{
if ((S_OK == pChannelAudio->IsIncoming()) != pUser->fLocal)
{
ASSERT((NULL == pUser->m_pChannelAudio) || (pChannelAudio == pUser->m_pChannelAudio));
// This is non-standard - we're storing a pointer to the specific channel,
// yet keeping a lock on the generic channel - weird....
pUser->m_pChannelAudio = pChannelAudio;
}
pChannelAudio->Release();
}
break;
}
case NMCH_VIDEO:
{
INmChannelVideo * pChannelVideo;
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelVideo, (PVOID *) &pChannelVideo)))
{
if ((S_OK == pChannelVideo->IsIncoming()) != pUser->fLocal)
{
ASSERT((NULL == pUser->m_pChannelVideo) || (pChannelVideo == pUser->m_pChannelVideo));
pUser->m_pChannelVideo = pChannelVideo;
}
pChannelVideo->Release();
}
break;
}
case NMCH_SHARE:
if (NULL == pUser->m_pChannelAs)
{
INmChannelAppShare * pChannelAs;
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelAppShare, (PVOID *) &pChannelAs)))
{
pUser->m_pChannelAs = pChannelAs;
pChannelAs->Release();
}
}
break;
case NMCH_FT:
if (NULL == pUser->m_pChannelFt)
{
INmChannelFt * pChannelFt;
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelFt, (PVOID *) &pChannelFt)))
{
pUser->m_pChannelFt = pChannelFt;
pChannelFt->Release();
}
}
break;
case NMCH_DATA:
ppChannel = (PVOID *) &(pUser->m_pChannelData);
break;
case NMCH_NONE:
case NMCH_ALL:
default:
break;
}
} /* CONFN_MEMBER_ADDED */

UpdateUserDisplay(pUser);
}


//****************************************************************************
//
// VOID UpdateUserInfo(PUSER pUser)
//
//****************************************************************************

VOID UpdateUserInfo(PUSER pUser)
{
ULONG ul;
HRESULT hr;
LPTSTR psz;
BSTR bstr;
INmMember * pMember = pUser->pMember;

hr = pMember->GetName(&bstr);
if (FAILED(hr))
{
WARN_MSG("Problem with GetName");
}
else
{
psz = PszFromBstr(bstr);
SysFreeString(bstr);

if (0 != lstrcmp(pUser->pszName, psz))
{
WARN_MSG("Replacing Name [%s] => [%s]", pUser->pszName, psz);
}
FreePlpv(&pUser->pszName);
pUser->pszName = psz;
}

hr = pMember->GetAddr(&bstr, &pUser->uType);
if (FAILED(hr))
{
WARN_MSG("Problem with GetAddr");
}
else
{
psz = PszFromBstr(bstr);
SysFreeString(bstr);

if (0 != lstrcmp(pUser->pszAddr, psz))
{
WARN_MSG("Replacing Addr [%s] => [%s]", pUser->pszAddr, psz);
}
FreePlpv(&pUser->pszAddr);
pUser->pszAddr = psz;
}

hr = pMember->GetNmchCaps(&ul);
if (FAILED(hr))
{
WARN_MSG("Problem with GetNmchCaps");
pUser->uchCaps = 0;
}
else if (pUser->uchCaps != ul)
{
WARN_MSG("Updating uchCaps [%08X] => [%08X]", pUser->uchCaps, ul);
pUser->uchCaps = ul;
}

hr = pMember->GetNmVersion(&ul);
if (FAILED(hr))
{
WARN_MSG("Problem with GetNmVersion");
pUser->uVersion = 0;
}
else if (pUser->uVersion != ul)
{
WARN_MSG("Updating version [%08X] => [%08X]", pUser->uVersion, ul);
pUser->uchCaps = ul;
}


if (pUser->fLocal != (S_OK == pMember->IsSelf()) )
{
ERROR_MSG("Local User status changed?");
}

if (pUser->fMcu != (S_OK == pMember->IsMCU()))
{
ERROR_MSG("MCU status changed?");
}
}


//****************************************************************************
//
// VOID UpdateConfView(void)
//
//****************************************************************************

VOID UpdateConfView(void)
{
if (NULL == g_pListUser)
return;

POSITION pos = g_pListUser->GetHeadPosition();
while (NULL != pos)
{
PUSER pUser = (PUSER) g_pListUser->GetNext(pos);
UpdateUserInfo(pUser);
UpdateUserDisplay(pUser);
}
}