|
|
//
// T126OBJ.CPP
// T126 objects: point, openpolyline, closepolyline, ellipse, bitmaps, workspaces
//
// Copyright Microsoft 1998-
//
#include "precomp.h"
#include "NMWbObj.h"
void T126Obj::AddToWorkspace() {
ULONG gccHandle;
UINT neededHandles = 1; if(GetType() == workspaceCreatePDU_chosen) { neededHandles = 2; } if(g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount >= neededHandles) { gccHandle = g_GCCPreallocHandles[g_iGCCHandleIndex].InitialGCCHandle + g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount - neededHandles; g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount = g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount - neededHandles;
//
// We got a handle no need to ask for another one
//
GotGCCHandle(gccHandle);
TimeToGetGCCHandles(PREALLOC_GCC_HANDLES); return; } else {
TRACE_MSG(("GCC Tank %d has not enough handles, we needed %d and we have %d", g_iGCCHandleIndex, neededHandles, g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount));
//
// Not enough handles
//
g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount = 0; TRACE_MSG(("GCC Tank %d is now empty, switching to other GCC tank", g_iGCCHandleIndex));
//
// Switch gcc handles
//
g_iGCCHandleIndex = g_iGCCHandleIndex ? 0 : 1;
//
// Try again
//
if(g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount >= neededHandles) { gccHandle = g_GCCPreallocHandles[g_iGCCHandleIndex].InitialGCCHandle + g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount - neededHandles; g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount = g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount - neededHandles;
//
// We got a handle no need to ask for another one
//
GotGCCHandle(gccHandle); TimeToGetGCCHandles(PREALLOC_GCC_HANDLES); return; } }
//
// Save this object in our list of DrawingObjects
//
g_pListOfObjectsThatRequestedHandles->AddHead(this);
//
// Ask GCC to give us an unique handle
//
T120Error rc = g_pNMWBOBJ->AllocateHandles(neededHandles);
//
// If we are not in a conference RegistryAllocateHandle will not work,
// so we need to create a fake confirm to remove the object from the list
//
if (T120_NO_ERROR != rc) { //
// Fake a GCCAllocateHandleConfim
//
T126_GCCAllocateHandleConfirm(AllocateFakeGCCHandle(),neededHandles); } }
//
//
// Function: T126Obj::NormalizeRect
//
// Purpose: Normalize a rectangle ensuring that the top left is above
// and to the left of the bottom right.
//
//
void NormalizeRect(LPRECT lprc) { int tmp;
if (lprc->right < lprc->left) { tmp = lprc->left; lprc->left = lprc->right; lprc->right = tmp; }
if (lprc->bottom < lprc->top) { tmp = lprc->top; lprc->top = lprc->bottom; lprc->bottom = tmp; } }
void T126Obj::SetRect(LPCRECT lprc) { m_rect.top = lprc->top; m_rect.bottom = lprc->bottom; m_rect.left = lprc->left; m_rect.right = lprc->right; }
void T126Obj::SetBoundsRect(LPCRECT lprc) { m_boundsRect.top = lprc->top; m_boundsRect.bottom = lprc->bottom; m_boundsRect.left = lprc->left; m_boundsRect.right = lprc->right; }
void T126Obj::SetRectPts(POINT point1, POINT point2) { RECT rc;
rc.left = point1.x; rc.top = point1.y; rc.right = point2.x; rc.bottom = point2.y;
SetRect(&rc); }
void T126Obj::SetBoundRectPts(POINT point1, POINT point2) { RECT rc;
rc.left = point1.x; rc.top = point1.y; rc.right = point2.x; rc.bottom = point2.y;
SetBoundsRect(&rc); }
void T126Obj::GetRect(LPRECT lprc) { lprc->top = m_rect.top; lprc->bottom = m_rect.bottom; lprc->left = m_rect.left; lprc->right = m_rect.right; }
void T126Obj::GetBoundsRect(LPRECT lprc) { if(GraphicTool() == TOOLTYPE_HIGHLIGHT || GraphicTool() == TOOLTYPE_PEN) { lprc->top = m_boundsRect.top; lprc->bottom = m_boundsRect.bottom; lprc->left = m_boundsRect.left; lprc->right = m_boundsRect.right; } else { GetRect(lprc); ::InflateRect(lprc, m_penThickness/2, m_penThickness/2); } NormalizeRect(lprc); }
BOOL T126Obj::PointInBounds(POINT point) { RECT rect; GetBoundsRect(&rect); return ::PtInRect(&rect, point); }
void T126Obj::MoveBy(int cx, int cy) { // Move the bounding rectangle
::OffsetRect(&m_rect, cx, cy); }
void T126Obj::MoveTo(int x, int y) { // Calculate the offset needed to translate the object from its current
// position to the required position.
x -= m_rect.left; y -= m_rect.top;
MoveBy(x, y); }
//
// Select a drawing and add the rectangle sizes to the selector size rectangle
//
void T126Obj::SelectDrawingObject(void) {
if(GraphicTool() == TOOLTYPE_REMOTEPOINTER && GetOwnerID() != GET_NODE_ID_FROM_MEMBER_ID(g_MyMemberID)) { return; }
//
// Mark it as selected locally
//
SelectedLocally();
//
// Calculate the size of the rectangle to be invalidated.
//
CalculateInvalidationRect();
//
// Draw the selection rectangle
//
DrawRect(); }
void T126Obj::UnselectDrawingObject(void) { //
// Erase selection rect
//
DrawRect();
if(GraphicTool() == TOOLTYPE_REMOTEPOINTER && GetOwnerID() != GET_NODE_ID_FROM_MEMBER_ID(g_MyMemberID)) { return; }
ClearSelectionFlags();
//
// Don't even bother sending selection changes if we were deleted
// or if this was a remote that unselected us.
//
if(WasDeletedLocally() || WasSelectedRemotely()) { return; }
ResetAttrib(); SetViewState(unselected_chosen);
//
// We are going to send a new view state, mark it as edited locally
//
EditedLocally();
//
// Sends the change in the view state to the other nodes
//
OnObjectEdit(); ClearEditionFlags(); }
void T126Obj::DrawRect(void) { if(GraphicTool() == TOOLTYPE_REMOTEPOINTER) { return; }
RECT rect; GetBoundsRect(&rect); ::DrawFocusRect(g_pDraw->m_hDCCached,&rect); } void T126Obj::SelectedLocally(void) { m_bSelectedLocally = TRUE; m_bSelectedRemotely = FALSE; SetViewState(selected_chosen);
//
// We are going to send a new view state, mark it as edited locally
//
EditedLocally();
ResetAttrib(); ChangedViewState();
//
// Sends the change in the view state to the other nodes
//
OnObjectEdit(); }
void T126Obj::SelectedRemotely(void) { m_bSelectedLocally = FALSE; m_bSelectedRemotely = TRUE; SetViewState(selected_chosen); }
void T126Obj::MoveBy(LONG x , LONG y) {
//
// Erase the old one
//
if(GraphicTool() == TOOLTYPE_REMOTEPOINTER) { UnDraw(); }
DrawRect();
RECT rect; if(GraphicTool() == TOOLTYPE_PEN || GraphicTool() == TOOLTYPE_HIGHLIGHT) { GetBoundsRect(&rect); } else { GetRect(&rect); } ::OffsetRect(&rect, x, y); if(GraphicTool() == TOOLTYPE_PEN || GraphicTool() == TOOLTYPE_HIGHLIGHT) { SetBoundsRect(&rect); } else { SetRect(&rect); }
POINT anchorPoint; GetAnchorPoint(&anchorPoint); SetAnchorPoint(anchorPoint.x + x ,anchorPoint.y + y); //
// Draw the new one
//
if(GraphicTool() == TOOLTYPE_REMOTEPOINTER) { Draw(); }
DrawRect(); CalculateInvalidationRect();
}
void T126Obj::CalculateInvalidationRect(void) {
RECT rect; UINT penThickness = GetPenThickness();
TRACE_DEBUG(("Invalidation Rect (%d,%d) (%d,%d)", g_pDraw->m_selectorRect.left,g_pDraw->m_selectorRect.top, g_pDraw->m_selectorRect.right, g_pDraw->m_selectorRect.bottom )); GetBoundsRect(&rect); ::UnionRect(&g_pDraw->m_selectorRect,&g_pDraw->m_selectorRect,&rect); TRACE_DEBUG(("Invalidation Rect (%d,%d) (%d,%d)", g_pDraw->m_selectorRect.left,g_pDraw->m_selectorRect.top, g_pDraw->m_selectorRect.right, g_pDraw->m_selectorRect.bottom )); }
//
// Checks object for an actual overlap with pRectHit. This
// function assumes that the boundingRect has already been
// compared with pRectHit.
//
BOOL T126Obj::RectangleHit(BOOL borderHit, LPCRECT pRectHit) { RECT rectEdge; RECT rectHit; RECT rect;
//
// If we are filled do the simple thing
//
if(!borderHit) { POINT point; point.x = (pRectHit->left + pRectHit->right) / 2; point.y = (pRectHit->top + pRectHit->bottom) / 2; if(PointInBounds(point)) { return TRUE; } }
GetRect(&rect);
NormalizeRect(&rect); // check left edge
rectEdge.left = rect.left - GetPenThickness()/2; rectEdge.top = rect.top - GetPenThickness()/2; rectEdge.right = rect.left + GetPenThickness()/2 ; rectEdge.bottom = rect.bottom + GetPenThickness()/2;
if (::IntersectRect(&rectHit, &rectEdge, pRectHit)) return( TRUE );
// check right edge
rectEdge.left = rect.right - GetPenThickness()/2; rectEdge.right = rect.right + GetPenThickness()/2;
if (::IntersectRect(&rectHit, &rectEdge, pRectHit)) return( TRUE );
// check top edge
rectEdge.left = rect.left; rectEdge.right = rect.right; rectEdge.top = rect.top - GetPenThickness()/2; rectEdge.bottom = rect.top + GetPenThickness()/2;
if (::IntersectRect(&rectHit, &rectEdge, pRectHit)) return( TRUE );
// check bottom edge
rectEdge.top = rect.bottom - GetPenThickness()/2; rectEdge.bottom = rect.bottom + GetPenThickness()/2;
if (::IntersectRect(&rectHit, &rectEdge, pRectHit)) return( TRUE );
return( FALSE ); }
void T126Obj::SetAnchorPoint(LONG x, LONG y) { if(m_anchorPoint.x != x || m_anchorPoint.y != y) { ChangedAnchorPoint(); m_anchorPoint.x = x; m_anchorPoint.y = y; } }
void T126Obj::SetZOrder(ZOrder zorder) { m_zOrder = zorder; ChangedZOrder(); }
#define ARRAY_INCREMENT 0x200
DCDWordArray::DCDWordArray() { MLZ_EntryOut(ZONE_FUNCTION, "DCDWordArray::DCDWordArray"); m_Size = 0; m_MaxSize = ARRAY_INCREMENT; DBG_SAVE_FILE_LINE m_pData = new POINT[ARRAY_INCREMENT]; ASSERT(m_pData); }
DCDWordArray::~DCDWordArray() { MLZ_EntryOut(ZONE_FUNCTION, "DCDWordArray::~DCDWordArray");
delete[] m_pData; }
//
// We need to increase the size of the array
//
BOOL DCDWordArray::ReallocateArray(void) { POINT *pOldArray = m_pData; DBG_SAVE_FILE_LINE m_pData = new POINT[m_MaxSize]; ASSERT(m_pData); if(m_pData) { TRACE_DEBUG((">>>>>Increasing size of array to hold %d points", m_MaxSize)); // copy new data from old
memcpy( m_pData, pOldArray, (m_Size) * sizeof(POINT));
TRACE_DEBUG(("Deleting array of points %x", pOldArray)); delete[] pOldArray; return TRUE; } else { m_pData = pOldArray; return FALSE; } }
//
// Add a new point to the array
//
void DCDWordArray::Add(POINT point) {
MLZ_EntryOut(ZONE_FUNCTION, "DCDWordArray::Add"); TRACE_DEBUG(("Adding point(%d,%d) at %d", point.x, point.y, m_Size)); TRACE_DEBUG(("Adding point at %x", &m_pData[m_Size]));
if(m_pData == NULL) { return; } m_pData[m_Size].x = point.x; m_pData[m_Size].y = point.y; m_Size++;
//
// if we want more points, we need to re allocate the array
//
if(m_Size == m_MaxSize) { m_MaxSize +=ARRAY_INCREMENT; if(ReallocateArray() == FALSE) { m_Size--; } } }
//
// Return the number of points in the array
//
UINT DCDWordArray::GetSize(void) { return m_Size; }
//
// Sets the size of the array
//
void DCDWordArray::SetSize(UINT size) { int newSize; //
// if we want more points, we need to re allocate the array
//
if (size > m_MaxSize) { m_MaxSize= ((size/ARRAY_INCREMENT)+1)*ARRAY_INCREMENT; if(ReallocateArray() == FALSE) { return; } } m_Size = size; }
void T126Obj::SetPenThickness(UINT penThickness) { m_penThickness = penThickness; ChangedPenThickness(); }
void T126Obj::GotGCCHandle(ULONG gccHandle) { //
// Save this objects handle
//
SetThisObjectHandle(gccHandle); //
// It was created locally
//
CreatedLocally();
switch(GetType()) { //
// New drawing requested a unique handle
//
case(bitmapCreatePDU_chosen): case(drawingCreatePDU_chosen): {
WorkspaceObj * pWorkspace = GetWorkspace(GetWorkspaceHandle()); if(pWorkspace && !pWorkspace->IsObjectInWorkspace(this)) { //
// Add a this drawing to the correct workspace
//
if(!AddT126ObjectToWorkspace(this)) { return; } }
break; }
//
// New workspace requested a unique handle
//
case(workspaceCreatePDU_chosen): { //
// Save this objects handle
//
SetViewHandle(gccHandle + 1); SetWorkspaceHandle(gccHandle);
if(!IsWorkspaceListed(this)) { AddNewWorkspace((WorkspaceObj*) this); }
break; } }
//
// Send it to T126 apps
//
SendNewObjectToT126Apps();
}
//
// Create the nonstandard pdu header
//
void CreateNonStandardPDU(NonStandardParameter * sipdu, LPSTR NonStandardString) { PT126_VENDORINFO vendorInfo; sipdu->nonStandardIdentifier.choice = h221nonStandard_chosen; vendorInfo = (PT126_VENDORINFO) &sipdu->nonStandardIdentifier.u.h221nonStandard.value; vendorInfo->bCountryCode = USA_H221_COUNTRY_CODE; vendorInfo->bExtension = USA_H221_COUNTRY_EXTENSION; vendorInfo->wManufacturerCode = MICROSOFT_H_221_MFG_CODE; lstrcpy((LPSTR)&vendorInfo->nonstandardString,NonStandardString); sipdu->nonStandardIdentifier.u.h221nonStandard.length = sizeof(T126_VENDORINFO) -sizeof(vendorInfo->nonstandardString) + lstrlen(NonStandardString); sipdu->data.value = NULL; }
void TimeToGetGCCHandles(ULONG numberOfGccHandles) {
TRACE_MSG(("Using GCC Tank %d ", g_iGCCHandleIndex)); TRACE_MSG(("GCC Tank 0 has %d GCC handles ", g_GCCPreallocHandles[0].GccHandleCount)); TRACE_MSG(("GCC Tank 1 has %d GCC handles ", g_GCCPreallocHandles[1].GccHandleCount));
//
// If we have half a tank of GCC handles, it is time to fill up the spare tank
//
if(g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount <= PREALLOC_GCC_HANDLES / 2 && g_GCCPreallocHandles[g_iGCCHandleIndex ? 0 : 1].GccHandleCount == 0 && !g_WaitingForGCCHandles) {
TRACE_MSG(("GCC Tank %d is half full, time to get more GCC handles", g_iGCCHandleIndex));
g_pNMWBOBJ->AllocateHandles(numberOfGccHandles); g_WaitingForGCCHandles = TRUE; }
//
// If we ran out of handles, it is time to switch tanks
//
if(g_GCCPreallocHandles[g_iGCCHandleIndex].GccHandleCount == 0) { TRACE_MSG(("GCC Tank %d is empty, switching to other GCC tank", g_iGCCHandleIndex)); g_iGCCHandleIndex = g_iGCCHandleIndex ? 0 : 1; } }
|