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; }
/*! ****************************************************************************** @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; }
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); } }
/*! ****************************************************************************** @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; }
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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/*! ****************************************************************************** @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; }
/***************************************************************************\ * 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); }
/***************************************************************************\ * 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; } }
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); }
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; }