BOOL CSSolid::SplitFace(SSHANDLE h1, SSHANDLE h2)
{
	SSHANDLEINFO hi;
	GetHandleInfo(&hi, h1);

	if(m_nFaces == MAX_FACES-1)
		return FALSE;

	BOOL bRvl = FALSE;

	if(hi.Type == shtEdge)
	{
		// edge-based face split
		bRvl = SplitFaceByEdges((CSSEdge*) hi.pData, 
			(CSSEdge*) GetHandleData(h2));
	}
	else if(hi.Type == shtVertex)
	{
		// vertex-based face split
		bRvl = SplitFaceByVertices((CSSVertex*) hi.pData, 
			(CSSVertex*) GetHandleData(h2));
	}

	return bRvl;
}
SSHANDLE* CSSolid::CreatePointHandleList(CSSFace & face, SSHANDLE* phPoints)
{
	SSHANDLE* pts;
	int nPts = 0;

	if(phPoints)
		pts = phPoints;
	else
		pts = new SSHANDLE[face.nEdges+1];

	for(int i = 0; i < face.nEdges; i++)
	{
		// calc next edge so we can see which is the next clockwise point
		int iNextEdge = i+1;
		if(iNextEdge == face.nEdges)
			iNextEdge = 0;

		CSSEdge * edgeCur = (CSSEdge*) GetHandleData(face.Edges[i]);
		CSSEdge * edgeNext = (CSSEdge*) GetHandleData(face.Edges[iNextEdge]);

		SSHANDLE hVertex = GetConnectionVertex(edgeCur, edgeNext);
		ASSERT(hVertex);

		pts[i] = hVertex;
	}

	return pts;
}
// Create point list, but return indices instead of positions ->
PINT CSSolid::CreatePointIndexList(CSSFace & face, PINT piPoints)
{
	PINT pts;
	int nPts = 0;

	if(piPoints)
		pts = piPoints;
	else
		pts = new int[face.nEdges+1];

	SSHANDLEINFO hi;

	for(int i = 0; i < face.nEdges; i++)
	{
		// calc next edge so we can see which is the next clockwise point
		int iNextEdge = i+1;
		if(iNextEdge == face.nEdges)
			iNextEdge = 0;

		CSSEdge * edgeCur = (CSSEdge*) GetHandleData(face.Edges[i]);
		CSSEdge * edgeNext = (CSSEdge*)  GetHandleData(face.Edges[iNextEdge]);

		SSHANDLE hVertex = GetConnectionVertex(edgeCur, edgeNext);
		ASSERT(hVertex);

		GetHandleInfo(&hi, hVertex);
		pts[i] = hi.iIndex;
	}

	return pts;
}
Beispiel #4
0
/*!
******************************************************************************

 @Function	PVRSRVLookupSubHandle

 @Description	Lookup the data pointer corresponding to a subhandle

 @Input		ppvData - location to return data pointer
		hHandle - handle from client
		eType - handle type
		hAncestor - ancestor handle

 @Output	ppvData - points to the data pointer

 @Return	Error code or PVRSRV_OK

******************************************************************************/
PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase,
				   IMG_PVOID *ppvData,
				   IMG_HANDLE hHandle,
				   PVRSRV_HANDLE_TYPE eType,
				   IMG_HANDLE hAncestor)
{
	HANDLE_DATA *psPHandleData = IMG_NULL;
	HANDLE_DATA *psCHandleData = IMG_NULL;
	PVRSRV_ERROR eError;

	/* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
	PVR_ASSERT(gpsHandleFuncs);

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Missing handle base"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err;
	}

	eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVLookupSubHandle: Error looking up subhandle (%s)",
			 PVRSRVGetErrorStringKM(eError)));
		OSDumpStack();
		goto err;
	}

	/* Look for hAncestor among the handle's ancestors */
	for (psPHandleData = psCHandleData; ParentHandle(psPHandleData) != hAncestor; )
	{
		eError = GetHandleData(psBase, &psPHandleData, ParentHandle(psPHandleData), PVRSRV_HANDLE_TYPE_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
			eError = PVRSRV_ERROR_INVALID_SUBHANDLE;
			goto err;
		}
	}

	*ppvData = psCHandleData->pvData;

	eError = PVRSRV_OK;

	err:
	return eError;
}
Beispiel #5
0
static INLINE
HANDLE_LIST *GetHandleListFromHandleAndOffset(PVRSRV_HANDLE_BASE *psBase, 
					      IMG_HANDLE hEntry, 
					      IMG_HANDLE hParent, 
					      IMG_SIZE_T uiParentOffset, 
					      IMG_SIZE_T uiEntryOffset)
{
	HANDLE_DATA *psHandleData = IMG_NULL;
	PVRSRV_ERROR eError;

	PVR_ASSERT(psBase != IMG_NULL);

	eError = GetHandleData(psBase, 
			       &psHandleData, 
			       hEntry, 
			       PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		return IMG_NULL;
	}

	if (hEntry == hParent)
	{
		return (HANDLE_LIST *)((IMG_CHAR *)psHandleData + uiParentOffset);
	}
	else
	{
		return (HANDLE_LIST *)((IMG_CHAR *)psHandleData + uiEntryOffset);
	}
}
Beispiel #6
0
/*!
******************************************************************************

 @Function	PVRSRVLookupHandleAnyType

 @Description	Lookup the data pointer and type corresponding to a handle

 @Input		ppvData - location to return data pointer
		peType - location to return handle type
		hHandle - handle from client

 @Output	ppvData - points to the data pointer
		peType - points to handle type

 @Return	Error code or PVRSRV_OK

******************************************************************************/
PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase,
				       IMG_PVOID *ppvData,
				       PVRSRV_HANDLE_TYPE *peType,
				       IMG_HANDLE hHandle)
{
	HANDLE_DATA *psHandleData = IMG_NULL;
	PVRSRV_ERROR eError;

	PVR_ASSERT(gpsHandleFuncs);

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Missing handle base"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err;
	}

	eError = GetHandleData(psBase, &psHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVLookupHandleAnyType: Error looking up handle (%s)",
			 PVRSRVGetErrorStringKM(eError)));
		OSDumpStack();
		goto err;
	}

	*ppvData = psHandleData->pvData;
	*peType = psHandleData->eType;

	eError = PVRSRV_OK;

	err:
	return eError;
}
// Create list of points from face ->
Vector * CSSolid::CreatePointList(CSSFace & face, Vector * pPts)
{
	Vector * pts;
	int nPts = 0;

	if(pPts)
		pts = pPts;
	else
		pts = new Vector[face.nEdges+1];

	for(int i = 0; i < face.nEdges; i++)
	{
		// calc next edge so we can see which is the next clockwise point
		int iNextEdge = i+1;
		if(iNextEdge == face.nEdges)
			iNextEdge = 0;

		CSSEdge * edgeCur = (CSSEdge*) GetHandleData(face.Edges[i]);
		CSSEdge * edgeNext = (CSSEdge*) GetHandleData(face.Edges[iNextEdge]);

		if(!edgeCur || !edgeNext)
		{
			CString str;
			str.Format("Conversion error!\n"
				"edgeCur = %08X, edgeNext = %08X", edgeCur, edgeNext);
			AfxMessageBox(str);
			return NULL;
		}

		SSHANDLE hVertex = GetConnectionVertex(edgeCur, edgeNext);

		if(!hVertex)
		{
			CString str;
			str.Format("Conversion error!\n"
				"hVertex = %08X", hVertex);
			AfxMessageBox(str);
			return NULL;
		}

		CSSVertex *pVertex = (CSSVertex*) GetHandleData(hVertex);

		pts[i] = pVertex->pos;
	}

	return pts;
}
Beispiel #8
0
static PVRSRV_ERROR FreeHandleDataWrapper(IMG_HANDLE hHandle, IMG_VOID *pvData)
{
	PVRSRV_HANDLE_BASE *psBase = (PVRSRV_HANDLE_BASE *)pvData;
	HANDLE_DATA *psHandleData = IMG_NULL;
	PVRSRV_ERROR eError;

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "FreeHandleDataWrapper: Handle base missing"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	eError = GetHandleData(psBase, 
			       &psHandleData, 
			       hHandle, 
			       PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "FreeHandleDataWrapper: Couldn't get handle data for handle"));
		return eError;
	}

	if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
	{
		HAND_KEY aKey;
		IMG_HANDLE hRemovedHandle;

		InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, ParentIfPrivate(psHandleData));

		hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psBase->psHashTab, aKey);

		PVR_ASSERT(hRemovedHandle != IMG_NULL);
		PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
		PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
	}

	OSFreeMem(psHandleData);

	return PVRSRV_OK;
}
Beispiel #9
0
/*!
******************************************************************************

 @Function	PVRSRVGetParentHandle

 @Description	Lookup the parent of a handle

 @Input		phParent - location for returning parent handle
		hHandle - handle for which the parent handle is required
		eType - handle type
		hParent - parent handle

 @Output	*phParent - parent handle, or IMG_NULL if there is no parent

 @Return	Error code or PVRSRV_OK.  Note that not having a parent is
		not regarded as an error.

******************************************************************************/
PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase,
				   IMG_HANDLE *phParent,
				   IMG_HANDLE hHandle,
				   PVRSRV_HANDLE_TYPE eType)
{
	HANDLE_DATA *psHandleData = IMG_NULL;
	PVRSRV_ERROR eError;

	/* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
	PVR_ASSERT(gpsHandleFuncs);

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Missing handle base"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err;
	}

	eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVGetParentHandle: Error looking up subhandle (%s)",
			 PVRSRVGetErrorStringKM(eError)));
		OSDumpStack();
		goto err;
	}

	*phParent = ParentHandle(psHandleData);

	eError = PVRSRV_OK;

	err:
	return eError;
}
Beispiel #10
0
/*!
******************************************************************************

 @Function	FreeHandle

 @Description	Free a handle data structure.

 @Input		psBase - Pointer to handle base structure
		hHandle - Handle to be freed
		eType - Type of the handle to be freed
		ppvData - Location for data associated with the freed handle

 @Output 		ppvData - Points to data that was associated with the freed handle

 @Return	PVRSRV_OK or PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase,
			       IMG_HANDLE hHandle,
			       PVRSRV_HANDLE_TYPE eType,
			       IMG_VOID **ppvData)
{
	HANDLE_DATA *psHandleData = IMG_NULL;
	HANDLE_DATA *psReleasedHandleData;
	PVRSRV_ERROR eError;

	eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}

	PVR_ASSERT(psHandleData->ui32Refs>0);

	psHandleData->ui32Refs--;
	if (psHandleData->ui32Refs > 0)
	{
		/* Reference count still positive, only possible for shared handles */
		PVR_ASSERT(TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_SHARED));
		return PVRSRV_OK;
	}
	/* else reference count zero, time to clean up */

	if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
	{
		HAND_KEY aKey;
		IMG_HANDLE hRemovedHandle;

		InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, ParentIfPrivate(psHandleData));

		hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psBase->psHashTab, aKey);

		PVR_ASSERT(hRemovedHandle != IMG_NULL);
		PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
		PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
	}

	eError = UnlinkFromParent(psBase, psHandleData);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "FreeHandle: Error whilst unlinking from parent handle (%s)", 
			 PVRSRVGetErrorStringKM(eError)));
		return eError;
	}

	/* Free children */
	eError = IterateOverChildren(psBase, psHandleData, FreeHandleWrapper);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "FreeHandle: Error whilst freeing subhandles (%s)",
			 PVRSRVGetErrorStringKM(eError)));
		return eError;
	}

	eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, psHandleData->hHandle, (IMG_VOID **)&psReleasedHandleData);
	if (eError == PVRSRV_OK)
	{
		PVR_ASSERT(psReleasedHandleData == psHandleData);
	}

	if (ppvData)
	{
		*ppvData = psHandleData->pvData;
	}

	OSFreeMem(psHandleData);

	return eError;
}
Beispiel #11
0
/*!
******************************************************************************

 @Function	PVRSRVAllocSubHandle

 @Description	Allocate a subhandle

 @Input		phHandle - location for new subhandle
		pvData - pointer to resource to be associated with the subhandle
		eType - the type of resource
		hParent - parent handle

 @Output	phHandle - points to new subhandle

 @Return	Error code or PVRSRV_OK

******************************************************************************/
PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase,
				  IMG_HANDLE *phHandle,
				  IMG_VOID *pvData,
				  PVRSRV_HANDLE_TYPE eType,
				  PVRSRV_HANDLE_ALLOC_FLAG eFlag,
				  IMG_HANDLE hParent)
{
	HANDLE_DATA *psPHandleData = IMG_NULL;
	HANDLE_DATA *psCHandleData = IMG_NULL;
	IMG_HANDLE hParentKey;
	IMG_HANDLE hHandle;
	PVRSRV_ERROR eError;

	*phHandle = IMG_NULL;

	/* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
	PVR_ASSERT(gpsHandleFuncs);

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Missing handle base"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err;
	}

	hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : IMG_NULL;

	/* Lookup the parent handle */
	eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
		goto err;
	}

	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
	{
		/* See if there is already a handle for this data pointer */
		hHandle = FindHandle(psBase, pvData, eType, hParentKey);
		if (hHandle != IMG_NULL)
		{
			eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
				goto err;
			}

			PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(psCHandleData) == hParent);

			/*
			 * If the client is willing to share a handle, the
			 * existing handle is marked as shareable, and the
			 * existing handle has the same parent, return the
			 * existing handle.
			 */
			if (TEST_FLAG(psCHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && 
			    ParentHandle(psCHandleData) == hParent)
			{
				psCHandleData->ui32Refs++;
				*phHandle = hHandle;
				eError = PVRSRV_OK;
				goto err;
			}
			eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
			goto err;
		}
	}

	eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
	if (eError != PVRSRV_OK)
	{
		goto err;
	}

	eError = GetHandleData(psBase, &psCHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));

		/* If we were able to allocate the handle then there should be no reason why we 
		   can't also get it's handle structure. Otherwise something has gone badly wrong. */
		PVR_ASSERT(eError == PVRSRV_OK);

		goto err;
	}

	/*
	 * Get the parent handle structure again, in case the handle
	 * structure has moved (depending on the implementation
	 * of AllocHandle).
	 */
	eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));

		FreeHandle(psBase, hHandle, eType, IMG_NULL);
		goto err;
	}

	eError = AdoptChild(psBase, psPHandleData, psCHandleData);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Parent handle failed to adopt subhandle"));

		FreeHandle(psBase, hHandle, eType, IMG_NULL);
		goto err;
	}

	*phHandle = hHandle;

	eError = PVRSRV_OK;

	err:
	return eError;
}
Beispiel #12
0
/*!
******************************************************************************

 @Function	PVRSRVAllocHandle

 @Description	Allocate a handle

 @Input		phHandle - location for new handle
		pvData - pointer to resource to be associated with the handle
		eType - the type of resource

 @Output	phHandle - points to new handle

 @Return	Error code or PVRSRV_OK

******************************************************************************/
PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
			       IMG_HANDLE *phHandle,
			       IMG_VOID *pvData,
			       PVRSRV_HANDLE_TYPE eType,
			       PVRSRV_HANDLE_ALLOC_FLAG eFlag)
{
	IMG_HANDLE hHandle;
	PVRSRV_ERROR eError;

	*phHandle = IMG_NULL;

	/* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
	PVR_ASSERT(gpsHandleFuncs);

	if (psBase == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Missing handle base"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto exit_AllocHandle;
	}

	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
	{
		/* See if there is already a handle for this data pointer */
		hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
		if (hHandle != IMG_NULL)
		{
			HANDLE_DATA *psHandleData = IMG_NULL;

			eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR,
					 "PVRSRVAllocHandle: Lookup of existing handle failed (%s)",
					 PVRSRVGetErrorStringKM(eError)));
				goto exit_AllocHandle;
			}

			/*
			 * If the client is willing to share a handle, and the
			 * existing handle is marked as shareable, return the
			 * existing handle.
			 */
			if (TEST_FLAG(psHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
			{
				psHandleData->ui32Refs++;
				*phHandle = hHandle;
				eError = PVRSRV_OK;
				goto exit_AllocHandle;
			}
			eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
			goto exit_AllocHandle;
		}
	}

	eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);

	exit_AllocHandle:

	return eError;
}
Beispiel #13
0
/***************************************************************************\
* DdeConnectList (DDEML API)
*
* Description:
* Initiates DDE conversations with multiple servers or adds unique servers
* to an existing conversation list.
*
* History:
* 11-12-91 sanfords Created.
\***************************************************************************/
HCONVLIST DdeConnectList(
    DWORD idInst,
    HSZ hszService,
    HSZ hszTopic,
    HCONVLIST hConvList,
    PCONVCONTEXT pCC)
{
    PCL_INSTANCE_INFO pcii;
    PCONV_INFO pcoi, pcoiNew, pcoiExisting, pcoiNext;
    HCONVLIST hConvListRet = 0;
    HWND hwndTarget = 0;
    LATOM aNormalSvcName = 0;
    PCONVLIST pcl = NULL;
    HCONVLIST hConvListOld;
    int i;

    CheckDDECritOut;

    EnterDDECrit;

    if (!ValidateConnectParameters((HANDLE)idInst, &pcii, &hszService, hszTopic,
            &aNormalSvcName, &pCC, &hwndTarget, hConvList)) {
        goto Exit;
    }

    ValidateConvList(hConvList);

    hConvListOld = hConvList;
    pcoi = (PCONV_INFO)ConnectConv(pcii,
            LATOM_FROM_HSZ(hszService),
            LATOM_FROM_HSZ(hszTopic),
            hwndTarget,
            (pcii->afCmd & (CBF_FAIL_SELFCONNECTIONS | CBF_FAIL_CONNECTIONS)) ?
                pcii->hwndMother : 0,
            pCC,
            hConvListOld,
            CLST_MULT_INITIALIZING);

    if (pcoi == NULL) {
        /*
         * no new connections made
         */
        SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED);
        hConvListRet = hConvListOld;
        goto Exit;
    }

    /*
     * allocate or reallocate the hConvList hwnd list for later addition
     * If we already have a valid list, reuse the handle so we don't have
     * to alter the preexisting pcoi->hConvList values.
     */
    if (hConvListOld == 0) {
        pcl = (PCONVLIST)DDEMLAlloc(sizeof(CONVLIST));
        if (pcl == NULL) {
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            DisconnectConv(pcoi);
            goto Exit;
        }
        // pcl->chwnd = 0; LPTR zero inits.

        hConvList = (HCONVLIST)CreateHandle((DWORD)pcl,
                HTYPE_CONVERSATION_LIST, InstFromHandle(pcii->hInstClient));
        if (hConvList == 0) {
            DDEMLFree(pcl);
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            DisconnectConv(pcoi);
            goto Exit;
        }
    } else {
        pcl = (PCONVLIST)GetHandleData((HANDLE)hConvList);
        pcl = DDEMLReAlloc(pcl, sizeof(CONVLIST) + sizeof(HWND) * pcl->chwnd);
        if (pcl == NULL) {
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            hConvListRet = hConvListOld;
            DisconnectConv(pcoi);
            goto Exit;
        }
        SetHandleData((HANDLE)hConvList, (DWORD)pcl);
    }

    ValidateConvList(hConvListOld);

    if (hConvListOld) {
        /*
         * remove duplicates from new conversations
         *
         * Although we tried to prevent duplicates from happening
         * within the initiate enumeration code, wild initiates or
         * servers responding with different service names than
         * requested could cause duplicates.
         */

        /* For each client window... */

        for (i = 0; i < pcl->chwnd; i++) {

        /* For each existing conversation in that window... */

            for (pcoiExisting = (PCONV_INFO)
                        GetWindowLong(pcl->ahwnd[i], GWL_PCI);
                    pcoi != NULL && pcoiExisting != NULL;
                    pcoiExisting = pcoiExisting->next) {

                if (!(pcoiExisting->state & ST_CONNECTED))
                    continue;

        /* For each new conversation... */

                for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNext) {

                    pcoiNext = pcoiNew->next;

        /* see if the new conversation duplicates the existing one */

                    if (!(pcoiNew->state & ST_CONNECTED))
                        continue;

                    UserAssert(((PCL_CONV_INFO)pcoiExisting)->hwndReconnect);
                    UserAssert(((PCL_CONV_INFO)pcoiNew)->hwndReconnect);

                    if (((PCL_CONV_INFO)pcoiExisting)->hwndReconnect ==
                                ((PCL_CONV_INFO)pcoiNew)->hwndReconnect &&
                            pcoiExisting->laTopic == pcoiNew->laTopic &&
                            pcoiExisting->laService == pcoiNew->laService) {
                        /*
                         * duplicate conversation - disconnection causes an unlink
                         */
                        if (pcoiNew == pcoi) {
                            /*
                             * We are freeing up the head of the list,
                             * Reset the head to the next guy.
                             */
                            pcoi = pcoiNext;
                        }
                        ValidateConvList(hConvList);
                        ShutdownConversation(pcoiNew, FALSE);
                        ValidateConvList(hConvList);
                        break;
                    }
                }
            }
        }

        for (pcoiExisting = pcoi; pcoiExisting != NULL; pcoiExisting = pcoiExisting->next) {
            /*
             * if these are all zombies - we DONT want to link it in!
             * This is possible because ShutdownConversation() leaves the critical section
             * and could allow responding terminates to come through.
             */
            if (pcoiExisting->state & ST_CONNECTED) {
                goto FoundOne;
            }
        }
        pcoi = NULL;    // abandon this guy - he will clean up in time.
FoundOne:
        /*
         * add new pcoi (if any are left) hwnd to ConvList hwnd list.
         */
        if (pcoi != NULL) {
            UserAssert(pcoi->hwndConv);
            pcl->ahwnd[pcl->chwnd] = pcoi->hwndConv;
            pcl->chwnd++;
            hConvListRet = hConvList;
        } else {
            hConvListRet = hConvListOld;
            if (!hConvListOld) {
                DestroyHandle((HANDLE)hConvList);
            }
        }


    } else {    // no hConvListOld

        UserAssert(pcoi->hwndConv);
        pcl->ahwnd[0] = pcoi->hwndConv;
        pcl->chwnd = 1;
        hConvListRet = hConvList;
    }

    if (pcoi != NULL) {
        /*
         * set hConvList field for all remaining new conversations.
         */
        UserAssert(hConvListRet);
        for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNew->next) {
            if (pcoiNew->state & ST_CONNECTED) {
                ((PCL_CONV_INFO)pcoiNew)->hConvList = hConvListRet;
            }
        }
    }

Exit:
    if (aNormalSvcName) {
        DeleteAtom(aNormalSvcName);
    }
    ValidateConvList(hConvListRet);
    LeaveDDECrit;
    return (hConvListRet);
}
Beispiel #14
0
/***************************************************************************\
* UnlinkConvFromOthers
*
* Description:
*
* Helper function to handle ugly cross dependency removal.  If we are
* unlinking a conversation that is going zombie, fGoingZombie is TRUE;
*
* Conversations that are going zombie are in phase 1 of a 2 phase unlink.
* Phase 1 unlinks do not remove the pcoi from its hwnd's list.
* All unlinks should result in:
*   pcoi->hConvList = 0;
*   hConvList/aServerLookup no longer refrences pcoi->hwndConv unless
*       one of the pcoi's related to hwndConv is still active.
*
*
* History:
*  3-2-92 sanfords Created.
\***************************************************************************/
VOID UnlinkConvFromOthers(
PCONV_INFO pcoi,
BOOL gGoingZombie)
{
    PCONV_INFO pcoiPrev, pcoiFirst, pcoiNow;
    PCONVLIST pcl;
    int i, cActiveInList = 0;
#ifdef TESTING
    DWORD path = 0;
#define ORPATH(x) path |= x;
#else
#define ORPATH(x)
#endif // TESTING

    CheckDDECritIn;

    /*
     * Scan pcoi linked list to get key pointers.
     */
    pcoiPrev = NULL;
    pcoiFirst = pcoiNow = (PCONV_INFO)GetWindowLong(pcoi->hwndConv, GWL_PCI);

#ifdef TESTING
    /*
     * verify that pcoi is in the conv list for this window.
     */
    while (pcoiNow != NULL) {
        if (pcoiNow == pcoi) {
            goto FoundIt;
        }
        pcoiNow = pcoiNow->next;
    }
    DebugBreak();
FoundIt:
    pcoiNow = pcoiFirst;
#endif // TESTING

    UserAssert(pcoiFirst);
    while (pcoiNow != NULL) {
        if (TypeFromHandle(pcoiNow->hConv) != HTYPE_ZOMBIE_CONVERSATION) {
            ORPATH(1);
            cActiveInList++;
        }
        if (pcoiNow->next == pcoi) {
            pcoiPrev = pcoiNow;
        }
        pcoiNow = pcoiNow->next;
    }

    ValidateAllConvLists();

    /*
     * Unlink conversation unless its going Zombie.
     */
    if (!gGoingZombie) {
        ORPATH(2);
        if (TypeFromHandle(pcoi->hConv) != HTYPE_ZOMBIE_CONVERSATION) {
            ORPATH(4);
            cActiveInList--;
        }

        if (pcoiPrev == NULL) {
            ORPATH(8);
            pcoiFirst = pcoi->next;
            SetWindowLong(pcoi->hwndConv, GWL_PCI, (LONG)pcoiFirst);
        } else {
            pcoiPrev->next = pcoi->next;
        }
    }

    UserAssert(pcoiFirst != NULL || !cActiveInList);

    if (cActiveInList == 0) {
        ORPATH(0x10);
        if (pcoi->state & ST_CLIENT) {
            ORPATH(0x20);
            if (((PCL_CONV_INFO)pcoi)->hConvList) {
                /*
                 * Remove pcoi's hwnd from its hConvList.
                 */
                pcl = (PCONVLIST)GetHandleData((HANDLE)((PCL_CONV_INFO)pcoi)->hConvList);
                for (i = 0; i < pcl->chwnd; i++) {
                    if (pcl->ahwnd[i] == pcoi->hwndConv) {
                        ORPATH(0x40);
                        pcl->chwnd--;
                        UserAssert(pcl->ahwnd[pcl->chwnd]);
                        pcl->ahwnd[i] = pcl->ahwnd[pcl->chwnd];
                        ValidateConvList(((PCL_CONV_INFO)pcoi)->hConvList);
                        break;
                    }
                }
                ORPATH(0x80);
            }
        } else {  // SERVER
            /*
             * remove server window from the service/topic lookup table.
             */
            ORPATH(0x100);
            for (i = 0; i < pcoi->pcii->cServerLookupAlloc; i++) {
                if (pcoi->pcii->aServerLookup[i].hwndServer == pcoi->hwndConv) {
                    ORPATH(0x200);
                    if (--(pcoi->pcii->cServerLookupAlloc)) {
                        ORPATH(0x400);
                        pcoi->pcii->aServerLookup[i] =
                                pcoi->pcii->aServerLookup[pcoi->pcii->cServerLookupAlloc];
                    } else {
                        DDEMLFree(pcoi->pcii->aServerLookup);
                        pcoi->pcii->aServerLookup = NULL;
                    }
                    break;
                }
            }
        }
    }
#ifdef TESTING
      else {
        /*
         * make sure at this point we have at least one non-zombie
         */
        pcoiNow = pcoiFirst;
        while (pcoiNow != NULL) {
            if (TypeFromHandle(pcoiNow->hConv) != HTYPE_ZOMBIE_CONVERSATION) {
                goto Out;
            }
            pcoiNow = pcoiNow->next;
        }
        DebugBreak();
Out:
        ;
    }
#endif // TESTING

    ValidateAllConvLists();
    ORPATH(0x800);

    /*
     * In any case remove hConvList references from client conversation.
     */
    if (pcoi->state & ST_CLIENT) {
#ifdef TESTING
        /*
         * Verify that the hConvList that is being removed, doesn't reference
         * this window.
         */
        if (((PCL_CONV_INFO)pcoi)->hConvList && !cActiveInList) {
            BOOL fFound = FALSE;

            pcl = (PCONVLIST)GetHandleData((HANDLE)((PCL_CONV_INFO)pcoi)->hConvList);
            for (i = 0; i < pcl->chwnd; i++) {
                if (pcl->ahwnd[i] == pcoi->hwndConv) {
                    fFound = TRUE;
                    break;
                }
            }
            UserAssert(!fFound);
        }
#endif // TESTING
        ((PCL_CONV_INFO)pcoi)->hConvList = 0;
        pcoi->state &= ~ST_INLIST;
    }

    /*
     * last one out turns out the lights.
     */
    if (pcoiFirst == NULL) {
        /*
         * If the pcoi list is empty, this window can go away.
         */
        LeaveDDECrit;
        NtUserDestroyWindow(pcoi->hwndConv);
        EnterDDECrit;
    }
}
Beispiel #15
0
BOOL CSSolid::SplitFaceByVertices(CSSVertex *pVertex1, CSSVertex *pVertex2)
{
	if(GetEdgeIndex(pVertex1->id, pVertex2->id) != -1)
		return FALSE;	// already an edge there!

	// find the face, first - get a list of affected edges and find
	//  two with a common face
	int iNumEdges1, iNumEdges2;
	SSHANDLE hFace = 0;
	CSSEdge *pEdges1[64], *pEdges2[64], **pTmp;

	pTmp = FindAffectedEdges(&pVertex1->id, 1, iNumEdges1);
	memcpy(pEdges1, pTmp, iNumEdges1 * sizeof(CSSEdge*));
	pTmp = FindAffectedEdges(&pVertex2->id, 1, iNumEdges2);
	memcpy(pEdges2, pTmp, iNumEdges2 * sizeof(CSSEdge*));

	for(int i = 0; i < iNumEdges1; i++)
	{
		SSHANDLE hFace0 = pEdges1[i]->Faces[0];
		SSHANDLE hFace1 = pEdges1[i]->Faces[1];
		for(int i2 = 0; i2 < iNumEdges2; i2++)
		{
			if(hFace0 == pEdges2[i2]->Faces[0] ||
				hFace0 == pEdges2[i2]->Faces[1])
			{
				hFace = hFace0;
				break;
			}
			else if(hFace1 == pEdges2[i2]->Faces[0] ||
				hFace1 == pEdges2[i2]->Faces[1])
			{
				hFace = hFace1;
				break;
			}
		}
	}

	// couldn't find a common face
	if(hFace == 0)
		return FALSE;

	CSSFace *pFace = (CSSFace*) GetHandleData(hFace);

	// create a new face
	CSSFace *pNewFace = AddFace();
	memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE));

	// create a new edge between two vertices
	CSSEdge *pNewEdge = AddEdge();
	pNewEdge->hvStart = pVertex1->id;
	pNewEdge->hvEnd = pVertex2->id;
	CalcEdgeCenter(pNewEdge);

	// assign face ids to the new edge
	AssignFace(pNewEdge, pFace->id);
	AssignFace(pNewEdge, pNewFace->id);

	// set up edges - start with newvertex1 
	SSHANDLE hNewEdges[64];
	int nNewEdges;
	BOOL bFirst = TRUE;
	CSSFace *pStoreFace = pFace;

	SSHANDLE *phVertexList = CreatePointHandleList(*pFace);
	int nVertices = pFace->nEdges;

	int v1index, v2index;

	// find where the vertices are and
	//  kill face references in edges first
	for(i = 0; i < nVertices; i++)
	{
		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], 
			phVertexList[iNextVertex]);
		CSSEdge *pEdge = &m_Edges[iEdgeIndex];
		AssignFace(pEdge, pFace->id, TRUE);

		if(phVertexList[i] == pVertex1->id)
			v1index = i;
		else if(phVertexList[i] == pVertex2->id)
			v2index = i;
	}

DoNextFace:
	nNewEdges = 0;
	for(i = v1index; ; i++)
	{
		if(i == nVertices)
			i = 0;

		if(i == v2index)
			break;

		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
		ASSERT(iEdgeIndex != -1);

		hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;

		AssignFace(&m_Edges[iEdgeIndex], pFace->id);
	}
	// now add the middle edge
	hNewEdges[nNewEdges++] = pNewEdge->id;
	// now set up in face
	pStoreFace->nEdges = nNewEdges;
	memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

	if(bFirst)
	{
		int tmp = v1index;
		v1index = v2index;
		v2index = tmp;
		pStoreFace = pNewFace;
		bFirst = FALSE;
		goto DoNextFace;
	}

	delete phVertexList;

	return(TRUE);
}
Beispiel #16
0
BOOL CSSolid::SplitFaceByEdges(CSSEdge *pEdge1, CSSEdge *pEdge2)
{
	SSHANDLE hFace;

	// find the handle of the face
	if(pEdge1->Faces[0] == pEdge2->Faces[0] || 
		pEdge1->Faces[0] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[0];
	}
	else if(pEdge1->Faces[1] == pEdge2->Faces[0] || 
		pEdge1->Faces[1] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[1];
	}
	else return FALSE;	// not the same face

	// get pointer to face
	CSSFace *pFace = (CSSFace*) GetHandleData(hFace);

	// create new objects
	CSSFace *pNewFace = AddFace();
	CSSEdge *pNewEdgeMid = AddEdge();
	int iNewVertex1, iNewVertex2;
	CSSVertex *pNewVertex1 = AddVertex(&iNewVertex1);
	CSSVertex *pNewVertex2 = AddVertex(&iNewVertex2);

	// assign faces to new edge
	AssignFace(pNewEdgeMid, pFace->id);
	AssignFace(pNewEdgeMid, pNewFace->id);

	// copy texture info from one face to the other
	memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE));

	// set vertex positions
	m_Vertices[iNewVertex1].pos = pEdge1->ptCenter;
	m_Vertices[iNewVertex2].pos = pEdge2->ptCenter;

	// set up middle edge
	pNewEdgeMid->hvStart = pNewVertex1->id;
	pNewEdgeMid->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pNewEdgeMid);

	// set up new side edges
	CSSEdge *pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvStart;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvStart;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

/*
	FILE *fp = fopen("split", "w");
	for(i = 0; i < nVertices; i++)
	{
		fprintf(fp, "%lu\n", phVertexList[i]);
	}
	fclose(fp);
*/

	// set up edges - start with newvertex1 
	SSHANDLE hNewEdges[64];
	int nNewEdges;
	BOOL bFirst = TRUE;
	CSSFace *pStoreFace = pFace;

	// ** do two new faces first **

	int nv1index, nv2index;
	SSHANDLE *phVertexList = CreateNewVertexList(pFace, pEdge1, pEdge2, 
		nv1index, nv2index, pNewVertex1, pNewVertex2);
	int nVertices = pFace->nEdges;
	if(nv1index != -1)
		++nVertices;
	if(nv2index != -1)
		++nVertices;

	// kill face references in edges first
	for(int i = 0; i < nVertices; i++)
	{
		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], 
			phVertexList[iNextVertex]);
		CSSEdge *pEdge = &m_Edges[iEdgeIndex];
		ASSERT(pEdge->id != pEdge1->id);
		ASSERT(pEdge->id != pEdge2->id);
		AssignFace(pEdge, pFace->id, TRUE);
	}

DoNextFace:
	nNewEdges = 0;
	for(i = nv1index; ; i++)
	{
		if(i == nVertices)
			i = 0;

		if(i == nv2index)
			break;

		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
		ASSERT(iEdgeIndex != -1);

		hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;

		AssignFace(&m_Edges[iEdgeIndex], pStoreFace->id);
	}
	// now add the middle edge
	hNewEdges[nNewEdges++] = pNewEdgeMid->id;
	// now set up in face
	pStoreFace->nEdges = nNewEdges;
	memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

	if(bFirst)
	{
		int tmp = nv1index;
		nv1index = nv2index;
		nv2index = tmp;
		pStoreFace = pNewFace;
		bFirst = FALSE;
		goto DoNextFace;
	}

	delete phVertexList;

	// ** now regular faces **
	for(int iFace = 0; iFace < m_nFaces; iFace++)
	{
		CSSFace *pUpdFace = &m_Faces[iFace];

		if(pUpdFace == pNewFace || pUpdFace == pFace)
			continue;
		
		SSHANDLE *phVertexList = CreateNewVertexList(pUpdFace, pEdge1, pEdge2,
			nv1index, nv2index, pNewVertex1, pNewVertex2);

		if(phVertexList == NULL)	// don't need to update this face
			continue;
	
		nNewEdges = 0;
		nVertices = pUpdFace->nEdges;
		if(nv1index != -1)
			++nVertices;
		if(nv2index != -1)
			++nVertices;
		for(i = 0; i < nVertices; i++)
		{
			int iNextVertex = GetNext(i, 1, nVertices);
			int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
			ASSERT(iEdgeIndex != -1);

			AssignFace(&m_Edges[iEdgeIndex], pUpdFace->id);
			hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;
		}

		// now set up in face
		pUpdFace->nEdges = nNewEdges;
		memcpy(pUpdFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

		delete phVertexList;
	}

	SSHANDLE id1 = pEdge1->id;
	SSHANDLE id2 = pEdge2->id;

	// delete old edges
	for(i = 0; i < m_nEdges; i++)
	{
		if(m_Edges[i].id == id1 || m_Edges[i].id == id2)
		{
			DeleteEdge(i);
			--i;
		}
	}

	return TRUE;
}