|
|
// NMWbObj.cpp : Implementation of CNMWbObj
#include "precomp.h"
#include <wbguid.h>
#include "wbcaps.h"
#include "NMWbObj.h"
#include <iappldr.h>
// Local prototypes
void CALLBACK T120AppletCallbackProc(T120AppletMsg *pMsg); void CALLBACK T120SessionCallbackProc(T120AppletSessionMsg *pMsg);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// CNMWbObj Construction and initialization
///////////////////////////////////////////////////////////////////////////////////////////////////////
CNMWbObj* g_pNMWBOBJ; UINT g_numberOfWorkspaces; UINT g_numberOfObjects; CWBOBLIST* g_pListOfWorkspaces; BOOL g_fWaitingForBufferAvailable; CWBOBLIST* g_pListOfObjectsThatRequestedHandles; CWBOBLIST* g_pRetrySendList; CWBOBLIST* g_pTrash; ULONG g_MyMemberID; ULONG g_RefresherID; UINT g_MyIndex; BOOL g_bSavingFile; BOOL g_bContentsChanged;
GCCPREALOC g_GCCPreallocHandles[PREALLOC_GCC_BUFFERS]; UINT g_iGCCHandleIndex; BOOL g_WaitingForGCCHandles;
//
// T.126 protocol related
//
static const ULONG g_T126KeyNodes[] = {0,0,20,126,0,1}; static const T120ChannelID g_aStaticChannels[] = { _SI_CHANNEL_0 };
//
// T.120 capabilities
//
static GCCAppCap *g_CapPtrList[_iT126_MAX_COLLAPSING_CAPABILITIES]; static GCCAppCap g_CapArray[_iT126_MAX_COLLAPSING_CAPABILITIES];
//
// T.120 non-collapsing capabilities
//
#define MY_APP_STR "_MSWB"
#define T126_TEXT_STRING "NM 3 Text"
#define T126_24BIT_STRING "NM 3 24BitMap"
static const OSTR s_AppData[_iT126_LAST_NON_COLLAPSING_CAPABILITIES] = { { sizeof(T126_TEXT_STRING), (LPBYTE) T126_TEXT_STRING }, { sizeof(T126_24BIT_STRING), (LPBYTE) T126_24BIT_STRING }, };
static GCCNonCollCap g_NCCapArray[2]; static const GCCNonCollCap *g_NCCapPtrList[2] = { &g_NCCapArray[0], &g_NCCapArray[1] };
//
// Member ID arrays, assuming 64 members
//
#define MAX_MEMBERS 128
static MEMBER_ID g_aMembers[MAX_MEMBERS];
CNMWbObj::CNMWbObj( void ) : // T.120 applet SAP
m_pApplet(NULL), m_aMembers(&g_aMembers[0]) { DBGENTRY(CNMWbObj::CNMWbObj);
DBG_SAVE_FILE_LINE g_pListOfWorkspaces = new CWBOBLIST(); DBG_SAVE_FILE_LINE g_pListOfObjectsThatRequestedHandles = new CWBOBLIST(); DBG_SAVE_FILE_LINE g_pTrash = new CWBOBLIST(); DBG_SAVE_FILE_LINE g_pRetrySendList = new CWBOBLIST(); g_pListOfWorkspaces->EmptyList(); g_pListOfObjectsThatRequestedHandles->EmptyList(); g_pRetrySendList->EmptyList(); g_pTrash->EmptyList(); g_numberOfWorkspaces = 0; g_numberOfObjects = 0; g_MyIndex = 0; g_bSavingFile = FALSE; g_bContentsChanged = FALSE; g_iGCCHandleIndex = 0; g_fWaitingForBufferAvailable = FALSE; g_WaitingForGCCHandles = FALSE; ::ZeroMemory(&g_GCCPreallocHandles, sizeof(g_GCCPreallocHandles)); m_instanceNumber = 0; m_bConferenceOnlyNetmeetingNodes = TRUE;
g_pNMWBOBJ = this;
// Cleanup per-conference T.120 info
CleanupPerConf();
// T.120 Applet
T120Error rc = ::T120_CreateAppletSAP(&m_pApplet); if (T120_NO_ERROR != rc) { ERROR_OUT(("CNMWbObj::CNMWbObj: cannot create applet SAP")); return; } ASSERT(NULL != m_pApplet); m_pApplet->Advise(T120AppletCallbackProc, this);
//
// Fill in the capabilities
//
BuildCaps();
//
// Load IMM32 if this is FE
//
ASSERT(!g_hImmLib); ASSERT(!g_fnImmGetContext); ASSERT(!g_fnImmNotifyIME);
if (GetSystemMetrics(SM_DBCSENABLED)) { g_hImmLib = LoadLibrary("imm32.dll"); if (!g_hImmLib) { ERROR_OUT(("Failed to load imm32.dll")); } else { g_fnImmGetContext = (IGC_PROC)GetProcAddress(g_hImmLib, "ImmGetContext"); if (!g_fnImmGetContext) { ERROR_OUT(("Failed to get ImmGetContext pointer")); } g_fnImmNotifyIME = (INI_PROC)GetProcAddress(g_hImmLib, "ImmNotifyIME"); if (!g_fnImmNotifyIME) { ERROR_OUT(("Failed to get ImmNotifyIME pointer")); } } }
DBG_SAVE_FILE_LINE g_pMain = new WbMainWindow(); if (!g_pMain) { ERROR_OUT(("Can't create WbMainWindow")); } else { //
// OK, now we're ready to create our HWND
//
if (!g_pMain->Open(SW_SHOWDEFAULT)) { ERROR_OUT(("Can't create WB windows")); } }
DBGEXIT(CNMWbObj::CNMWbObj); }
CNMWbObj::~CNMWbObj( void ) { DBGENTRY(CNMWbObj::~CNMWbObj);
//
// If i'm the refresher, I have to release the token
// And send an workspace refresh status pdu
//
if(m_bImTheT126Refresher) { ::ZeroMemory(&m_tokenRequest, sizeof(m_tokenRequest)); m_tokenRequest.eCommand = APPLET_RELEASE_TOKEN; m_tokenRequest.nTokenID = _SI_WORKSPACE_REFRESH_TOKEN; T120Error rc = m_pAppletSession->TokenRequest(&m_tokenRequest);
SendWorkspaceRefreshPDU(FALSE); }
// no more T.120
if (NULL != m_pAppletSession) { m_pAppletSession->ReleaseInterface(); CleanupPerConf(); } if (NULL != m_pApplet) { m_pApplet->ReleaseInterface(); m_pApplet = NULL; }
if(g_pMain) { delete g_pMain; g_pMain = NULL; }
//
// Delete all the global lists
//
DeleteAllWorkspaces(FALSE); g_pListOfWorkspaces->EmptyList(); g_pListOfObjectsThatRequestedHandles->EmptyList(); g_numberOfWorkspaces = 0;
T126Obj* pGraphic; //
// Burn trash
//
pGraphic = (T126Obj *)g_pTrash->RemoveTail(); while (pGraphic != NULL) { delete pGraphic; pGraphic = (T126Obj *) g_pTrash->RemoveTail(); }
if(g_pTrash) { delete g_pTrash; g_pTrash = NULL; }
if(g_pListOfWorkspaces) { delete g_pListOfWorkspaces; g_pListOfWorkspaces = NULL; }
if(g_pListOfObjectsThatRequestedHandles) { delete g_pListOfObjectsThatRequestedHandles; g_pListOfObjectsThatRequestedHandles = NULL; } if(g_pRetrySendList) { delete g_pRetrySendList; g_pRetrySendList = NULL; }
g_fnImmNotifyIME = NULL; g_fnImmGetContext = NULL; if (g_hImmLib) { FreeLibrary(g_hImmLib); g_hImmLib = NULL; }
DBGEXIT(CNMWbObj::~CNMWbObj); }
void CNMWbObj::BuildCaps(void) { // Fill in the caps we support
int i;
for(i=0;i<_iT126_MAX_COLLAPSING_CAPABILITIES;i++) { g_CapArray[i].capability_id.capability_id_type = GCC_STANDARD_CAPABILITY; g_CapArray[i].capability_id.standard_capability = GCCCaps[i].CapValue; g_CapArray[i].capability_class.eType = GCCCaps[i].Type;
if( GCCCaps[i].CapValue == Soft_Copy_Workspace_Max_Width) { GCCCaps[i].MinValue = DRAW_WIDTH + 1; GCCCaps[i].MaxValue = DRAW_WIDTH - 1; }
if(GCCCaps[i].CapValue == Soft_Copy_Workspace_Max_Height) { GCCCaps[i].MinValue = DRAW_HEIGHT + 1; GCCCaps[i].MaxValue = DRAW_HEIGHT - 1; }
if(GCCCaps[i].CapValue == Soft_Copy_Workspace_Max_Planes) { GCCCaps[i].MinValue = WB_MAX_WORKSPACES + 1; GCCCaps[i].MaxValue = WB_MAX_WORKSPACES - 1; }
if(GCCCaps[i].Type == GCC_UNSIGNED_MINIMUM_CAPABILITY) { g_CapArray[i].capability_class.nMinOrMax = GCCCaps[i].MinValue - 1; } else if ((GCCCaps[i].Type == GCC_UNSIGNED_MAXIMUM_CAPABILITY)) { g_CapArray[i].capability_class.nMinOrMax = GCCCaps[i].MaxValue + 1; } else { g_CapArray[i].capability_class.nMinOrMax = 0; }
g_CapArray[i].number_of_entities = 0;
g_CapPtrList[i] = &g_CapArray[i]; }
//
// Non-Collapsed Capabilities
//
g_NCCapArray[0].capability_id.capability_id_type = GCC_STANDARD_CAPABILITY; g_NCCapArray[0].capability_id.standard_capability = _iT126_TEXT_CAPABILITY_ID; g_NCCapArray[0].application_data = (OSTR *) &s_AppData[0];
//
// How many bits per pixel can we handle?
//
HDC hDC = CreateCompatibleDC(NULL);
if((GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES)) >= 24) { m_bICanDo24BitBitmaps = TRUE; g_NCCapArray[1].capability_id.capability_id_type = GCC_STANDARD_CAPABILITY; g_NCCapArray[1].capability_id.standard_capability = _iT126_24BIT_BITMAP_ID; g_NCCapArray[1].application_data = (OSTR *) &s_AppData[1]; } else { m_bICanDo24BitBitmaps = FALSE; }
if (hDC) { DeleteDC(hDC); }
}
//
// T120 Applet Functions
//
void CALLBACK T120AppletCallbackProc ( T120AppletMsg *pMsg ) { CNMWbObj *pWBOBJ = (CNMWbObj *) pMsg->pAppletContext; if (pWBOBJ == g_pNMWBOBJ) { switch (pMsg->eMsgType) { case GCC_PERMIT_TO_ENROLL_INDICATION: pWBOBJ->OnPermitToEnroll(pMsg->PermitToEnrollInd.nConfID, pMsg->PermitToEnrollInd.fPermissionGranted); break;
case T120_JOIN_SESSION_CONFIRM: default: break; } } }
void CALLBACK T120SessionCallbackProc ( T120AppletSessionMsg *pMsg ) { if(g_pNMWBOBJ == NULL) { return; }
CNMWbObj *pSession = (CNMWbObj *) pMsg->pSessionContext; ASSERT(pMsg->pAppletContext == pMsg->pSessionContext); if (pSession == g_pNMWBOBJ) { ASSERT(pMsg->nConfID == pSession->GetConfID()); switch (pMsg->eMsgType) { case MCS_UNIFORM_SEND_DATA_INDICATION: //
// Check if we are receiving a indication from owrself
//
if(pMsg->SendDataInd.initiator == GET_USER_ID_FROM_MEMBER_ID(g_MyMemberID)) { return; } case MCS_SEND_DATA_INDICATION: ::T126_MCSSendDataIndication( pMsg->SendDataInd.user_data.length, pMsg->SendDataInd.user_data.value, pMsg->SendDataInd.initiator, FALSE); break;
case MCS_TRANSMIT_BUFFER_AVAILABLE_INDICATION: g_fWaitingForBufferAvailable = FALSE; RetrySend(); break;
case GCC_APP_ROSTER_REPORT_INDICATION: pSession->OnRosterIndication((ULONG) pMsg->AppRosterReportInd.cRosters, pMsg->AppRosterReportInd.apAppRosters); break;
case GCC_ALLOCATE_HANDLE_CONFIRM: pSession->OnAllocateHandleConfirm(&pMsg->RegAllocHandleConfirm); break;
case T120_JOIN_SESSION_CONFIRM: pSession->OnJoinSessionConfirm(&pMsg->JoinSessionConfirm); break;
case MCS_TOKEN_GRAB_CONFIRM: TRACE_DEBUG(("MCS_TOKEN_GRAB_CONFIRM result = %d",pMsg->TokenConfirm.eResult));
if(pMsg->TokenConfirm.eResult == T120_RESULT_SUCCESSFUL) { TRACE_DEBUG((">>> I'm the T126 REFRESHER <<<")); g_pNMWBOBJ->m_bImTheT126Refresher = TRUE;
//
// Tell everybody I'm the refresher
//
SendWorkspaceRefreshPDU(TRUE);
g_RefresherID = g_MyMemberID; } else { TRACE_DEBUG((">>> I'm NOT the T126 REFRESHER <<<"));
// if we are not the t126 refresher, we should save the previous work
if (!g_pNMWBOBJ->m_bImTheT126Refresher) {
if(!g_pNMWBOBJ->IsInConference()) { if (g_pMain && (g_pMain->QuerySaveRequired(FALSE) == IDYES)) { g_pMain->OnSave(FALSE); } //
// If we were waiting on the save contents <yes> <no> dialog
// and the whole conference and UI are exiting, g_pMain could be NULL
// Or if we are not in a call anymore, we don't need to delete all the local workspaces.
//
if(g_pMain == NULL || !g_pNMWBOBJ->IsInConference()) { return; }
::InvalidateRect(g_pDraw->m_hwnd, NULL, TRUE); DeleteAllWorkspaces(FALSE);
//
// Fill up the GCC tank
//
TimeToGetGCCHandles(PREALLOC_GCC_HANDLES); } // ELSE
// If we got here and we are in a call don't do a thing.
// We just got here because the refresher went away. We tried
// to grab the token and we lost it to a faster node.
//
} }
break;
default: break; } } }
void CNMWbObj::OnPermitToEnroll ( T120ConfID nConfID, BOOL fPermissionGranted ) { if (fPermissionGranted) { // We are not in a conference, right?
ASSERT(NULL == m_pAppletSession);
m_bConferenceOnlyNetmeetingNodes = TRUE;
// Create an applet session
T120Error rc = m_pApplet->CreateSession(&m_pAppletSession, nConfID); if (T120_NO_ERROR == rc) { ASSERT(NULL != m_pAppletSession); m_pAppletSession->Advise(T120SessionCallbackProc, this, this);
// get top provider information
m_bImTheTopProvider = m_pAppletSession->IsThisNodeTopProvider();
// Build join-sesion request
::ZeroMemory(&m_JoinSessionReq, sizeof(m_JoinSessionReq)); m_JoinSessionReq.dwAttachmentFlags = ATTACHMENT_DISCONNECT_IN_DATA_LOSS | ATTACHMENT_MCS_FREES_DATA_IND_BUFFER; m_JoinSessionReq.SessionKey.application_protocol_key.key_type = GCC_OBJECT_KEY; m_JoinSessionReq.SessionKey.application_protocol_key.object_id.long_string = (ULONG *) g_T126KeyNodes; m_JoinSessionReq.SessionKey.application_protocol_key.object_id.long_string_length = sizeof(g_T126KeyNodes) / sizeof(g_T126KeyNodes[0]); m_JoinSessionReq.SessionKey.session_id = _SI_CHANNEL_0; m_JoinSessionReq.fConductingCapable = FALSE; m_JoinSessionReq.nStartupChannelType =MCS_STATIC_CHANNEL; m_JoinSessionReq.cNonCollapsedCaps =1 + (m_bICanDo24BitBitmaps ? 1 : 0); m_JoinSessionReq.apNonCollapsedCaps = (GCCNonCollCap **) g_NCCapPtrList; m_JoinSessionReq.cCollapsedCaps = sizeof(g_CapPtrList) / sizeof(g_CapPtrList[0]); ASSERT(_iT126_MAX_COLLAPSING_CAPABILITIES == sizeof(g_CapPtrList) / sizeof(g_CapPtrList[0])); m_JoinSessionReq.apCollapsedCaps = g_CapPtrList; m_JoinSessionReq.cStaticChannels = sizeof(g_aStaticChannels) / sizeof(g_aStaticChannels[0]); m_JoinSessionReq.aStaticChannels = (T120ChannelID *) g_aStaticChannels;
//
// Token to grab
//
::ZeroMemory(&m_tokenResourceRequest, sizeof(m_tokenResourceRequest)); m_tokenResourceRequest.eCommand = APPLET_GRAB_TOKEN_REQUEST; // m_tokenRequest.nChannelID = _SI_CHANNEL_0;
m_tokenResourceRequest.nTokenID = _SI_WORKSPACE_REFRESH_TOKEN; m_tokenResourceRequest.fImmediateNotification = TRUE;
m_JoinSessionReq.cResourceReqs = 1; m_JoinSessionReq.aResourceReqs = &m_tokenResourceRequest;
// Join now
rc = m_pAppletSession->Join(&m_JoinSessionReq); if (T120_NO_ERROR == rc) { m_nConfID = nConfID;
//
// JOSEF NOW SET THE MAIN WINDOW STATUS
} else { WARNING_OUT(("CNMWbObj::OnPermitToEnroll: cannot join conf=%u, rc=%u", nConfID, rc)); } } } else { if (NULL != m_pAppletSession) { m_pAppletSession->ReleaseInterface(); CleanupPerConf(); } } }
void CNMWbObj::OnJoinSessionConfirm ( T120JoinSessionConfirm *pConfirm ) { if (NULL != m_pAppletSession) { ASSERT(m_pAppletSession == pConfirm->pIAppletSession); if (T120_RESULT_SUCCESSFUL == pConfirm->eResult) { m_uidMyself = pConfirm->uidMyself; m_sidMyself = pConfirm->sidMyself; m_eidMyself = pConfirm->eidMyself; m_nidMyself = pConfirm->nidMyself;
// create member ID
g_MyMemberID = MAKE_MEMBER_ID(m_nidMyself, m_uidMyself);
if(g_pDraw && g_pDraw->IsLocked()) { m_LockerID = g_MyMemberID; }
// regardless, update the index anyway
g_MyIndex = (m_uidMyself + NUMCOLS) % NUMCLRPANES;
// we are now in the conference
m_fInConference = TRUE;
// allocate handles for all objects
if (m_bImTheT126Refresher) {
g_RefresherID = g_MyMemberID;
//
// Resend all objects
//
WBPOSITION pos; WBPOSITION posObj; WorkspaceObj* pWorkspace; T126Obj* pObj;
pos = g_pListOfWorkspaces->GetHeadPosition();
while(pos) { pWorkspace = (WorkspaceObj*)g_pListOfWorkspaces->GetNext(pos); g_pListOfObjectsThatRequestedHandles->AddHead(pWorkspace); posObj = pWorkspace->GetHeadPosition(); while(posObj) { pObj = pWorkspace->GetNextObject(posObj); if(pObj) { g_pListOfObjectsThatRequestedHandles->AddHead(pObj); } } }
//
// Delete the fake handles we had
//
g_WaitingForGCCHandles = FALSE; g_GCCPreallocHandles[0].GccHandleCount = 0; g_GCCPreallocHandles[1].GccHandleCount = 0; TimeToGetGCCHandles(g_numberOfObjects + g_numberOfWorkspaces + PREALLOC_GCC_HANDLES); } else { ::InvalidateRect(g_pDraw->m_hwnd, NULL, TRUE); DeleteAllWorkspaces(FALSE); }
} else { WARNING_OUT(("CNMWbObj::OnJoinSessionConfirm: failed to join conference, result=%u. error=%u", pConfirm->eResult, pConfirm->eError)); ASSERT(GCC_CONFERENCE_NOT_ESTABLISHED == pConfirm->eError); m_pAppletSession->ReleaseInterface(); CleanupPerConf(); } } }
void CNMWbObj::OnAllocateHandleConfirm ( GCCRegAllocateHandleConfirm *pConfirm ) { if (T120_RESULT_SUCCESSFUL == pConfirm->nResult) { ::T126_GCCAllocateHandleConfirm(pConfirm->nFirstHandle, pConfirm->cHandles); } else { ERROR_OUT(("CNMWbObj::OnAllocateHandleConfirm: failed to allocate %u handles, result=%u", pConfirm->cHandles, pConfirm->nResult)); } }
void CNMWbObj::OnRosterIndication ( ULONG cRosters, GCCAppRoster *apRosters[] ) { if (IsInConference()) { BOOL fAdded = FALSE; BOOL fRemoved = FALSE; ULONG cOtherMembers = 0; ULONG i, j, k;
// Caculate how many members in this session
for (i = 0; i < cRosters; i++) { GCCAppRoster *pRoster = apRosters[i];
// bail out if this roster is not for this session
if (pRoster->session_key.session_id != m_sidMyself) { continue; }
// node added or removed?
fAdded |= pRoster->nodes_were_added; fRemoved |= pRoster->nodes_were_removed;
BOOL conferenceCanDo24BitBitmap = TRUE; BOOL conferenceCanDoText = TRUE; // parse the roster records
for (j = 0; j < pRoster->number_of_records; j++) { GCCAppRecord *pRecord = pRoster->application_record_list[j]; if (pRecord->is_enrolled_actively) { MEMBER_ID nMemberID = MAKE_MEMBER_ID(pRecord->node_id, pRecord->application_user_id); if (nMemberID != g_MyMemberID) { //
// Only count T126 apps
//
if((pRoster->session_key.application_protocol_key.key_type == GCC_OBJECT_KEY && pRoster->session_key.application_protocol_key.object_id.long_string_length == sizeof(g_T126KeyNodes) / sizeof(g_T126KeyNodes[0]) && !memcmp (pRoster->session_key.application_protocol_key.object_id.long_string, g_T126KeyNodes, sizeof(g_T126KeyNodes)))) { cOtherMembers++; m_instanceNumber = pRoster->instance_number;
if(T120_GetNodeVersion(m_nConfID, pRecord->node_id) < 0x404) { m_bConferenceOnlyNetmeetingNodes = FALSE; }
} }
//
// Can we do 24 color bitmap
//
BOOL nodeCanDo24BitBitmap = FALSE; BOOL nodeCanDoText = FALSE; for (k = 0; k < pRecord->number_of_non_collapsed_caps; k++) { //
// Check if the node handles 24 bit bitmaps
//
if(pRecord->non_collapsed_caps_list[k]->application_data->length == sizeof(T126_24BIT_STRING)) { if(!memcmp(pRecord->non_collapsed_caps_list[k]->application_data->value, T126_24BIT_STRING ,sizeof(T126_24BIT_STRING))) { nodeCanDo24BitBitmap = TRUE; } }
//
// Check if the node handles text
//
if(pRecord->non_collapsed_caps_list[k]->application_data->length == sizeof(T126_TEXT_STRING)) { if(!memcmp(pRecord->non_collapsed_caps_list[k]->application_data->value, T126_TEXT_STRING ,sizeof(T126_TEXT_STRING))) { nodeCanDoText = TRUE; } } }
conferenceCanDo24BitBitmap &= nodeCanDo24BitBitmap; conferenceCanDoText &= nodeCanDoText; } } // for
m_bConferenceCanDo24BitBitmaps = conferenceCanDo24BitBitmap; m_bConferenceCanDoText = conferenceCanDoText; } // for
// If there are changes, we then do the update
if (fAdded || fRemoved || cOtherMembers != m_cOtherMembers) { MEMBER_ID aTempMembers[MAX_MEMBERS]; // scratch copy
// make sure we are able to handle it
if (cOtherMembers >= MAX_MEMBERS) { ERROR_OUT(("CNMWbObj::OnRosterIndication: we hit the max members limit, cOtherMembers=%u, max-members=%u", cOtherMembers, MAX_MEMBERS)); cOtherMembers = MAX_MEMBERS; }
// reset the flags for members added and removed
fAdded = FALSE; fRemoved = FALSE;
// copy the members
ULONG idxTempMember = 0; for (i = 0; i < cRosters; i++) { GCCAppRoster *pRoster = apRosters[i];
// bail out if this roster is not for this session
if (pRoster->session_key.session_id != m_sidMyself) { continue; }
// parse the roster records
for (j = 0; j < pRoster->number_of_records; j++) { GCCAppRecord *pRecord = pRoster->application_record_list[j]; if (pRecord->is_enrolled_actively) { MEMBER_ID nMemberID = MAKE_MEMBER_ID(pRecord->node_id, pRecord->application_user_id); if (nMemberID != g_MyMemberID && idxTempMember < cOtherMembers) { aTempMembers[idxTempMember++] = nMemberID;
// let's see if it is an 'add' or a 'delete'
for (k = 0; k < m_cOtherMembers; k++) { if (m_aMembers[k] == nMemberID) { m_aMembers[k] = 0; break; } } fAdded |= (k >= m_cOtherMembers); // not found, must be new
} } } // for
} // for
// sanity check
ASSERT(idxTempMember == cOtherMembers);
// see if there are ones that are not in the new roster.
// if so, they must be removed.
for (k = 0; k < m_cOtherMembers; k++) { if (m_aMembers[k]) { fRemoved = TRUE;
ULONG memberID = GET_USER_ID_FROM_MEMBER_ID(m_aMembers[k]);
TRACE_DEBUG(("OnRosterIndication removing RemotePointer from member =%x", memberID));
RemoveRemotePointer(memberID);
//
// if the refresher went away
//
if(g_RefresherID == memberID) { GrabRefresherToken(); }
//
// if node locking went away
//
if(m_LockerID == memberID) { TogleLockInAllWorkspaces(FALSE, FALSE); // Not locked, don't send updates
g_pMain->UnlockDrawingArea(); g_pMain->m_TB.PopUp(IDM_LOCK); g_pMain->UncheckMenuItem(IDM_LOCK); m_LockerID = 0; } } }
// now, update the member array
m_cOtherMembers = cOtherMembers; if (m_cOtherMembers) { ASSERT(sizeof(m_aMembers[0]) == sizeof(aTempMembers[0])); ::CopyMemory(&m_aMembers[0], &aTempMembers[0], m_cOtherMembers * sizeof(m_aMembers[0])); }
// if added, resend all objects
if (fAdded && (m_bImTheT126Refresher)) { //
// Tell the new node that I'm the refresher
//
SendWorkspaceRefreshPDU(TRUE);
//
// Refresh the new node
//
ResendAllObjects();
//
// if node locking everybody went away
//
if(m_LockerID == g_MyMemberID) { TogleLockInAllWorkspaces(TRUE, TRUE); // Locked, send updates
}
//
// Syncronize it
//
if(g_pCurrentWorkspace) { g_pCurrentWorkspace->OnObjectEdit(); } }
// finally, update the caption
if(g_pMain) { g_pMain->UpdateWindowTitle(); } } // if any change
} // if is in conf
}
void CNMWbObj::CleanupPerConf(void) { m_fInConference = FALSE; m_pAppletSession = NULL;
g_MyMemberID = 0; g_RefresherID = 0;
m_nConfID = 0; // Conf ID
m_uidMyself = 0; // User ID
m_sidMyself = 0; // Session ID
m_eidMyself = 0; // Entity ID
m_nidMyself = 0; // Node ID
m_bImTheTopProvider = FALSE; m_bImTheT126Refresher = FALSE; m_bConferenceOnlyNetmeetingNodes = TRUE; m_cOtherMembers = 0;
if(g_pMain) { g_pMain->UpdateWindowTitle(); RemoveRemotePointer(0); DeleteAllRetryPDUS(); g_pListOfObjectsThatRequestedHandles->EmptyList();
ASSERT(g_pDraw); //
// If we were locked
//
if(g_pDraw->IsLocked()) { m_LockerID = g_MyMemberID; TogleLockInAllWorkspaces(FALSE, FALSE); // Not locked, don't send updates
g_pMain->UnlockDrawingArea(); g_pMain->m_TB.PopUp(IDM_LOCK); g_pMain->UncheckMenuItem(IDM_LOCK); } } m_LockerID = 0; }
T120Error CNMWbObj::SendData ( T120Priority ePriority, ULONG cbDataSize, PBYTE pbData ) { T120Error rc;
if (IsInConference()) { rc = m_pAppletSession->SendData( UNIFORM_SEND_DATA, _SI_CHANNEL_0, ePriority, pbData, cbDataSize, APP_ALLOCATION); } else { rc = GCC_CONFERENCE_NOT_ESTABLISHED; }
return rc; }
T120Error CNMWbObj::GrabRefresherToken(void) { T120Error rc;
if (IsInConference()) { T120TokenRequest Req;
Req.eCommand = APPLET_GRAB_TOKEN; Req.nTokenID = _SI_WORKSPACE_REFRESH_TOKEN; Req.uidGiveTo = m_uidMyself; Req.eGiveResponse = T120_RESULT_SUCCESSFUL;
rc = m_pAppletSession->TokenRequest(&Req); if (T120_NO_ERROR != rc) { WARNING_OUT(("CNMWbObj::AllocateHandles: TokenRequest")); } } else { rc = GCC_CONFERENCE_NOT_ESTABLISHED; }
return rc; }
T120Error CNMWbObj::AllocateHandles ( ULONG cHandles ) { T120Error rc;
if ( cHandles > 0 && IsInConference()) { T120RegistryRequest Req; Req.eCommand = APPLET_ALLOCATE_HANDLE; Req.pRegistryKey = NULL; Req.cHandles = cHandles;
rc = m_pAppletSession->RegistryRequest(&Req); if (T120_NO_ERROR != rc) { ERROR_OUT(("CNMWbObj::AllocateHandles: RegistryRequest(cHandles=%u), rc=%u", cHandles, rc)); } } else { rc = GCC_CONFERENCE_NOT_ESTABLISHED; }
return rc; }
|