File: | fe-text/mainwindows-layout.c |
Location: | line 155, column 15 |
Description: | Division by zero/undefined value. |
1 | /* |
2 | mainwindows-layout.c : irssi |
3 | |
4 | Copyright (C) 2001 Timo Sirainen |
5 | |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License along |
17 | with this program; if not, write to the Free Software Foundation, Inc., |
18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ |
20 | |
21 | #include "module.h" |
22 | #include "signals.h" |
23 | #include "misc.h" |
24 | #include "lib-config/iconfig.h" |
25 | #include "settings.h" |
26 | |
27 | #include "mainwindows.h" |
28 | #include "gui-windows.h" |
29 | #include "textbuffer-view.h" |
30 | |
31 | static void sig_layout_window_save(WINDOW_REC *window, CONFIG_NODE *node) |
32 | { |
33 | WINDOW_REC *active; |
34 | GUI_WINDOW_REC *gui; |
35 | |
36 | gui = WINDOW_GUI(window)((GUI_WINDOW_REC *) ((window)->gui_data)); |
37 | if (gui->sticky) { |
38 | iconfig_node_set_bool(node, "sticky", TRUE)config_node_set_bool(mainconfig, node, "sticky", (!(0))); |
39 | active = gui->parent->active; |
40 | if (window != active) |
41 | iconfig_node_set_int(node, "parent", active->refnum)config_node_set_int(mainconfig, node, "parent", active->refnum ); |
42 | } |
43 | |
44 | if (gui->use_scroll) |
45 | iconfig_node_set_bool(node, "scroll", gui->scroll)config_node_set_bool(mainconfig, node, "scroll", gui->scroll ); |
46 | } |
47 | |
48 | static void sig_layout_window_restore(WINDOW_REC *window, CONFIG_NODE *node) |
49 | { |
50 | WINDOW_REC *parent; |
51 | GUI_WINDOW_REC *gui; |
52 | |
53 | gui = WINDOW_GUI(window)((GUI_WINDOW_REC *) ((window)->gui_data)); |
54 | |
55 | parent = window_find_refnum(config_node_get_int(node, "parent", -1)); |
56 | if (parent != NULL((void *)0)) |
57 | gui_window_reparent(window, WINDOW_MAIN(parent)(((GUI_WINDOW_REC *) ((parent)->gui_data))->parent)); |
58 | |
59 | if (config_node_get_bool(node, "sticky", FALSE(0))) |
60 | gui_window_set_sticky(window); |
61 | if (config_node_get_str(node, "scroll", NULL((void *)0)) != NULL((void *)0)) { |
62 | gui->use_scroll = TRUE(!(0)); |
63 | gui->scroll = config_node_get_bool(node, "scroll", TRUE(!(0))); |
64 | textbuffer_view_set_scroll(gui->view, gui->scroll); |
65 | } |
66 | } |
67 | |
68 | static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node) |
69 | { |
70 | char num[MAX_INT_STRLEN((sizeof(int) * 8 + 2) / 3 + 1)]; |
71 | |
72 | ltoa(num, window->active->refnum)g_snprintf(num, sizeof(num), "%d", window->active->refnum ); |
73 | node = config_node_section(node, num, NODE_TYPE_BLOCK); |
74 | |
75 | iconfig_node_set_int(node, "first_line", window->first_line)config_node_set_int(mainconfig, node, "first_line", window-> first_line); |
76 | iconfig_node_set_int(node, "lines", window->height)config_node_set_int(mainconfig, node, "lines", window->height ); |
77 | } |
78 | |
79 | static void sig_layout_save(void) |
80 | { |
81 | CONFIG_NODE *node; |
82 | |
83 | iconfig_set_str(NULL, "mainwindows", NULL)config_set_str(mainconfig, ((void *)0), "mainwindows", ((void *)0)); |
84 | node = iconfig_node_traverse("mainwindows", TRUE)config_node_traverse(mainconfig, "mainwindows", (!(0))); |
85 | |
86 | g_slist_foreach(mainwindows, (GFunc) main_window_save, node); |
87 | } |
88 | |
89 | static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2) |
90 | { |
91 | return config_node_get_int(n1, "first_line", 0) > |
92 | config_node_get_int(n2, "first_line", 0) ? -1 : 1; |
93 | } |
94 | |
95 | /* Returns list of mainwindow nodes sorted by first_line |
96 | (lowest in screen first) */ |
97 | static GSList *get_sorted_windows_config(CONFIG_NODE *node) |
98 | { |
99 | GSList *tmp, *output; |
100 | |
101 | output = NULL((void *)0); |
102 | tmp = config_node_first(node->value); |
103 | for (; tmp != NULL((void *)0); tmp = config_node_next(tmp)) { |
104 | output = g_slist_insert_sorted(output, tmp->data, |
105 | (GCompareFunc) window_node_cmp); |
106 | } |
107 | |
108 | return output; |
109 | } |
110 | |
111 | static void sig_layout_restore(void) |
112 | { |
113 | MAIN_WINDOW_REC *lower_window; |
114 | WINDOW_REC *window; |
115 | CONFIG_NODE *node; |
116 | GSList *tmp, *sorted_config; |
117 | int avail_height, height, *heights; |
118 | int i, lower_size, windows_count, diff; |
119 | |
120 | node = iconfig_node_traverse("mainwindows", FALSE)config_node_traverse(mainconfig, "mainwindows", (0)); |
121 | if (node == NULL((void *)0)) return; |
[1] Taking false branch | |
122 | |
123 | sorted_config = get_sorted_windows_config(node); |
124 | windows_count = g_slist_length(sorted_config); |
125 | |
126 | /* calculate the saved terminal height */ |
127 | avail_height = term_height - |
128 | screen_reserved_top - screen_reserved_bottom; |
129 | height = 0; |
130 | heights = g_new0(int, windows_count)((int *) g_malloc0 (((gsize) sizeof (int)) * ((gsize) (windows_count )))); |
131 | for (i = 0, tmp = sorted_config; tmp != NULL((void *)0); tmp = tmp->next, i++) { |
[2] Loop condition is false. Execution continues on line 138 | |
132 | CONFIG_NODE *node = tmp->data; |
133 | |
134 | heights[i] = config_node_get_int(node, "lines", 0); |
135 | height += heights[i]; |
136 | } |
137 | |
138 | if (avail_height <= (WINDOW_MIN_SIZE2*2)+1) { |
[3] Taking false branch | |
139 | /* we can fit only one window to screen - |
140 | give it all the height we can */ |
141 | windows_count = 1; |
142 | heights[0] = avail_height; |
143 | } else if (height != avail_height) { |
[4] Taking true branch | |
144 | /* Terminal's height is different from the saved one. |
145 | Resize the windows so they fit to screen. */ |
146 | while (height > avail_height && |
[5] Loop condition is false. Execution continues on line 154 | |
147 | windows_count*(WINDOW_MIN_SIZE2+1) > avail_height) { |
148 | /* all windows can't fit into screen, |
149 | remove the lowest ones */ |
150 | windows_count--; |
151 | } |
152 | |
153 | /* try to keep the windows' size about the same in percents */ |
154 | for (i = 0; i < windows_count; i++) { |
[6] Loop condition is true. Entering loop body | |
155 | int size = avail_height*heights[i]/height; |
[7] Division by zero/undefined value | |
156 | if (size < WINDOW_MIN_SIZE2+1) |
157 | size = WINDOW_MIN_SIZE2+1; |
158 | heights[i] = size; |
159 | } |
160 | |
161 | /* give/remove the last bits */ |
162 | height = 0; |
163 | for (i = 0; i < windows_count; i++) |
164 | height += heights[i]; |
165 | |
166 | diff = height < avail_height ? 1 : -1; |
167 | for (i = 0; height != avail_height; i++) { |
168 | if (i == windows_count) |
169 | i = 0; |
170 | |
171 | if (heights[i] > WINDOW_MIN_SIZE2+1) { |
172 | height += diff; |
173 | heights[i] += diff; |
174 | } |
175 | } |
176 | } |
177 | |
178 | /* create all the visible windows with correct size */ |
179 | lower_window = NULL((void *)0); lower_size = 0; |
180 | for (i = 0, tmp = sorted_config; i < windows_count; tmp = tmp->next, i++) { |
181 | CONFIG_NODE *node = tmp->data; |
182 | |
183 | /* create a new window + mainwindow */ |
184 | signal_emit("gui window create override", 1, |
185 | GINT_TO_POINTER(0)((gpointer) (0))); |
186 | |
187 | window = window_create(NULL((void *)0), TRUE(!(0))); |
188 | window_set_refnum(window, atoi(node->key)); |
189 | |
190 | if (lower_size > 0) |
191 | mainwindow_set_size(lower_window, lower_size, FALSE(0)); |
192 | |
193 | window_set_active(window); |
194 | active_mainwin = WINDOW_MAIN(window)(((GUI_WINDOW_REC *) ((window)->gui_data))->parent); |
195 | |
196 | lower_window = WINDOW_MAIN(window)(((GUI_WINDOW_REC *) ((window)->gui_data))->parent); |
197 | lower_size = heights[i]; |
198 | if (lower_size < WINDOW_MIN_SIZE2+1) |
199 | lower_size = WINDOW_MIN_SIZE2+1; |
200 | } |
201 | g_slist_free(sorted_config); |
202 | g_free(heights); |
203 | |
204 | if (lower_size > 0) |
205 | mainwindow_set_size(lower_window, lower_size, FALSE(0)); |
206 | } |
207 | |
208 | static void sig_layout_reset(void) |
209 | { |
210 | iconfig_set_str(NULL, "mainwindows", NULL)config_set_str(mainconfig, ((void *)0), "mainwindows", ((void *)0)); |
211 | } |
212 | |
213 | void mainwindows_layout_init(void) |
214 | { |
215 | signal_add("layout save window", (SIGNAL_FUNC) sig_layout_window_save)signal_add_full("fe-text", 0, ("layout save window"), (SIGNAL_FUNC ) ((SIGNAL_FUNC) sig_layout_window_save), ((void *)0)); |
216 | signal_add("layout restore window", (SIGNAL_FUNC) sig_layout_window_restore)signal_add_full("fe-text", 0, ("layout restore window"), (SIGNAL_FUNC ) ((SIGNAL_FUNC) sig_layout_window_restore), ((void *)0)); |
217 | signal_add("layout save", (SIGNAL_FUNC) sig_layout_save)signal_add_full("fe-text", 0, ("layout save"), (SIGNAL_FUNC) ( (SIGNAL_FUNC) sig_layout_save), ((void *)0)); |
218 | signal_add_first("layout restore", (SIGNAL_FUNC) sig_layout_restore)signal_add_full("fe-text", -100, ("layout restore"), (SIGNAL_FUNC ) ((SIGNAL_FUNC) sig_layout_restore), ((void *)0)); |
219 | signal_add("layout reset", (SIGNAL_FUNC) sig_layout_reset)signal_add_full("fe-text", 0, ("layout reset"), (SIGNAL_FUNC) ((SIGNAL_FUNC) sig_layout_reset), ((void *)0)); |
220 | } |
221 | |
222 | void mainwindows_layout_deinit(void) |
223 | { |
224 | signal_remove("layout save window", (SIGNAL_FUNC) sig_layout_window_save)signal_remove_full(("layout save window"), (SIGNAL_FUNC) ((SIGNAL_FUNC ) sig_layout_window_save), ((void *)0)); |
225 | signal_remove("layout restore window", (SIGNAL_FUNC) sig_layout_window_restore)signal_remove_full(("layout restore window"), (SIGNAL_FUNC) ( (SIGNAL_FUNC) sig_layout_window_restore), ((void *)0)); |
226 | signal_remove("layout save", (SIGNAL_FUNC) sig_layout_save)signal_remove_full(("layout save"), (SIGNAL_FUNC) ((SIGNAL_FUNC ) sig_layout_save), ((void *)0)); |
227 | signal_remove("layout restore", (SIGNAL_FUNC) sig_layout_restore)signal_remove_full(("layout restore"), (SIGNAL_FUNC) ((SIGNAL_FUNC ) sig_layout_restore), ((void *)0)); |
228 | signal_remove("layout reset", (SIGNAL_FUNC) sig_layout_reset)signal_remove_full(("layout reset"), (SIGNAL_FUNC) ((SIGNAL_FUNC ) sig_layout_reset), ((void *)0)); |
229 | } |