gliv-1.4.5
[gliv.git] / src / history.c
blob6d0b6bb8041ad901a1377f92ea57270bc60230c7
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <booh@altern.org>
21 /*********************
22 * History handling. *
23 *********************/
25 #include "gliv.h"
27 extern rt_struct *rt;
28 extern options_struct *options;
30 static GList *list = NULL;
31 static GList *node = NULL; /* Currrent position in the list. */
33 /*
34 * Number of elements in the list, it would 50 days with 1 event
35 * each millisecond to overflow, so we feel safe.
37 static guint32 count;
39 static gboolean used; /* Wether the history has been initialized. */
41 void init_history(void)
43 if (options->history_size != 0) {
44 node = list = g_new0(GList, 1);
45 count = 0;
46 used = TRUE;
47 } else
48 used = FALSE;
51 /* Returns item->next. */
52 static GList *free_item(GList * item)
54 GList *next;
56 if (item->prev != NULL)
57 item->prev->next = NULL;
59 if (item->next != NULL)
60 item->next->prev = NULL;
62 g_free(item->data);
63 next = item->next;
64 g_list_free_1(item);
65 count--;
67 return next;
70 static void free_list(GList * item)
72 while (item != NULL)
73 item = free_item(item);
76 static void clean_list(void)
78 while (count > options->history_size) {
79 if (node == list)
80 node = node->next;
81 list = free_item(list);
84 list->prev = NULL;
87 void append_history(void)
89 GList *item;
91 if (used == FALSE || options->history_size == 0)
92 return;
94 item = g_list_alloc();
95 item->data = g_new(state_struct, 1);
97 matrix_cpy(item->data, NULL);
99 item->prev = node;
100 item->next = NULL;
102 if (list == NULL)
103 list = item;
104 else {
105 if (node->next != NULL)
106 free_list(node->next);
108 node->next = item;
111 node = item;
112 count++;
114 if (options->history_size > 0)
115 clean_list();
118 static void set_state(GList * item)
120 if (item != NULL && item->data != NULL) {
121 node = item;
122 matrix_cpy(NULL, item->data);
123 refresh(REFRESH_IMAGE | REFRESH_STATUS);
127 void undo(void)
129 set_state(g_list_previous(node));
132 void redo(void)
134 set_state(g_list_next(node));
137 void clear_history(void)
139 if (list != NULL) {
140 free_list(list);
141 node = list = NULL;
142 count = 0;
143 init_history();
144 append_history();