1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * phoimglist.c: list manipulation for PhoImage type. 4 * 5 * Copyright 2010 by Akkana Peck. 6 * You are free to use or modify this code under the Gnu Public License. 7 */ 8 9 /* A PhoImage is a doubly-linked list, with ->next and ->prev. 10 * The global gFirstImage marks the head of the list; 11 * the list is circular, so the last item has next = gFirstImage. 12 * 13 * gCurImage points to the current list item. 14 * 15 * List items are freed with FreePhoImage() 16 */ 17 18 #include "pho.h" 19 #include <stdlib.h> 20 21 /* This routine exists to keep track of any allocated memory 22 * existing in the PhoImage structure. 23 */ FreePhoImage(PhoImage * img)24static void FreePhoImage(PhoImage* img) 25 { 26 if (img->comment) free(img->comment); 27 free(img); 28 } 29 printImageList()30static void printImageList() 31 { 32 if (! gFirstImage) { 33 printf(" No images\n"); 34 return; 35 } 36 PhoImage* im = gFirstImage; 37 PhoImage* lastIm = gFirstImage->prev; 38 while (im) { 39 if (im == gCurImage) 40 printf("> %s\n", im->filename); 41 else 42 printf(" %s\n", im->filename); 43 if (im == lastIm) 44 break; 45 im = im->next; 46 } 47 printf("\n"); 48 } 49 50 /* Delete an image from the image list (not from disk). 51 * Will use gCurImage if item == 0. 52 * Update gCurImage if needed. 53 */ DeleteItem(PhoImage * item)54void DeleteItem(PhoImage* item) 55 { 56 if (gDebug) { 57 printf("Removing image %s from image list\n", item->filename); 58 printf("Image list before removal:\n"); 59 printImageList(); 60 } 61 62 if (!item) 63 item = gCurImage; 64 65 /* Is this the only image? */ 66 if (item == gFirstImage && item->next == gFirstImage) { 67 gFirstImage = gCurImage = 0; 68 } 69 else { 70 /* Is it the first image? */ 71 if (item == gFirstImage) { 72 if (gCurImage) 73 gCurImage = item->next; 74 gFirstImage = item->next; 75 } 76 77 /* Is it the last image? */ 78 else if (item == gFirstImage->prev) { 79 gFirstImage->prev = item->prev; // New last image 80 item->prev->next = gFirstImage; 81 if (gCurImage) 82 gCurImage = item->prev; 83 } 84 else if (gCurImage) 85 gCurImage = item->next; 86 87 item->next->prev = item->prev; 88 item->prev->next = item->next; 89 } 90 91 /* It's disconnected. Free all the memory */ 92 FreePhoImage(item); 93 94 /* What does the list look like now? */ 95 if (gDebug) { 96 printf("Image list after removal:\n"); 97 printImageList(); 98 } 99 } 100 101 /* Append an item to the end of the list */ AppendItem(PhoImage * item)102void AppendItem(PhoImage* item) 103 { 104 PhoImage* last; 105 106 if (!item) 107 return; 108 109 /* Is the list empty? */ 110 if (gFirstImage == 0) { 111 gFirstImage = item; 112 item->next = item->prev = item; 113 return; 114 } 115 116 /* Is there only one item in the list? */ 117 if (gFirstImage->next == gFirstImage) { 118 gFirstImage->next = gFirstImage->prev = item; 119 item->next = item->prev = gFirstImage; 120 return; 121 } 122 123 last = gFirstImage->prev; 124 last->next = item; 125 item->prev = last; 126 item->next = gFirstImage; 127 gFirstImage->prev = item; 128 } 129 130 /* Remove all images from the image list, to start fresh. */ ClearImageList()131void ClearImageList() 132 { 133 PhoImage* img = gFirstImage; 134 do { 135 PhoImage* next = img->next; 136 FreePhoImage(img); 137 img = next; 138 } while (img && img != gFirstImage); 139 140 gCurImage = gFirstImage = 0; 141 } 142 143