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.

1430 lines
31 KiB

  1. #include "precomp.h"
  2. #include "gcchelp.h"
  3. #include "coder.hpp"
  4. #include "drawobj.hpp"
  5. #include "NMWbObj.h"
  6. extern Coder * g_pCoder;
  7. UINT AllocateFakeGCCHandle(void)
  8. {
  9. return g_localGCCHandle++;
  10. }
  11. void SetFakeGCCHandle(UINT fakeGCCHandle)
  12. {
  13. g_localGCCHandle = fakeGCCHandle;
  14. }
  15. //
  16. // Add drawings/bitmaps etc... to workspace
  17. //
  18. BOOL AddT126ObjectToWorkspace(T126Obj *pObj)
  19. {
  20. WorkspaceObj * pWorkspace = GetWorkspace(pObj->GetWorkspaceHandle());
  21. if(pWorkspace)
  22. {
  23. pWorkspace->AddTail(pObj);
  24. g_numberOfObjects++;
  25. return TRUE;
  26. }
  27. else
  28. {
  29. WARNING_OUT(("Object sent to invalid workspace %d, will be deleted now!!!", GetWorkspace(pObj->GetWorkspaceHandle())));
  30. delete pObj;
  31. return FALSE;
  32. }
  33. }
  34. //
  35. // Cleanup for all pdus we send
  36. //
  37. void SIPDUCleanUp(SIPDU *sipdu)
  38. {
  39. switch(sipdu->choice)
  40. {
  41. //
  42. // Simple cleanup
  43. //
  44. case bitmapDeletePDU_chosen:
  45. case drawingDeletePDU_chosen:
  46. case workspaceDeletePDU_chosen:
  47. case workspaceRefreshStatusPDU_chosen:
  48. break;
  49. //
  50. // Bitmap Create cleanup
  51. //
  52. case bitmapCreatePDU_chosen:
  53. {
  54. if(sipdu->u.bitmapCreatePDU.nonStandardParameters)
  55. {
  56. delete sipdu->u.bitmapCreatePDU.nonStandardParameters;
  57. }
  58. PBitmapCreatePDU_attributes pAttrib;
  59. PBitmapCreatePDU_attributes pNextAttrib;
  60. pAttrib = sipdu->u.bitmapCreatePDU.attributes;
  61. while(pAttrib)
  62. {
  63. pNextAttrib = pAttrib->next;
  64. delete pAttrib;
  65. pAttrib = pNextAttrib;
  66. }
  67. }
  68. break;
  69. case bitmapEditPDU_chosen:
  70. {
  71. BitmapEditPDU_attributeEdits * pAttrib;
  72. BitmapEditPDU_attributeEdits * pNextAttrib;
  73. pAttrib = sipdu->u.bitmapEditPDU.attributeEdits;
  74. while(pAttrib)
  75. {
  76. pNextAttrib = pAttrib->next;
  77. delete pAttrib;
  78. pAttrib = pNextAttrib;
  79. }
  80. }
  81. break;
  82. //
  83. // Bitmap Continue cleanup
  84. //
  85. case bitmapCreateContinuePDU_chosen:
  86. {
  87. if(sipdu->u.bitmapCreateContinuePDU.nonStandardParameters)
  88. {
  89. delete sipdu->u.bitmapCreateContinuePDU.nonStandardParameters;
  90. }
  91. }
  92. break;
  93. //
  94. // Drawing Edit Cleanup
  95. //
  96. case drawingEditPDU_chosen:
  97. {
  98. if(sipdu->u.drawingEditPDU.bit_mask & DrawingEditPDU_attributeEdits_present)
  99. {
  100. PDrawingEditPDU_attributeEdits pAttrib;
  101. PDrawingEditPDU_attributeEdits pNextAttrib;
  102. pAttrib = sipdu->u.drawingEditPDU.attributeEdits;
  103. while(pAttrib)
  104. {
  105. pNextAttrib = pAttrib->next;
  106. delete pAttrib;
  107. pAttrib = pNextAttrib;
  108. }
  109. }
  110. if(sipdu->u.drawingEditPDU.pointListEdits.value[0].subsequentPointEdits.u.pointsDiff16)
  111. {
  112. PPointList_pointsDiff16 drawingPoint = sipdu->u.drawingEditPDU.pointListEdits.value[0].subsequentPointEdits.u.pointsDiff16;
  113. PPointList_pointsDiff16 drawingPointNext = drawingPoint;
  114. while(drawingPointNext)
  115. {
  116. drawingPointNext = drawingPoint->next;
  117. delete drawingPoint;
  118. drawingPoint = drawingPointNext;
  119. }
  120. }
  121. }
  122. break;
  123. //
  124. // Drawing Edit cleanup
  125. //
  126. case drawingCreatePDU_chosen:
  127. {
  128. PDrawingCreatePDU_attributes pNextAttrib;
  129. PDrawingCreatePDU_attributes pAttrib;
  130. pAttrib = sipdu->u.drawingCreatePDU.attributes;
  131. while(pAttrib)
  132. {
  133. pNextAttrib = pAttrib->next;
  134. delete pAttrib;
  135. pAttrib = pNextAttrib;
  136. }
  137. PPointList_pointsDiff16 pNextPoint;
  138. PPointList_pointsDiff16 pPoint;
  139. pPoint = sipdu->u.drawingCreatePDU.pointList.u.pointsDiff16;
  140. while(pPoint)
  141. {
  142. pNextPoint = pPoint->next;
  143. delete pPoint;
  144. pPoint = pNextPoint;
  145. }
  146. }
  147. break;
  148. //
  149. // Non Standard cleanup
  150. //
  151. case siNonStandardPDU_chosen:
  152. if(sipdu->u.siNonStandardPDU.nonStandardTransaction.data.value)
  153. {
  154. delete sipdu->u.siNonStandardPDU.nonStandardTransaction.data.value;
  155. }
  156. break;
  157. //
  158. // Workspace Edit cleanup
  159. //
  160. case workspaceEditPDU_chosen:
  161. {
  162. if(sipdu->u.workspaceEditPDU.bit_mask & viewEdits_present)
  163. {
  164. PWorkspaceEditPDU_viewEdits_Set_action_editView pEditView = sipdu->u.workspaceEditPDU.viewEdits->value.action.u.editView;
  165. PWorkspaceEditPDU_viewEdits_Set_action_editView pNextEditView = pEditView;
  166. while(pNextEditView)
  167. {
  168. pNextEditView = pEditView->next;
  169. delete pEditView;
  170. pEditView = pNextEditView;
  171. }
  172. delete sipdu->u.workspaceEditPDU.viewEdits;
  173. }
  174. }
  175. break;
  176. //
  177. // Workspace Create cleanup
  178. //
  179. case workspaceCreatePDU_chosen:
  180. {
  181. if(sipdu->u.workspaceCreatePDU.viewParameters)
  182. {
  183. if(sipdu->u.workspaceCreatePDU.viewParameters->value.viewAttributes)
  184. {
  185. delete sipdu->u.workspaceCreatePDU.viewParameters->value.viewAttributes;
  186. }
  187. delete sipdu->u.workspaceCreatePDU.viewParameters;
  188. }
  189. if(sipdu->u.workspaceCreatePDU.planeParameters)
  190. {
  191. PWorkspaceCreatePDU_planeParameters_Seq_usage pNextUsage;
  192. PWorkspaceCreatePDU_planeParameters_Seq_usage pUsage = sipdu->u.workspaceCreatePDU.planeParameters->value.usage;
  193. while(pUsage)
  194. {
  195. pNextUsage = pUsage->next;
  196. delete pUsage;
  197. pUsage = pNextUsage;
  198. }
  199. delete sipdu->u.workspaceCreatePDU.planeParameters->value.planeAttributes;
  200. PWorkspaceCreatePDU_planeParameters pNextPlaneParameters;
  201. PWorkspaceCreatePDU_planeParameters pPlaneParameters = sipdu->u.workspaceCreatePDU.planeParameters;
  202. while(pPlaneParameters)
  203. {
  204. pNextPlaneParameters = pPlaneParameters->next;
  205. delete pPlaneParameters;
  206. pPlaneParameters = pNextPlaneParameters;
  207. }
  208. }
  209. }
  210. break;
  211. default:
  212. ERROR_OUT(("UNKNOWN PDU TYPE = %d we may leak memory", sipdu->choice));
  213. break;
  214. }
  215. delete sipdu;
  216. }
  217. //
  218. // Cleans the retry list, when we close down or disconnect
  219. //
  220. void DeleteAllRetryPDUS(void)
  221. {
  222. SIPDU * sipdu;
  223. while((sipdu = (SIPDU *)g_pRetrySendList->RemoveTail()) != NULL)
  224. {
  225. SIPDUCleanUp(sipdu);
  226. }
  227. }
  228. //
  229. // Retry sending buffered pdus and send the new pdu
  230. //
  231. T120Error SendT126PDU(SIPDU * pPDU)
  232. {
  233. MLZ_EntryOut(ZONE_FUNCTION, "SendT126PDU");
  234. //
  235. // First send buffered pdus
  236. //
  237. RetrySend();
  238. //
  239. // Now send the current pdu
  240. //
  241. T120Error rc = SendPDU(pPDU, FALSE);
  242. return rc;
  243. }
  244. //
  245. // Retry sending pdus that couldn't be sent before
  246. //
  247. void RetrySend(void)
  248. {
  249. MLZ_EntryOut(ZONE_FUNCTION, "RetrySend");
  250. if(g_fWaitingForBufferAvailable)
  251. {
  252. return;
  253. }
  254. TRACE_MSG(("RetrySend"));
  255. SIPDU * sipdu;
  256. while((sipdu = (SIPDU *)g_pRetrySendList->RemoveTail()) != NULL)
  257. {
  258. TRACE_DEBUG(("RetrySend sipdu->choice = %d", sipdu->choice));
  259. T120Error rc = SendPDU(sipdu, TRUE);
  260. if(rc == T120_NO_ERROR)
  261. {
  262. TRACE_DEBUG(("RetrySend OK!!!"));
  263. SIPDUCleanUp(sipdu);
  264. }
  265. else
  266. {
  267. TRACE_DEBUG(("RetrySend Failed"));
  268. break;
  269. }
  270. }
  271. }
  272. //
  273. // Send T126 pdus down to the conference
  274. //
  275. T120Error SendPDU(SIPDU * pPDU, BOOL bRetry)
  276. {
  277. MLZ_EntryOut(ZONE_FUNCTION, "SendPDU");
  278. T120Error rc = T120_NO_ERROR;
  279. //
  280. // If we are in a conference
  281. //
  282. if(g_pNMWBOBJ->IsInConference() || g_bSavingFile)
  283. {
  284. ASN1_BUF encodedPDU;
  285. g_pCoder->Encode(pPDU, &encodedPDU);
  286. if(g_bSavingFile)
  287. {
  288. g_pMain->ObjectSave(TYPE_T126_ASN_OBJECT, encodedPDU.value, encodedPDU.length);
  289. }
  290. else
  291. {
  292. if(!g_fWaitingForBufferAvailable)
  293. {
  294. T120Priority ePriority = APPLET_LOW_PRIORITY;
  295. if(pPDU->choice == workspaceCreatePDU_chosen ||
  296. pPDU->choice == workspaceEditPDU_chosen ||
  297. pPDU->choice == workspaceDeletePDU_chosen)
  298. {
  299. //
  300. // Do what the standard says send the pdus in 3 different priorities
  301. //
  302. TRACE_MSG(("SendPDU sending PDU length = %d in APPLET_HIGH_PRIORITY", encodedPDU.length));
  303. rc = g_pNMWBOBJ->SendData(APPLET_HIGH_PRIORITY,
  304. encodedPDU.length,
  305. encodedPDU.value);
  306. TRACE_MSG(("SendPDU sending PDU length = %d in APPLET_MEDIUM_PRIORITY", encodedPDU.length));
  307. if(rc == T120_NO_ERROR)
  308. {
  309. rc = g_pNMWBOBJ->SendData(APPLET_MEDIUM_PRIORITY,
  310. encodedPDU.length,
  311. encodedPDU.value);
  312. }
  313. }
  314. TRACE_MSG(("SendPDU sending PDU length = %d in APPLET_LOW_PRIORITY", encodedPDU.length));
  315. if(rc == T120_NO_ERROR)
  316. {
  317. rc = g_pNMWBOBJ->SendData(ePriority,
  318. encodedPDU.length,
  319. encodedPDU.value);
  320. }
  321. if(rc == MCS_TRANSMIT_BUFFER_FULL)
  322. {
  323. g_fWaitingForBufferAvailable = TRUE;
  324. //
  325. // We need to add it back to the correct position
  326. //
  327. if(bRetry)
  328. {
  329. g_pRetrySendList->AddTail(pPDU);
  330. }
  331. else
  332. {
  333. g_pRetrySendList->AddHead(pPDU);
  334. }
  335. }
  336. }
  337. else
  338. {
  339. rc = MCS_TRANSMIT_BUFFER_FULL;
  340. g_pRetrySendList->AddHead(pPDU);
  341. }
  342. }
  343. // Free the encoder memory
  344. g_pCoder->Free(encodedPDU);
  345. }
  346. return rc;
  347. }
  348. BOOL T126_MCSSendDataIndication(ULONG uSize, LPBYTE pb, ULONG memberID, BOOL bResend)
  349. {
  350. BOOL bRet = TRUE;
  351. SIPDU * pDecodedPDU;
  352. ASN1_BUF InputBuffer;
  353. InputBuffer.length = uSize;
  354. InputBuffer.value = pb;
  355. //
  356. // Decode incoming PDU
  357. if(ASN1_SUCCEEDED(g_pCoder->Decode(&InputBuffer, &pDecodedPDU)))
  358. {
  359. switch(pDecodedPDU->choice)
  360. {
  361. // case (archiveAcknowledgePDU_chosen):
  362. // {
  363. // TRACE_DEBUG((">>> Received a archiveAcknowledgePDU"));
  364. // TRACE_DEBUG(("No action taken"));
  365. // break;
  366. // }
  367. // case (archiveClosePDU_chosen):
  368. // {
  369. // TRACE_DEBUG((">>> Received a archiveClosePDU"));
  370. // TRACE_DEBUG(("No action taken"));
  371. // break;
  372. // }
  373. // case (archiveErrorPDU_chosen):
  374. // {
  375. // TRACE_DEBUG((">>> Received a archiveErrorPDU"));
  376. // TRACE_DEBUG(("No action taken"));
  377. // break;
  378. // }
  379. // case (archiveOpenPDU_chosen):
  380. // {
  381. // TRACE_DEBUG((">>> Received a archiveOpenPDU"));
  382. // TRACE_DEBUG(("No action taken"));
  383. // break;
  384. // }
  385. case (bitmapAbortPDU_chosen):
  386. {
  387. TRACE_DEBUG((">>> Received a bitmapAbortPDU"));
  388. OnBitmapAbortPDU(&pDecodedPDU->u.bitmapAbortPDU, memberID);
  389. break;
  390. }
  391. case (bitmapCheckpointPDU_chosen):
  392. {
  393. TRACE_DEBUG((">>> Received a bitmapCheckpointPDU"));
  394. OnBitmapCheckpointPDU(&pDecodedPDU->u.bitmapCheckpointPDU, memberID);
  395. break;
  396. }
  397. case (bitmapCreatePDU_chosen):
  398. {
  399. TRACE_DEBUG((">>> Received a bitmapCreatePDU"));
  400. OnBitmapCreatePDU(&pDecodedPDU->u.bitmapCreatePDU, memberID, bResend);
  401. break;
  402. }
  403. case (bitmapCreateContinuePDU_chosen):
  404. {
  405. TRACE_DEBUG((">>> Received a bitmapCreateContinuePDU"));
  406. OnBitmapCreateContinuePDU(&pDecodedPDU->u.bitmapCreateContinuePDU, memberID, bResend);
  407. break;
  408. }
  409. case (bitmapDeletePDU_chosen):
  410. {
  411. TRACE_DEBUG((">>> Received a bitmapDeletePDU"));
  412. OnBitmapDeletePDU(&pDecodedPDU->u.bitmapDeletePDU, memberID);
  413. break;
  414. }
  415. case (bitmapEditPDU_chosen):
  416. {
  417. TRACE_DEBUG((">>> Received a bitmapEditPDU"));
  418. OnBitmapEditPDU(&pDecodedPDU->u.bitmapEditPDU, memberID);
  419. break;
  420. }
  421. case (conductorPrivilegeGrantPDU_chosen):
  422. {
  423. TRACE_DEBUG((">>> Received a conductorPrivilegeGrantPDU"));
  424. TRACE_DEBUG(("No action taken"));
  425. break;
  426. }
  427. case (conductorPrivilegeRequestPDU_chosen):
  428. {
  429. TRACE_DEBUG((">>> Received a conductorPrivilegeRequestPDU"));
  430. TRACE_DEBUG(("No action taken"));
  431. break;
  432. }
  433. case (drawingCreatePDU_chosen):
  434. {
  435. TRACE_DEBUG((">>> Received a drawingCreatePDU"));
  436. OnDrawingCreatePDU(&pDecodedPDU->u.drawingCreatePDU, memberID, bResend);
  437. break;
  438. }
  439. case (drawingDeletePDU_chosen):
  440. {
  441. TRACE_DEBUG((">>> Received a drawingDeletePDU"));
  442. OnDrawingDeletePDU(&pDecodedPDU->u.drawingDeletePDU, memberID);
  443. break;
  444. }
  445. case (drawingEditPDU_chosen):
  446. {
  447. TRACE_DEBUG((">>> Received a drawingEditPDU"));
  448. OnDrawingEditPDU(&pDecodedPDU->u.drawingEditPDU, memberID, bResend);
  449. break;
  450. }
  451. // case (remoteEventPermissionGrantPDU_chosen):
  452. // {
  453. // TRACE_DEBUG((">>> Received a remoteEventPermissionGrantPDU"));
  454. // TRACE_DEBUG(("No action taken"));
  455. // break;
  456. // }
  457. // case (remoteEventPermissionRequestPDU_chosen):
  458. // {
  459. // TRACE_DEBUG((">>> Received a remoteEventPermissionRequestPDU"));
  460. // TRACE_DEBUG(("No action taken"));
  461. // break;
  462. // }
  463. // case (remoteKeyboardEventPDU_chosen):
  464. // {
  465. // TRACE_DEBUG((">>> Received a remoteKeyboardEventPDU"));
  466. // TRACE_DEBUG(("No action taken"));
  467. // break;
  468. // }
  469. // case (remotePointingDeviceEventPDU_chosen):
  470. // {
  471. // TRACE_DEBUG((">>> Received a remotePointingDeviceEventPDU"));
  472. // TRACE_DEBUG(("No action taken"));
  473. // break;
  474. // }
  475. // case (remotePrintPDU_chosen):
  476. // {
  477. // TRACE_DEBUG((">>> Received a remotePrintPDU"));
  478. // TRACE_DEBUG(("No action taken"));
  479. // break;
  480. // }
  481. case (siNonStandardPDU_chosen):
  482. {
  483. if(pDecodedPDU->u.siNonStandardPDU.nonStandardTransaction.nonStandardIdentifier.choice == h221nonStandard_chosen)
  484. {
  485. PT126_VENDORINFO pVendorInfo = (PT126_VENDORINFO)pDecodedPDU->u.siNonStandardPDU.nonStandardTransaction.nonStandardIdentifier.u.h221nonStandard.value;
  486. if (!lstrcmp((LPSTR)&pVendorInfo->nonstandardString, NonStandardTextID))
  487. {
  488. TEXTPDU_HEADER *pHeader = (TEXTPDU_HEADER*) pDecodedPDU->u.siNonStandardPDU.nonStandardTransaction.data.value;
  489. switch(pHeader->nonStandardPDU)
  490. {
  491. case textCreatePDU_chosen:
  492. TRACE_DEBUG((">>> Received a textCreatePDU_chosen"));
  493. OnTextCreatePDU((MSTextPDU*)pHeader, memberID, bResend);
  494. break;
  495. case textEditPDU_chosen:
  496. TRACE_DEBUG((">>> Received a textEditPDU_chosen"));
  497. OnTextEditPDU((MSTextPDU*)pHeader, memberID);
  498. break;
  499. case textDeletePDU_chosen:
  500. TRACE_DEBUG((">>> Received a textDeletePDU_chosen"));
  501. OnTextDeletePDU(pHeader, memberID);
  502. break;
  503. default:
  504. TRACE_DEBUG(("Invalid text pdu"));
  505. break;
  506. }
  507. }
  508. }
  509. break;
  510. }
  511. case (workspaceCreatePDU_chosen):
  512. {
  513. TRACE_DEBUG((">>> Received a workspaceCreatePDU"));
  514. OnWorkspaceCreatePDU(&pDecodedPDU->u.workspaceCreatePDU, memberID, bResend);
  515. break;
  516. }
  517. case (workspaceCreateAcknowledgePDU_chosen):
  518. {
  519. TRACE_DEBUG((">>> Received a workspaceCreateAcknowledgePDU"));
  520. OnWorkspaceCreateAcknowledgePDU(&pDecodedPDU->u.workspaceCreateAcknowledgePDU, memberID);
  521. break;
  522. }
  523. case (workspaceDeletePDU_chosen):
  524. {
  525. TRACE_DEBUG((">>> Received a workspaceDeletePDU"));
  526. OnWorkspaceDeletePDU(&pDecodedPDU->u.workspaceDeletePDU, memberID);
  527. break;
  528. }
  529. case (workspaceEditPDU_chosen):
  530. {
  531. TRACE_DEBUG((">>> Received a workspaceEditPDU"));
  532. OnWorkspaceEditPDU(&pDecodedPDU->u.workspaceEditPDU, memberID);
  533. break;
  534. }
  535. case (workspacePlaneCopyPDU_chosen):
  536. {
  537. TRACE_DEBUG((">>> Received a workspacePlaneCopyPDU"));
  538. OnWorkspacePlaneCopyPDU(&pDecodedPDU->u.workspacePlaneCopyPDU, memberID);
  539. break;
  540. }
  541. case (workspaceReadyPDU_chosen):
  542. {
  543. TRACE_DEBUG((">>> Received a workspaceReadyPDU"));
  544. OnWorkspaceReadyPDU(&pDecodedPDU->u.workspaceReadyPDU, memberID);
  545. break;
  546. }
  547. case (workspaceRefreshStatusPDU_chosen):
  548. {
  549. TRACE_DEBUG((">>> Received a workspaceRefreshStatusPDU"));
  550. OnWorkspaceRefreshStatusPDU(&pDecodedPDU->u.workspaceRefreshStatusPDU, memberID);
  551. break;
  552. }
  553. // case (fontPDU_chosen):
  554. // {
  555. // TRACE_DEBUG((">>> Received a fontPDU"));
  556. // TRACE_DEBUG(("No action taken"));
  557. // break;
  558. // }
  559. // case (textCreatePDU_chosen):
  560. // {
  561. // TRACE_DEBUG((">>> Received a textCreatePDU"));
  562. // TRACE_DEBUG(("No action taken"));
  563. // break;
  564. // }
  565. // case (textDeletePDU_chosen):
  566. // {
  567. // TRACE_DEBUG((">>> Received a textDeletePDU"));
  568. // TRACE_DEBUG(("No action taken"));
  569. // break;
  570. // }
  571. // case (textEditPDU_chosen):
  572. // {
  573. // TRACE_DEBUG((">>> Received a textEditPDU"));
  574. // TRACE_DEBUG(("No action taken"));
  575. // break;
  576. // }
  577. // case (videoWindowCreatePDU_chosen):
  578. // {
  579. // TRACE_DEBUG((">>> Received a videoWindowCreatePDU"));
  580. // TRACE_DEBUG(("No action taken"));
  581. // break;
  582. // }
  583. // case (videoWindowDeleatePDU_chosen):
  584. // {
  585. // TRACE_DEBUG((">>> Received a videoWindowDeleatePDU"));
  586. // TRACE_DEBUG(("No action taken"));
  587. // break;
  588. // }
  589. // case (videoWindowEditPDU_chosen):
  590. // {
  591. // TRACE_DEBUG((">>> Received a videoWindowEditPDU"));
  592. // TRACE_DEBUG(("No action taken"));
  593. // break;
  594. // }
  595. default:
  596. bRet = FALSE;
  597. TRACE_DEBUG(("Receive an Unhandled PDU choice = %d", pDecodedPDU->choice));
  598. break;
  599. }
  600. }
  601. //
  602. // Free the decoded pdu
  603. // JOSEF: for performance in the future we could pass
  604. // the decoded buffer to the ui, avoiding more memory allocation.
  605. // But it will be hard to read the code, since the T126 structures
  606. // are a bit confusing.
  607. //
  608. g_pCoder->Free(pDecodedPDU);
  609. return bRet;
  610. }
  611. //
  612. // Delete All Workspaces sent and received
  613. //
  614. void DeleteAllWorkspaces(BOOL sendPDU)
  615. {
  616. T126Obj * pObj;
  617. if(g_pDraw && g_pDraw->m_pTextEditor)
  618. {
  619. g_pDraw->m_pTextEditor->AbortEditGently();
  620. }
  621. g_pCurrentWorkspace = NULL;
  622. g_pConferenceWorkspace = NULL;
  623. while ((pObj = (T126Obj *)g_pListOfWorkspaces->RemoveTail()) != NULL)
  624. {
  625. if(sendPDU)
  626. {
  627. pObj->DeletedLocally();
  628. }
  629. else
  630. {
  631. pObj->ClearDeletionFlags();
  632. }
  633. delete pObj;
  634. }
  635. if(g_pMain)
  636. {
  637. g_pMain->EnableToolbar(FALSE);
  638. g_pMain->UpdatePageButtons();
  639. }
  640. }
  641. /////////////////////////////////////////////////////////////////////////////////////////////
  642. // TEXT PDUS
  643. /////////////////////////////////////////////////////////////////////////////////////////////
  644. void OnTextCreatePDU(MSTextPDU* pCreatePDU, ULONG memberID, BOOL bForcedResend)
  645. {
  646. WorkspaceObj* pWObj;
  647. WbTextEditor * pText;
  648. //
  649. // Check for resend
  650. //
  651. if(!bForcedResend)
  652. {
  653. pWObj = GetWorkspace(pCreatePDU->header.workspaceHandle);
  654. if(pWObj)
  655. {
  656. pText = (WbTextEditor *)pWObj->FindObjectInWorkspace(pCreatePDU->header.textHandle);
  657. if(pText)
  658. {
  659. TRACE_DEBUG(("drawingHandle already used = %d", pCreatePDU->header.textHandle ));
  660. return;
  661. }
  662. }
  663. }
  664. //
  665. // New Drawing object
  666. //
  667. DBG_SAVE_FILE_LINE
  668. pText = new WbTextEditor();
  669. pText->SetWorkspaceHandle(pCreatePDU->header.workspaceHandle);
  670. pText->SetThisObjectHandle(pCreatePDU->header.textHandle);
  671. if(!bForcedResend)
  672. {
  673. //
  674. // Some one sent us this drawing, it is not created locally
  675. //
  676. pText->ClearCreationFlags();
  677. //
  678. // Add a this drawing to the correct workspace
  679. //
  680. if(!AddT126ObjectToWorkspace(pText))
  681. {
  682. return;
  683. }
  684. }
  685. else
  686. {
  687. //
  688. // Add this object and send Create PDU
  689. //
  690. pText->SetAllAttribs();
  691. pText->SetWorkspaceHandle(g_pCurrentWorkspace == NULL ? 0 : g_pCurrentWorkspace->GetWorkspaceHandle());
  692. pText->ClearSelectionFlags();
  693. pText->GetTextAttrib(&pCreatePDU->attrib);
  694. pText->AddToWorkspace();
  695. pText->Draw();
  696. return;
  697. }
  698. pText->TextEditObj(&pCreatePDU->attrib);
  699. pText->Draw();
  700. pText->ResetAttrib();
  701. }
  702. void OnTextDeletePDU(TEXTPDU_HEADER *pHeader, ULONG memberID)
  703. {
  704. T126Obj* pText;
  705. WorkspaceObj* pWorkspace;
  706. // We should find this drawing object
  707. if(FindObjectAndWorkspace(pHeader->textHandle, (T126Obj**)&pText, (WorkspaceObj**)&pWorkspace))
  708. {
  709. pText->SetOwnerID(memberID);
  710. pWorkspace->RemoveT126Object(pText);
  711. }
  712. }
  713. void OnTextEditPDU(MSTextPDU *pEditPDU, ULONG memberID)
  714. {
  715. TextObj* pText;
  716. WorkspaceObj* pWorkspace;
  717. // We should find this drawing object
  718. if(FindObjectAndWorkspace(pEditPDU->header.textHandle, (T126Obj **)&pText, (WorkspaceObj**)&pWorkspace))
  719. {
  720. pText->SetOwnerID(memberID);
  721. pText->TextEditObj(&pEditPDU->attrib);
  722. }
  723. }
  724. /////////////////////////////////////////////////////////////////////////////////////////////
  725. // DRAWING PDUS
  726. /////////////////////////////////////////////////////////////////////////////////////////////
  727. void OnDrawingCreatePDU(DrawingCreatePDU * pdrawingCreatePDU, ULONG memberID, BOOL bForcedResend)
  728. {
  729. WorkspaceObj* pWObj;
  730. DrawObj * pDraw;
  731. UINT workspace;
  732. UINT planeID;
  733. //
  734. // If we don't have a drawing handle dont take it
  735. //
  736. if(!(pdrawingCreatePDU->bit_mask & drawingHandle_present))
  737. {
  738. TRACE_DEBUG(("Got a DrawingCreatePDU but no drawingHandle" ));
  739. return;
  740. }
  741. GetDrawingDestinationAddress(&pdrawingCreatePDU->destinationAddress, &workspace, &planeID);
  742. //
  743. // Check for resend
  744. //
  745. if(!bForcedResend)
  746. {
  747. pWObj = GetWorkspace(workspace);
  748. if(pWObj)
  749. {
  750. pDraw = (DrawObj *)pWObj->FindObjectInWorkspace(pdrawingCreatePDU->drawingHandle);
  751. if(pDraw)
  752. {
  753. TRACE_DEBUG(("drawingHandle already used = %d", pdrawingCreatePDU->drawingHandle ));
  754. return;
  755. }
  756. }
  757. }
  758. //
  759. // New Drawing object
  760. //
  761. DBG_SAVE_FILE_LINE
  762. pDraw = new DrawObj(pdrawingCreatePDU);
  763. pDraw->SetOwnerID(memberID);
  764. if(!bForcedResend)
  765. {
  766. //
  767. // Some one sent us this drawing, it is not created locally
  768. //
  769. pDraw->ClearCreationFlags();
  770. //
  771. // Add a this drawing to the correct workspace
  772. //
  773. if(!AddT126ObjectToWorkspace(pDraw))
  774. {
  775. return;
  776. }
  777. }
  778. else
  779. {
  780. //
  781. // Add this object and send Create PDU
  782. //
  783. pDraw->SetAllAttribs();
  784. pDraw->SetWorkspaceHandle(g_pCurrentWorkspace == NULL ? 0 : g_pCurrentWorkspace->GetWorkspaceHandle());
  785. pDraw->ClearSelectionFlags();
  786. pDraw->AddToWorkspace();
  787. pDraw->Draw();
  788. return;
  789. }
  790. //
  791. // Draw it
  792. //
  793. if(pDraw->GetPenThickness())
  794. {
  795. pDraw->Draw();
  796. pDraw->ResetAttrib();
  797. }
  798. }
  799. void OnDrawingDeletePDU(DrawingDeletePDU * pdrawingDeletePDU, ULONG memberID)
  800. {
  801. DrawObj* pDraw;
  802. WorkspaceObj* pWorkspace;
  803. // We should find this drawing object
  804. if(FindObjectAndWorkspace(pdrawingDeletePDU->drawingHandle, (T126Obj **)&pDraw, (WorkspaceObj**)&pWorkspace))
  805. {
  806. pDraw->SetOwnerID(memberID);
  807. pWorkspace->RemoveT126Object((T126Obj*)pDraw);
  808. }
  809. }
  810. void OnDrawingEditPDU(DrawingEditPDU * pdrawingEditPDU, ULONG memberID, BOOL bResend)
  811. {
  812. DrawObj* pDraw;
  813. WorkspaceObj* pWorkspace;
  814. // We should find this drawing object
  815. if(FindObjectAndWorkspace(pdrawingEditPDU->drawingHandle, (T126Obj **)&pDraw, (WorkspaceObj**)&pWorkspace))
  816. {
  817. pDraw->SetOwnerID(memberID);
  818. pDraw->DrawEditObj(pdrawingEditPDU);
  819. }
  820. else
  821. {
  822. //
  823. // We are reading this pdu from disk add the rest of the line to the previous freehand drawing
  824. //
  825. if(bResend)
  826. {
  827. T126Obj * pObj;
  828. pObj = g_pCurrentWorkspace->GetTail();
  829. if(pObj && pObj->GetType() == drawingCreatePDU_chosen &&
  830. (pObj->GraphicTool() == TOOLTYPE_PEN || pObj->GraphicTool() == TOOLTYPE_HIGHLIGHT))
  831. {
  832. pdrawingEditPDU->drawingHandle = pObj->GetThisObjectHandle();
  833. pObj->SetOwnerID(memberID);
  834. ((DrawObj*)pObj)->DrawEditObj(pdrawingEditPDU);
  835. }
  836. }
  837. }
  838. }
  839. /////////////////////////////////////////////////////////////////////////////////////////////
  840. // WORKSPACE PDUS
  841. /////////////////////////////////////////////////////////////////////////////////////////////
  842. BOOL FindObjectAndWorkspace(UINT objectHandle, T126Obj** pObj, WorkspaceObj**pWorkspace)
  843. {
  844. WorkspaceObj * pWrkspc;
  845. T126Obj * pT126Obj;
  846. WBPOSITION pos;
  847. pos = g_pListOfWorkspaces->GetHeadPosition();
  848. while (pos != NULL)
  849. {
  850. pWrkspc = (WorkspaceObj *) g_pListOfWorkspaces->GetNext(pos);
  851. if(pWrkspc)
  852. {
  853. pT126Obj = pWrkspc->FindObjectInWorkspace(objectHandle);
  854. if(pT126Obj)
  855. {
  856. *pObj = pT126Obj;
  857. *pWorkspace = pWrkspc;
  858. return TRUE;
  859. }
  860. }
  861. }
  862. return FALSE;
  863. }
  864. //
  865. // Retrieves workspace from the list of workspaces
  866. //
  867. WorkspaceObj * GetWorkspace(UINT activeWorkspace)
  868. {
  869. WorkspaceObj * pWorkspaceObj;
  870. WBPOSITION pos;
  871. pos = g_pListOfWorkspaces->GetHeadPosition();
  872. while (pos != NULL)
  873. {
  874. pWorkspaceObj = (WorkspaceObj *) g_pListOfWorkspaces->GetNext(pos);
  875. if(pWorkspaceObj->GetWorkspaceHandle() == activeWorkspace)
  876. {
  877. return pWorkspaceObj;
  878. }
  879. }
  880. return NULL;
  881. }
  882. //
  883. // The remote sent us a new workspace
  884. //
  885. void OnWorkspaceCreatePDU(WorkspaceCreatePDU * pWorkspaceCreatePDU, ULONG memberID, BOOL bForcedResend)
  886. {
  887. TRACE_DEBUG(("OnWorkspaceCreatePDU WorkspaceIdentifier = %d", pWorkspaceCreatePDU->workspaceIdentifier.u.activeWorkspace));
  888. WorkspaceObj * pWorkspaceObj;
  889. //
  890. // Check for resend
  891. //
  892. if(!bForcedResend)
  893. {
  894. pWorkspaceObj = GetWorkspace(WorkspaceObj::GetWorkspaceIdentifier(&pWorkspaceCreatePDU->workspaceIdentifier));
  895. if(pWorkspaceObj)
  896. {
  897. return;
  898. }
  899. DBG_SAVE_FILE_LINE
  900. pWorkspaceObj = new WorkspaceObj(pWorkspaceCreatePDU, bForcedResend);
  901. pWorkspaceObj->SetOwnerID(memberID);
  902. }
  903. else
  904. {
  905. DBG_SAVE_FILE_LINE
  906. pWorkspaceObj = new WorkspaceObj(pWorkspaceCreatePDU, bForcedResend);
  907. pWorkspaceObj->SetOwnerID(memberID);
  908. }
  909. }
  910. //
  911. // If we created an unsynchronized workspace the remote has to sen us
  912. // a WorkspaceCreateAcknowledgePDU. Why???
  913. //
  914. void OnWorkspaceCreateAcknowledgePDU(WorkspaceCreateAcknowledgePDU * pWorkspaceCreateAcknowledgePDU, ULONG memberID)
  915. {
  916. TRACE_DEBUG(("OnWorkspaceCreateAcknowledgePDU WorkspaceIdentifier = %d", pWorkspaceCreateAcknowledgePDU->workspaceIdentifier));
  917. }
  918. //
  919. // The remote is deleting the workspace
  920. //
  921. void OnWorkspaceDeletePDU(WorkspaceDeletePDU * pWorkspaceDeletePDU, ULONG memberID)
  922. {
  923. TRACE_DEBUG(("OnWorkspaceDeletePDU WorkspaceIdentifier = %d", pWorkspaceDeletePDU->workspaceIdentifier.u.activeWorkspace));
  924. //
  925. // Find the workspace
  926. //
  927. WorkspaceObj * pWorkspaceObj;
  928. pWorkspaceObj = GetWorkspace(WorkspaceObj::GetWorkspaceIdentifier(&pWorkspaceDeletePDU->workspaceIdentifier));
  929. if(!pWorkspaceObj)
  930. {
  931. return;
  932. }
  933. pWorkspaceObj->SetOwnerID(memberID);
  934. pWorkspaceObj->ClearDeletionFlags();
  935. //
  936. // Reason for deleting
  937. //
  938. TRACE_DEBUG(("OnWorkspaceDeletePDU reason = %d", pWorkspaceDeletePDU->reason.choice));
  939. //
  940. // Remove it from the List Of Workspaces
  941. //
  942. WBPOSITION prevPos;
  943. WBPOSITION pos;
  944. pos = g_pListOfWorkspaces->GetPosition(pWorkspaceObj);
  945. prevPos = g_pListOfWorkspaces->GetHeadPosition();
  946. //
  947. // This is the only workspace we have ?????
  948. //
  949. if(g_pListOfWorkspaces->GetHeadPosition() == g_pListOfWorkspaces->GetTailPosition())
  950. {
  951. RemoveWorkspace(pWorkspaceObj);
  952. g_pCurrentWorkspace = NULL;
  953. if(g_pMain)
  954. {
  955. g_pMain->EnableToolbar(FALSE);
  956. }
  957. }
  958. else
  959. {
  960. //
  961. // If we had a remote pointer
  962. //
  963. BOOL bRemote = FALSE;
  964. if(g_pMain->m_pLocalRemotePointer)
  965. {
  966. bRemote = TRUE;
  967. g_pMain->OnRemotePointer();
  968. }
  969. //
  970. // Remove the workspace and point the current one to the correct one.
  971. //
  972. pWorkspaceObj = RemoveWorkspace(pWorkspaceObj);
  973. g_pConferenceWorkspace = pWorkspaceObj;
  974. if(g_pDraw->IsSynced())
  975. {
  976. g_pMain->GoPage(pWorkspaceObj,FALSE);
  977. }
  978. //
  979. // If we had a remote pointer
  980. //
  981. if(bRemote)
  982. {
  983. g_pMain->OnRemotePointer();
  984. }
  985. }
  986. }
  987. //
  988. // The remote is changing the workspace
  989. //
  990. void OnWorkspaceEditPDU(WorkspaceEditPDU * pWorkspaceEditPDU, ULONG memberID)
  991. {
  992. TRACE_DEBUG(("OnWorkspaceEditPDU WorkspaceIdentifier = %d",pWorkspaceEditPDU->workspaceIdentifier.u.activeWorkspace));
  993. //
  994. // Find the workspace
  995. //
  996. WorkspaceObj * pWorkspaceObj;
  997. pWorkspaceObj = GetWorkspace(WorkspaceObj::GetWorkspaceIdentifier(&pWorkspaceEditPDU->workspaceIdentifier));
  998. if(!pWorkspaceObj)
  999. {
  1000. return;
  1001. }
  1002. pWorkspaceObj->SetOwnerID(memberID);
  1003. pWorkspaceObj->WorkspaceEditObj(pWorkspaceEditPDU);
  1004. }
  1005. void OnWorkspacePlaneCopyPDU(WorkspacePlaneCopyPDU * pWorkspacePlaneCopyPDU, ULONG memberID)
  1006. {
  1007. TRACE_DEBUG(("OnWorkspacePlaneCopyPDU WorkspaceIdentifier = %d",pWorkspacePlaneCopyPDU->sourceWorkspaceIdentifier));
  1008. }
  1009. void OnWorkspaceReadyPDU(WorkspaceReadyPDU * pWorkspaceReadyPDU, ULONG memberID)
  1010. {
  1011. TRACE_DEBUG(("OnWorkspaceReadyPDU WorkspaceIdentifier = %d",pWorkspaceReadyPDU->workspaceIdentifier));
  1012. //
  1013. // Find the workspace
  1014. //
  1015. WorkspaceObj * pWorkspaceObj;
  1016. pWorkspaceObj = GetWorkspace(WorkspaceObj::GetWorkspaceIdentifier(&pWorkspaceReadyPDU->workspaceIdentifier));
  1017. if(!pWorkspaceObj)
  1018. {
  1019. return;
  1020. }
  1021. pWorkspaceObj->SetOwnerID(memberID);
  1022. //
  1023. // This workspace is ready
  1024. //
  1025. pWorkspaceObj->m_bWorkspaceReady = TRUE;
  1026. }
  1027. //
  1028. // If we got a refreshStatus == TRUE, we have to refresh late joiners
  1029. //
  1030. void OnWorkspaceRefreshStatusPDU(WorkspaceRefreshStatusPDU * pWorkspaceRefreshStatusPDU, ULONG memberID)
  1031. {
  1032. if (pWorkspaceRefreshStatusPDU->refreshStatus == TRUE)
  1033. {
  1034. g_RefresherID = memberID;
  1035. }
  1036. else
  1037. {
  1038. //
  1039. // The token is out there, try to grab it
  1040. //
  1041. g_pNMWBOBJ->GrabRefresherToken();
  1042. }
  1043. }
  1044. /////////////////////////////////////////////////////////////////////////////////////////////
  1045. // BITMAP PDUS
  1046. /////////////////////////////////////////////////////////////////////////////////////////////
  1047. void OnBitmapCreatePDU(BitmapCreatePDU * pBitmapCreatePDU, ULONG memberID, BOOL bForcedResend)
  1048. {
  1049. TRACE_DEBUG(("drawingHandle = %d", pBitmapCreatePDU->bitmapHandle ));
  1050. //
  1051. // If we find this object, it is because T120 is broadcasting the drawing
  1052. // we just sent to T126
  1053. //
  1054. UINT workspace;
  1055. UINT planeID;
  1056. GetBitmapDestinationAddress(&pBitmapCreatePDU->destinationAddress, &workspace, &planeID);
  1057. //
  1058. // Check for resend
  1059. //
  1060. WorkspaceObj* pWObj;
  1061. BitmapObj * pBitmap;
  1062. if(!bForcedResend)
  1063. {
  1064. pWObj = GetWorkspace(workspace);
  1065. if(pWObj)
  1066. {
  1067. pBitmap = (BitmapObj*)pWObj->FindObjectInWorkspace(pBitmapCreatePDU->bitmapHandle);
  1068. if(pBitmap)
  1069. return;
  1070. }
  1071. }
  1072. //
  1073. // New Drawing object
  1074. //
  1075. DBG_SAVE_FILE_LINE
  1076. pBitmap = new BitmapObj(pBitmapCreatePDU);
  1077. pBitmap->SetOwnerID(memberID);
  1078. if(!bForcedResend)
  1079. {
  1080. //
  1081. // Someone else sent us this bitmap, it was not created locally
  1082. //
  1083. pBitmap->ClearCreationFlags();
  1084. //
  1085. // Add a this drawing to the correct workspace
  1086. //
  1087. if(!AddT126ObjectToWorkspace(pBitmap))
  1088. {
  1089. return;
  1090. }
  1091. }
  1092. else
  1093. {
  1094. //
  1095. // If we are reading from disk, this has to be added in the current workspace
  1096. // and we have to wait until we have the whole bitmap to send it
  1097. //
  1098. if(pBitmap->m_fMoreToFollow)
  1099. {
  1100. pBitmap->SetWorkspaceHandle(g_pCurrentWorkspace == NULL ? 0 : g_pCurrentWorkspace->GetWorkspaceHandle());
  1101. AddT126ObjectToWorkspace(pBitmap);
  1102. }
  1103. else
  1104. {
  1105. //
  1106. // Add this object and send Create PDU
  1107. //
  1108. pBitmap->SetAllAttribs();
  1109. pBitmap->AddToWorkspace();
  1110. }
  1111. }
  1112. //
  1113. // PASS IT TO UI
  1114. //
  1115. if(!pBitmap->m_fMoreToFollow)
  1116. {
  1117. pBitmap->Draw();
  1118. }
  1119. }
  1120. void OnBitmapCreateContinuePDU(BitmapCreateContinuePDU * pBitmapCreateContinuePDU, ULONG memberID, BOOL bForcedResend)
  1121. {
  1122. WorkspaceObj* pWorkspace;
  1123. BitmapObj* pBitmap = NULL;
  1124. // We should find this drawing object
  1125. //
  1126. // If we are loading from file it is in the current workspace
  1127. //
  1128. if(bForcedResend)
  1129. {
  1130. ASSERT(g_pCurrentWorkspace);
  1131. if(g_pCurrentWorkspace)
  1132. {
  1133. pBitmap = (BitmapObj*)g_pCurrentWorkspace->FindObjectInWorkspace(pBitmapCreateContinuePDU->bitmapHandle);
  1134. }
  1135. }
  1136. else
  1137. {
  1138. FindObjectAndWorkspace(pBitmapCreateContinuePDU->bitmapHandle, (T126Obj **)&pBitmap, (WorkspaceObj**)&pWorkspace);
  1139. }
  1140. if(pBitmap)
  1141. {
  1142. pBitmap->SetOwnerID(memberID);
  1143. //
  1144. // Found the previous bitmap, concatenate the data
  1145. //
  1146. pBitmap->Continue(pBitmapCreateContinuePDU);
  1147. //
  1148. // PASS IT TO UI
  1149. //
  1150. if(!pBitmap->m_fMoreToFollow)
  1151. {
  1152. pBitmap->Draw();
  1153. if(bForcedResend)
  1154. {
  1155. pBitmap->SetAllAttribs();
  1156. pBitmap->AddToWorkspace();
  1157. }
  1158. }
  1159. }
  1160. }
  1161. void OnBitmapCheckpointPDU(BitmapCheckpointPDU * pBitmapCheckPointPDU, ULONG memberID)
  1162. {
  1163. }
  1164. void OnBitmapAbortPDU(BitmapAbortPDU * pBitmapAbortPDU, ULONG memberID)
  1165. {
  1166. BitmapDeletePDU bitmapDeletePDU;
  1167. bitmapDeletePDU.bitmapHandle = pBitmapAbortPDU->bitmapHandle;
  1168. bitmapDeletePDU.bit_mask = 0;
  1169. //
  1170. // Pass it to bitmapDeletePDU
  1171. //
  1172. OnBitmapDeletePDU(&bitmapDeletePDU, memberID);
  1173. }
  1174. void OnBitmapEditPDU(BitmapEditPDU * pBitmapEditPDU, ULONG memberID)
  1175. {
  1176. BitmapObj* pObj;
  1177. WorkspaceObj* pWorkspace;
  1178. // We should find this drawing object
  1179. if(FindObjectAndWorkspace(pBitmapEditPDU->bitmapHandle, (T126Obj **)&pObj, (WorkspaceObj**)&pWorkspace))
  1180. {
  1181. pObj->SetOwnerID(memberID);
  1182. pObj->BitmapEditObj(pBitmapEditPDU);
  1183. }
  1184. }
  1185. void OnBitmapDeletePDU(BitmapDeletePDU * pBitmapDeletePDU, ULONG memberID)
  1186. {
  1187. BitmapObj* pObj;
  1188. WorkspaceObj* pWorkspace;
  1189. // We should find this drawing object
  1190. if(FindObjectAndWorkspace(pBitmapDeletePDU->bitmapHandle, (T126Obj **)&pObj, (WorkspaceObj**)&pWorkspace))
  1191. {
  1192. pObj->SetOwnerID(memberID);
  1193. pWorkspace->RemoveT126Object((T126Obj*)pObj);
  1194. }
  1195. }