imported hexedit_1.2.12.orig.tar.gz
[rofl0r-hexedit0r.git] / display.c
blobe2f9b70e01b24fec22e1d04dc807b5b6bd209e0d
1 /* hexedit -- Hexadecimal Editor for Binary Files
2 Copyright (C) 1998 Pixel (Pascal Rigaux)
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/
17 #include "hexedit.h"
19 int move_cursor(INT delta)
21 return set_cursor(base + cursor + delta);
24 int set_cursor(INT loc)
26 if (loc < 0 && base % lineLength)
27 loc = 0;
29 if (!tryloc(loc))
30 return FALSE;
32 if (loc < base) {
33 if (loc - base % lineLength < 0)
34 set_base(0);
35 else if (!move_base(myfloor(loc - base % lineLength, lineLength) + base % lineLength - base))
36 return FALSE;
37 cursor = loc - base;
38 } else if (loc >= base + page) {
39 if (!move_base(myfloor(loc - base % lineLength, lineLength) + base % lineLength - page + lineLength - base))
40 return FALSE;
41 cursor = loc - base;
42 } else if (loc > base + nbBytes) {
43 return FALSE;
44 } else
45 cursor = loc - base;
47 if (mark_set)
48 updateMarked();
50 return TRUE;
53 int move_base(INT delta)
55 if (mode == bySector) {
56 if (delta > 0 && delta < page)
57 delta = page;
58 else if (delta < 0 && delta > -page)
59 delta = -page;
61 return set_base(base + delta);
64 int set_base(INT loc)
66 if (loc < 0) loc = 0;
68 if (!tryloc(loc)) return FALSE;
69 base = loc;
70 readFile();
72 if (mode != bySector && nbBytes < page - lineLength && base != 0) {
73 base -= myfloor(page - nbBytes - lineLength, lineLength);
74 if (base < 0) base = 0;
75 readFile();
78 if (cursor > nbBytes) cursor = nbBytes;
79 return TRUE;
83 int computeLineSize(void) { return computeCursorXPos(lineLength - 1, 0) + 1; }
84 int computeCursorXCurrentPos(void) { return computeCursorXPos(cursor, hexOrAscii); }
85 int computeCursorXPos(int cursor, int hexOrAscii)
87 int r = 11;
88 int x = cursor % lineLength;
89 int h = (hexOrAscii ? x : lineLength - 1);
91 r += normalSpaces * (h % blocSize) + (h / blocSize) * (normalSpaces * blocSize + 1) + (hexOrAscii && cursorOffset);
93 if (!hexOrAscii) r += x + normalSpaces + 1;
95 return r;
100 /*******************************************************************************/
101 /* Curses functions */
102 /*******************************************************************************/
103 void initCurses(void)
105 initscr();
107 #ifdef HAVE_COLORS
108 if (colored) {
109 start_color();
110 use_default_colors();
111 init_pair(1, COLOR_RED, -1); /* null zeros */
112 init_pair(2, COLOR_GREEN, -1); /* control chars */
113 init_pair(3, COLOR_BLUE, -1); /* extended chars */
115 #endif
117 refresh();
118 raw();
119 noecho();
120 keypad(stdscr, TRUE);
122 if (mode == bySector) {
123 lineLength = modes[bySector].lineLength;
124 page = modes[bySector].page;
125 page = myfloor((LINES - 1) * lineLength, page);
126 blocSize = modes[bySector].blocSize;
127 if (computeLineSize() > COLS) DIE("%s: term is too small for sectored view (width)\n");
128 if (page == 0) DIE("%s: term is too small for sectored view (height)\n");
129 } else { /* mode == maximized */
130 if (LINES <= 4) DIE("%s: term is too small (height)\n");
132 blocSize = modes[maximized].blocSize;
133 for (lineLength = blocSize; computeLineSize() <= COLS; lineLength += blocSize);
134 lineLength -= blocSize;
135 if (lineLength == 0) DIE("%s: term is too small (width)\n");
137 page = lineLength * (LINES - 1);
139 colsUsed = computeLineSize();
140 buffer = malloc(page);
141 bufferAttr = malloc(page * sizeof(*bufferAttr));
144 void exitCurses(void)
146 close(fd);
147 clear();
148 refresh();
149 endwin();
152 void display(void)
154 int i;
156 for (i = 0; i < nbBytes; i += lineLength) {
157 move(i / lineLength, 0);
158 displayLine(i, nbBytes);
160 for (; i < page; i += lineLength) {
161 int j;
162 move(i / lineLength, 0);
163 for (j = 0; j < colsUsed; j++) printw(" "); /* cleanup the line */
164 move(i / lineLength, 0);
165 PRINTW(("%08lX", (int) (base + i)));
168 attrset(NORMAL);
169 move(LINES - 1, 0);
170 for (i = 0; i < colsUsed; i++) printw("-");
171 move(LINES - 1, 0);
172 if (isReadOnly) i = '%';
173 else if (edited) i = '*';
174 else i = '-';
175 printw("-%c%c %s --0x%llX", i, i, baseName, base + cursor);
176 if (MAX(fileSize, lastEditedLoc)) printw("/0x%llX", getfilesize());
177 if (mode == bySector) printw("--sector %d", (base + cursor) / SECTOR_SIZE);
179 move(cursor / lineLength, computeCursorXCurrentPos());
182 void displayLine(int offset, int max)
184 int i;
186 PRINTW(("%08lX ", (int) (base + offset)));
187 for (i = offset; i < offset + lineLength; i++) {
188 if (i > offset) MAXATTRPRINTW(bufferAttr[i] & MARKED, (((i - offset) % blocSize) ? " " : " "));
189 if (i < max) {
190 ATTRPRINTW(
191 #ifdef HAVE_COLORS
192 (!colored ? 0 :
193 buffer[i] == 0 ? COLOR_PAIR(1) :
194 buffer[i] < ' ' ? COLOR_PAIR(2) :
195 buffer[i] >= 127 ? COLOR_PAIR(3) : 0) |
196 #endif
197 bufferAttr[i], ("%02X", buffer[i]));
199 else PRINTW((" "));
201 PRINTW((" "));
202 for (i = offset; i < offset + lineLength; i++) {
203 if (i >= max) PRINTW((" "));
204 else if (buffer[i] >= ' ' && buffer[i] < 127) ATTRPRINTW(bufferAttr[i], ("%c", buffer[i]));
205 else ATTRPRINTW(bufferAttr[i], ("."));
209 void clr_line(int line) { move(line, 0); clrtoeol(); }
211 void displayCentered(char *msg, int line)
213 clr_line(line);
214 move(line, (COLS - strlen(msg)) / 2);
215 PRINTW(("%s", msg));
218 void displayOneLineMessage(char *msg)
220 int center = page / lineLength / 2;
221 clr_line(center - 1);
222 clr_line(center + 1);
223 displayCentered(msg, center);
226 void displayTwoLineMessage(char *msg1, char *msg2)
228 int center = page / lineLength / 2;
229 clr_line(center - 2);
230 clr_line(center + 1);
231 displayCentered(msg1, center - 1);
232 displayCentered(msg2, center);
235 void displayMessageAndWaitForKey(char *msg)
237 displayTwoLineMessage(msg, pressAnyKey);
238 getch();
241 int displayMessageAndGetString(char *msg, char **last, char *p, int p_size)
243 int ret = TRUE;
245 displayOneLineMessage(msg);
246 ungetstr(*last);
247 echo();
248 getnstr(p, p_size - 1);
249 noecho();
250 if (*p == '\0') {
251 if (*last) strcpy(p, *last); else ret = FALSE;
252 } else {
253 FREE(*last);
254 *last = strdup(p);
256 return ret;
259 void ungetstr(char *s)
261 char *p;
262 if (s)
263 for (p = s + strlen(s) - 1; p >= s; p--) ungetch(*p);
266 int get_number(INT *i)
268 int err;
269 char tmp[BLOCK_SEARCH_SIZE];
270 echo();
271 getnstr(tmp, BLOCK_SEARCH_SIZE - 1);
272 noecho();
273 if (strbeginswith(tmp, "0x"))
274 err = sscanf(tmp + strlen("0x"), "%llx", i);
275 else
276 err = sscanf(tmp, "%lld", i);
277 return err == 1;