void DestroyPtrList(LPLIST lpList) /***********************************************************************/ { LPTR lpNode; lpNode = (LPTR)ListGetHead(lpList); while (lpNode) { ListUnlink(lpList, lpNode); FreeUp(lpNode); lpNode = (LPTR)ListGetHead(lpList); } }
void ListUnThreadNode(ListNode *Node) { ListNode *Head, *Prev, *Next; ListDecrNoOfItems(Node); Prev=Node->Prev; Next=Node->Next; if (Prev !=NULL) Prev->Next=Next; if (Next !=NULL) Next->Prev=Prev; Head=ListGetHead(Node); if (Head) { //prev node of head points to LAST item in list if (Head->Prev==Node) { Head->Prev=Node->Prev; if (Head->Prev==Head) Head->Prev=NULL; } if (Head->Side==Node) Head->Side=NULL; if (Head->Next==Node) Head->Next=Next; if (Head->Prev==Node) Head->Prev=Prev; } //make our unthreaded node a singleton Node->Head=NULL; Node->Prev=NULL; Node->Next=NULL; Node->Side=NULL; }
//Item1 is before Item2! void ListSwapItems(ListNode *Item1, ListNode *Item2) { ListNode *Head, *Prev, *Next; if (! Item1) return; if (! Item2) return; //Never swap with a list head! Head=ListGetHead(Item1); if (Head==Item1) return; if (Head==Item2) return; Prev=Item1->Prev; Next=Item2->Next; if (Head->Next==Item1) Head->Next=Item2; if (Head->Prev==Item1) Head->Prev=Item2; if (Prev) Prev->Next=Item2; Item1->Prev=Item2; Item1->Next=Next; if (Next) Next->Prev=Item1; Item2->Prev=Prev; Item2->Next=Item1; }
void *ListDeleteNode(ListNode *Node) { ListNode *Head, *Prev, *Next; void *Contents; if (Node==NULL) { return(NULL); } Head=ListGetHead(Node); Prev=Node->Prev; Next=Node->Next; if (Prev !=NULL) Prev->Next=Next; if (Next !=NULL) Next->Prev=Prev; if (Head->Next==Node) Head->Next=Next; if (Head->Prev==Node) Head->Prev=Prev; Contents=Node->Item; ListDecrNoOfItems(Node); DestroyString(Node->Tag); free(Node); return(Contents); }
BOOL ConvertLowResLoad(LPLIST lpPktList) /***********************************************************************/ { LPCMDPKT lpCmdPkt; lpCmdPkt = (LPCMDPKT)ListGetHead(lpPktList); while (lpCmdPkt) { if (lpCmdPkt->idCommand == IDS_CMD_LOWRESLOAD) { LPLOADFILE_PARMS lpLoadFileParms; LPLOWRESLOAD_PARMS lpLowResParms; lpLoadFileParms = (LPLOADFILE_PARMS)Alloc(sizeof(LOADFILE_PARMS)); if (!lpLoadFileParms) { Message(IDS_EMEMALLOC); return(FALSE); } lpLowResParms = (LPLOWRESLOAD_PARMS)lpCmdPkt->lpParms; lstrcpy(lpLoadFileParms->szFileName, lpLowResParms->szFileName); lpLoadFileParms->idFileType = lpLowResParms->idFileType; lpLoadFileParms->cmsInfo = lpLowResParms->cmsInfo; FreeUpParms(lpCmdPkt->idCommand, lpCmdPkt->lpParms); lpCmdPkt->idCommand = IDS_CMD_LOADFILE; lpCmdPkt->lpParms = lpLoadFileParms; } lpCmdPkt = (LPCMDPKT)ListGetNext(lpCmdPkt); } return(TRUE); }
void ListSetFlags(ListNode *List, int Flags) { ListNode *Head; Head=ListGetHead(List); Head->Flags=Flags; }
unsigned long ListSize(ListNode *Node) { ListNode *Head; Head=ListGetHead(Node); if (Head && Head->Stats) return(Head->Stats->Hits); return(0); }
void ListSetNoOfItems(ListNode *LastItem, unsigned long val) { ListNode *Head; Head=ListGetHead(LastItem); if (LastItem->Next==NULL) Head->Prev=LastItem; /* The head Item has its Prev as being the last item! */ if (Head->Stats) Head->Stats->Hits=val; }
void ListSetFlags(ListNode *List, int Flags) { ListNode *Head; Head=ListGetHead(List); //only the first 16bit of flags is stored. Some flags > 16 bit effect config, but //don't need to be stored long term Head->Flags=Flags & 0xFFFF; }
ListNode *ListGetLast(ListNode *CurrItem) { ListNode *Head; Head=ListGetHead(CurrItem); if (! Head) return(CurrItem); /* the dummy header has a 'Prev' entry that points to the last item! */ if (Head->Prev) return(Head->Prev); return(Head); }
int ListDecrNoOfItems(ListNode *LastItem) { ListNode *Head; int *intptr; Head=ListGetHead(LastItem); if (LastItem->Next==NULL) Head->Prev=LastItem->Prev; /* The head Item has its Prev as being the last item! */ intptr=(int *) Head->Item; (*intptr)--; return(*intptr); }
int ListSize(ListNode *List) { ListNode *Head; int *intptr; if (! List) return(0); Head=ListGetHead(List); intptr=(int *) Head->Item; return(*intptr); }
LOCAL BOOL FindCommand(LPLIST lpPktList, ITEMID idCommand) /***********************************************************************/ { LPCMDPKT lpCmdPkt; lpCmdPkt = (LPCMDPKT)ListGetHead(lpPktList); while (lpCmdPkt) { if (lpCmdPkt->idCommand == idCommand) return(TRUE); lpCmdPkt = (LPCMDPKT)ListGetNext(lpCmdPkt); } return(FALSE); }
LOCAL int CountType(LPLIST lpPktList, COMMAND_TYPE Type) /***********************************************************************/ { LPCMDPKT lpCmdPkt; int nType = 0; lpCmdPkt = (LPCMDPKT)ListGetHead(lpPktList); while (lpCmdPkt) { if (GetCommandType(lpCmdPkt->idCommand) == Type) ++nType; lpCmdPkt = (LPCMDPKT)ListGetNext(lpCmdPkt); } return(nType); }
LOCAL BOOL NeedSequence(LPCMDLIST lpCmdList) /***********************************************************************/ { LPCMDPKT lpCmdPkt; int i; lpCmdPkt = (LPCMDPKT)ListGetHead(&lpCmdList->PacketList); while (lpCmdPkt) { if ((i = GetCommandIndex(lpCmdPkt->idCommand)) >= 0) { if (GetCommandSequence(lpCmdPkt->idCommand)) return(TRUE); } lpCmdPkt = (LPCMDPKT)ListGetNext(lpCmdPkt); } return(FALSE); }
ListNode *ListAddNamedItemAfter(ListNode *ListStart,const char *Name,void *Item) { ListNode *Curr; if (ListStart==NULL) return(NULL); Curr=ListStart; Curr->Next=(ListNode *) calloc(1,sizeof(ListNode)); Curr->Next->Prev=Curr; Curr=Curr->Next; Curr->Item=Item; Curr->Head=ListGetHead(ListStart); Curr->Next=NULL; if (Name) Curr->Tag=CopyStr(NULL,Name); ListIncrNoOfItems(Curr); return(Curr); }
//list get next is just a macro that either calls this for maps, or returns Node->next ListNode *MapGetNext(ListNode *CurrItem) { ListNode *SubNode, *Head; if (! CurrItem) return(NULL); if (CurrItem->Next) { if (CurrItem->Next->Next) { //it's unlikely that we will be looking up the same item again, because maps maintain seperate chains of items //and the likelyhood of hitting the same chain twice is low. THIS IS NOT TRUE FOR REPEATED LOOKUPS ON A LIST //because with a list we go through the same items over and over again whenever looking for items in the chain //Thus for maps we call this prefetch code, which prefetches into the L1 cache, but not into the larger, long-term //L2 cache. As we're unlikely to be revisiting this chain in the near future, we don't want to pollute the L2 //cache with it //This is a disaster for straight forward lists though, because they have only one chain that gets revisited on //every search for an item __builtin_prefetch (CurrItem->Next->Next, 0, 0); if (CurrItem->Next->Next->Tag) __builtin_prefetch (CurrItem->Next->Next->Tag, 0, 0); } return(CurrItem->Next); } if (CurrItem->Flags & LIST_FLAG_MAP_HEAD) { CurrItem=(ListNode *) CurrItem->Item; if (CurrItem->Next) return(CurrItem->Next); } //'Head' here points to a BUCKET HEADER. These are marked with this flag, except the last one //so we know when we've reached the end Head=ListGetHead(CurrItem); while (Head->Flags & LIST_FLAG_MAP_CHAIN) { Head++; if (Head->Next) return(Head->Next); } return(NULL); }
size_t RFC822HeadersWrite(FILE *out,const List *list) { struct pair *ppair; size_t size; assert(out != NULL); assert(list != NULL); for ( size = 0 , ppair = (struct pair *)ListGetHead((List *)list); NodeValid(&ppair->node); ppair = (struct pair *)NodeNext(&ppair->node) ) { size += RFC822HeaderWrite(out,ppair->name,ppair->value); } return(size); }
void ListThreadNode(ListNode *Prev, ListNode *Node) { ListNode *Head, *Next; //Never thread something to itself! if (Prev==Node) return; Next=Prev->Next; Node->Prev=Prev; Prev->Next=Node; Node->Next=Next; Head=ListGetHead(Prev); Node->Head=Head; // Next might be NULL! If it is, then our new node is last // item in list, so update Head node accordingly if (Next) Next->Prev=Node; else Head->Prev=Node; ListIncrNoOfItems(Prev); }
BOOL PlayMacro(LPCMDLIST lpCmdList, LPTSTR lpFileName, int nRepeat, BOOL fSequenceAll, LPLIST lpMacroList, HWND hParent, int PhotoCDResOverride, LPTSTR lpMacroName) /***********************************************************************/ { LPIMAGE lpImage; LPCMDLIST lpNewList; int nActivates, iCount; ITEMID idCommand; STRING szString, szAppName; BOOL fError; BOOL fSequence, fCmdSequence, fCopyPackets; LIST MacroList; LPCMDPKT lpCmdPkt, lpNextPkt; MACROSETUP Setup; COMMAND_TYPE CommandType; HWND hDlg = NULL; lpAbortProc = NULL; if (!hParent) hParent = PictPubApp.Get_hWndAstral(); // see if we need to copy our packets fCopyPackets = nRepeat > 1; if (!lpMacroList) { // read in the entire macro file for faster processing if (!ReadMacro(lpFileName, &MacroList)) return(FALSE); lpMacroList = &MacroList; } // count the number of activates in the macro file // because it affects sequencing nActivates = CountType(lpMacroList, CT_ACTIVATE); // turn of macro play mode and tell the world MacroMode = MM_PLAY; if ( AstralStrEx( IDS_APPNAME, szAppName, sizeof(szAppName) ) ) { if ( AstralStrEx( IDS_MACROPLAY, szString, sizeof(szString) ) ) { lstrcat( szAppName, szString ); SetWindowText( PictPubApp.Get_hWndAstral(), szAppName ); } } // reset untitled number so that if a macro is played it // can deal with untitled images the same Control.UntitledNo = 0; // If no command list passed in to work on (Macro Batch Mode) // then get command list for active image if (!lpCmdList) { if (lpImage = GetActiveImage()) lpCmdList = lpImage->lpCmdList; else lpCmdList = NULL; } // See if the macro contains any low res loads and // if so ask to user if he'd like to convert them // to hi res loads and if so do the convert if (FindCommand(lpMacroList, IDS_CMD_LOWRESLOAD)) if (AstralAffirm(IDS_CONVERTLOWRES)) if (!ConvertLowResLoad(lpMacroList)) { DestroyPacketList(lpMacroList); return(FALSE); } // disable all mouse and keyboard input during macro play EnableWindow(hParent, FALSE); // if not in a threading environment and caller wants us // to display a progress dialog, then set it up and do it if (!Control.UseThreading) { iCount = ListGetCount(lpMacroList) - nActivates; iCount *= nRepeat; Setup.iTotal = iCount; Setup.idDialog = IDD_MACRO_STATUS; Setup.lpFileName = NULL; hDlg = AstralDlgParam( YES, PictPubApp.GetResourceHandle(), hParent, IDD_MACRO_STATUS, DlgMacroStatusProc, (LPARAM)(LPVOID)&Setup ); if (hDlg) { if (lpMacroName) { STRING szString; GetWindowText(hDlg, szString, sizeof(szString)); lstrcat(szString, _T(" - ")); lstrcat(szString, lpMacroName); SetWindowText(hDlg, szString); } UpdateWindow(hDlg); } } // Repeat macro nRepeat number of times fError = FALSE; while (--nRepeat >= 0 && !fError) { if (lpAbortProc && (*lpAbortProc)()) break; // back to beginning of macro file lpNextPkt = (LPCMDPKT)ListGetHead(lpMacroList); // initialize sequencing fSequence = fSequenceAll; while (!fError && lpNextPkt) { if (lpAbortProc && (*lpAbortProc)()) { fError = TRUE; break; } // get the packet to work on if (fCopyPackets) { lpCmdPkt = CopyPacket(lpNextPkt); if (!lpCmdPkt) { fError = TRUE; break; } } else { ListUnlink(lpMacroList, lpNextPkt); lpCmdPkt = lpNextPkt; } // get command id and parms for this command idCommand = lpCmdPkt->idCommand; // Find out whether this command requires sequencing // set it here, so command can change it if needed before // we actually set fSequence fCmdSequence = GetCommandSequence(idCommand); CommandType = GetCommandType(idCommand); // Handle the different types of commands switch (CommandType) { case CT_LOAD: // create new command list for load lpNewList = CreateCommandList(); if (lpNewList) { ListAddTail(&lpNewList->PacketList, lpCmdPkt); // if we already have a command list containing commands, // kick off the execution of those commands before we // switch to the new command list if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); // if some command in the command list affects // sequencing force the whole command list to // be processed if (fSequence) { FlushCommands(lpCmdList); fSequence = fSequenceAll; } } // setup new command list for us to work with lpCmdList = lpNewList; lpCmdList->PhotoCDResOverride = PhotoCDResOverride; // If there are any activates in this macro make sure a // command that creates an image processes immediately if (nActivates) { PlaybackCommands(lpCmdList); FlushCommands(lpCmdList); fSequence = fSequenceAll; fCmdSequence = NO; // already sequenced } } break; case CT_COPY: // Make sure we have a command list to work with if (!lpCmdList) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } // Just add this command to the command list ListAddTail(&lpCmdList->PacketList, lpCmdPkt); // If there are any activates in this macro make sure a // command that creates an image processes immediately if (nActivates) { PlaybackCommands(lpCmdList); FlushCommands(lpCmdList); fSequence = fSequenceAll; fCmdSequence = NO; // already sequenced } break; case CT_SAVE: case CT_EDIT: case CT_MASK: case CT_MODE: case CT_EDITUNDO: case CT_MASKUNDO: case CT_EDITOBJ: case CT_CLOSE: // Make sure we have a command list to work with if (!lpCmdList) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } if (CommandType == CT_SAVE) { PlaybackCommands(lpCmdList); if (!lpCmdList->ThreadData.lpImage) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } } // Just add this command to the command list ListAddTail(&lpCmdList->PacketList, lpCmdPkt); if (CommandType != CT_CLOSE) break; case CT_ACTIVATE: // Program or commands that affect window activation // are processed here switch (idCommand) { case IDS_CMD_CLOSE: case IDS_CMD_ACTIVATEWINDOW: { // if we already have a command list containing commands, // kick of the execution of those commands before we // switch to the new command list if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); // if some command in the command list affects // sequencing force the whole command list to // be processed if (fSequence) { FlushCommands(lpCmdList); fSequence = fSequenceAll; } } // if this was a close command, then wack the command list pointer if (idCommand == IDS_CMD_CLOSE) lpCmdList = NULL; else { // now process the activate and get a new command list lpNewList = ProgActivateWindow( (LPACTIVATEWINDOW_PARMS)lpCmdPkt->lpParms); // setup the new command list if we got one if (lpNewList) lpCmdList = lpNewList; else { CommandError(idCommand); fError = TRUE; } // activate don't go through command processing // so we have to free it up here FreeUpPacket(lpCmdPkt); } } break; default: break; } break; default: break; } // if command just handled requires sequencing // set sequencing flag if (fCmdSequence) fSequence = YES; if (fCopyPackets) // get next command packet in macro list lpNextPkt = (LPCMDPKT)ListGetNext(lpNextPkt); else // head of list will be next one if we're not copying lpNextPkt = (LPCMDPKT)ListGetHead(lpMacroList); } } // get rid of macro list DestroyPacketList(lpMacroList); // if we already have a command list containing commands, // kick off the execution of those commands if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); if (fSequenceAll) FlushCommands(lpCmdList); } // turn off the macro mode EnableWindow(hParent, TRUE); if ( AstralStrEx( IDS_APPNAME, szAppName, sizeof(szAppName) ) ) SetWindowText( PictPubApp.Get_hWndAstral(), szAppName ); // if we have a progress dialog, nuke it if (hDlg) AstralDlgEnd(hDlg, TRUE); // if we are display the macro status for another modal dialog // make sure the main app stuff is still disabled if (hParent != PictPubApp.Get_hWndAstral()) { EnableOverlappedWindow( PictPubApp.Get_hWndAstral(), FALSE ); EnableWindow(PictPubApp.Get_hWndAstral(), FALSE); } MacroMode = MM_NONE; return(TRUE); }
void PlayBatchMacro(LPLIST lpQueueList) /***********************************************************************/ { LPQUEUEITEM lpQueueItem = NULL; LPMACROITEM lpMacroItem; FNAME szFileName; LIST TempList; BOOL fError = TRUE; fPCDNotice = FALSE; while (TRUE) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) { fError = FALSE; break; } ListInit(&lpQueueItem->PacketList); // create a command list for the load command if (!CreateLoadFileParms(0, lpQueueItem->szFileName, TRUE, &lpQueueItem->cmsInfo, &lpQueueItem->PhotoCDResOverride, &lpQueueItem->parms)) continue; lpMacroItem = NULL; while (TRUE) { if (lpMacroItem) lpMacroItem = (LPMACROITEM)ListGetNext(lpMacroItem); else lpMacroItem = (LPMACROITEM)ListGetHead(&lpQueueItem->MacroList); if (!lpMacroItem) break; if ( !LookupExtFile( lpMacroItem->szMacro, szFileName, IDN_MACRO ) ) continue; // read in the entire macro file for faster processing if (!ReadMacro(szFileName, &TempList)) continue; if (MacroAnyLoadCommands(&TempList)) { Message(IDS_BADBATCHMACRO); DestroyPacketList(&TempList); continue; } ListAddTail(&lpQueueItem->PacketList, ListGetHead(&TempList)); } if (!SetupMacro(lpQueueItem)) break; } if (!fError) { if (EnableLogging(TRUE)) { lpQueueItem = NULL; while (!fError) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) break; if (!PlayMacro(NULL, NULL, 1, NO, &lpQueueItem->PacketList, NULL, lpQueueItem->PhotoCDResOverride)) break; } EnableLogging(FALSE); } } lpQueueItem = NULL; while (TRUE) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) break; DestroyPacketList(&lpQueueItem->PacketList); DestroyPtrList(&lpQueueItem->MacroList); } DestroyPtrList(lpQueueList); }