19ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley/* hexedit.c - Hexadecimal file editor 29ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley * 39ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley * Copyright 2015 Rob Landley <rob@landley.net> 49ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley * 59ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley * No standard 69ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 75ea14bd1c246f7571d466d18385db22f59ac3262Rob LandleyUSE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE)) 89ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 99ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landleyconfig HEXEDIT 109ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley bool "hexedit" 114c182c325716776a3e40394b175de479738e31a6Rob Landley default y 129ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley help 139ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley usage: hexedit FILENAME 149ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 15137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley Hexadecimal file editor. All changes are written to disk immediately. 16ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 17ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley -r Read only (display but don't edit) 18137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley 19137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley Keys: 20137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley Arrows Move left/right/up/down by one line/column 21137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley Pg Up/Pg Dn Move up/down by one page 22137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley 0-9, a-f Change current half-byte to hexadecimal value 23137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley u Undo 24137f5c9b0937dfa204ea2580e58430c7180a79c5Rob Landley q/^c/^d/<esc> Quit 259ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley*/ 269ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 279ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley#define FOR_hexedit 289ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley#include "toys.h" 299ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 309ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob LandleyGLOBALS( 319ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley char *data; 329ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley long long len, base; 333b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley int numlen, undo, undolen; 349ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley unsigned height; 359ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley) 369ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 373b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley#define UNDO_LEN (sizeof(toybuf)/(sizeof(long long)+1)) 3853b0cb856deafa015626f21b5a2f972cddc015bdRob Landley 39ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley// Render all characters printable, using color to distinguish. 40e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landleystatic int draw_char(FILE *fp, wchar_t broiled) 41ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley{ 42e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley if (fp) { 43e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley if (broiled<32 || broiled>=127) { 44e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley if (broiled>127) { 45e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley tty_esc("2m"); 46e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley broiled &= 127; 47e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley } 48e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley if (broiled<32 || broiled==127) { 49e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley tty_esc("7m"); 50e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley if (broiled==127) broiled = 32; 51e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley else broiled += 64; 52e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley } 53e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley printf("%c", broiled); 54e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley tty_esc("0m"); 55e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley } else printf("%c", broiled); 56e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley } 57e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley 58e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley return 1; 59ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley} 60ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 615ea14bd1c246f7571d466d18385db22f59ac3262Rob Landleystatic void draw_tail(void) 625ea14bd1c246f7571d466d18385db22f59ac3262Rob Landley{ 63b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_jump(0, TT.height); 64b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("K"); 655ea14bd1c246f7571d466d18385db22f59ac3262Rob Landley 66ba86864699997b0da780e15fd6be33c8a556e927Rob Landley draw_trim(*toys.optargs, -1, 71); 675ea14bd1c246f7571d466d18385db22f59ac3262Rob Landley} 685ea14bd1c246f7571d466d18385db22f59ac3262Rob Landley 699ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landleystatic void draw_line(long long yy) 709ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley{ 71913a7796bb47e0b65c4f28920c39a87c6b6211ddRob Landley int x, xx = 16; 729ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 739ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley yy = (TT.base+yy)*16; 74913a7796bb47e0b65c4f28920c39a87c6b6211ddRob Landley if (yy+xx>=TT.len) xx = TT.len-yy; 759ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 769ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley if (yy<TT.len) { 779ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley printf("\r%0*llX ", TT.numlen, yy); 78913a7796bb47e0b65c4f28920c39a87c6b6211ddRob Landley for (x=0; x<xx; x++) printf(" %02X", TT.data[yy+x]); 79913a7796bb47e0b65c4f28920c39a87c6b6211ddRob Landley printf("%*s", 2+3*(16-xx), ""); 80e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley for (x=0; x<xx; x++) draw_char(stdout, TT.data[yy+x]); 81913a7796bb47e0b65c4f28920c39a87c6b6211ddRob Landley printf("%*s", 16-xx, ""); 829ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley } 83b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("K"); 849ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley} 859ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 86ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landleystatic void draw_page(void) 879ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley{ 889ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley int y; 899ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 90b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_jump(0, 0); 919ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley for (y = 0; y<TT.height; y++) { 929ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley if (y) printf("\r\n"); 939ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley draw_line(y); 949ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley } 955ea14bd1c246f7571d466d18385db22f59ac3262Rob Landley draw_tail(); 969ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley} 979ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 98ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley// side: 0 = editing left, 1 = editing right, 2 = clear, 3 = read only 99ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landleystatic void highlight(int xx, int yy, int side) 100ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley{ 101ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley char cc = TT.data[16*(TT.base+yy)+xx]; 102ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley int i; 103ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 104ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley // Display cursor 105b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_jump(2+TT.numlen+3*xx, yy); 106b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("0m"); 107b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley if (side!=2) tty_esc("7m"); 108ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley if (side>1) printf("%02X", cc); 109ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley else for (i=0; i<2;) { 110b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley if (side==i) tty_esc("32m"); 111ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley printf("%X", (cc>>(4*(1&++i)))&15); 112ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley } 113b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("0m"); 114b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_jump(TT.numlen+17*3+xx, yy); 115e32e802240c5b3803b9769948dc7a18b3fc1630cRob Landley draw_char(stdout, cc); 116ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley} 117ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 1189ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landleyvoid hexedit_main(void) 1199ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley{ 1204eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley long long pos = 0, y; 1214eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley int x, i, side = 0, key, ro = toys.optflags&FLAG_r, 122ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley fd = xopen(*toys.optargs, ro ? O_RDONLY : O_RDWR); 1233b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley char keybuf[16]; 1249ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 125671ce0c9298091f28c92430482b18c1449dcd09eRob Landley *keybuf = 0; 126671ce0c9298091f28c92430482b18c1449dcd09eRob Landley 127b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley // Terminal setup 1289ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley TT.height = 25; 1299ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley terminal_size(0, &TT.height); 13053b0cb856deafa015626f21b5a2f972cddc015bdRob Landley if (TT.height) TT.height--; 131b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley sigatexit(tty_sigreset); 132b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("0m"); 133b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_esc("?25l"); 1349ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley fflush(0); 1351b983744cde6819fe1d810e98cfac52585ceacafRob Landley xset_terminal(1, 1, 0); 1369ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 137544c1ec1614cd9a8dcedac3478701e4b97b0f8a0Rob Landley if ((TT.len = fdlength(fd))<1) error_exit("bad length"); 1389ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley if (sizeof(long)==32 && TT.len>SIZE_MAX) TT.len = SIZE_MAX; 139b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley // count file length hex in digits, rounded up to multiple of 4 1409ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley for (pos = TT.len, TT.numlen = 0; pos; pos >>= 4, TT.numlen++); 1419ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley TT.numlen += (4-TT.numlen)&3; 1429ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 143ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley TT.data = mmap(0, TT.len, PROT_READ|(PROT_WRITE*!ro), MAP_SHARED, fd, 0); 1449ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley draw_page(); 1459ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 1469ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley for (;;) { 1474eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley // Scroll display if necessary 1484eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley if (pos<0) pos = 0; 149544c1ec1614cd9a8dcedac3478701e4b97b0f8a0Rob Landley if (pos>=TT.len) pos = TT.len-1; 1504eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley x = pos&15; 1514eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley y = pos/16; 1524eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley 1534eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley i = 0; 1544eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley while (y<TT.base) { 1554eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley if (TT.base-y>(TT.height/2)) { 1564eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley TT.base = y; 1574eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley draw_page(); 1584eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley } else { 1594eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley TT.base--; 1604eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley i++; 1614eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley tty_esc("1T"); 1624eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley tty_jump(0, 0); 1634eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley draw_line(0); 1644eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley } 1654eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley } 1664eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley while (y>=TT.base+TT.height) { 1674eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley if (y-(TT.base+TT.height)>(TT.height/2)) { 1684eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley TT.base = y-TT.height-1; 1694eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley draw_page(); 1704eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley } else { 1714eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley TT.base++; 1724eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley i++; 1734eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley tty_esc("1S"); 1744eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley tty_jump(0, TT.height-1); 1754eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley draw_line(TT.height-1); 1764eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley } 1779ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley } 1784eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley if (i) draw_tail(); 1794eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley y -= TT.base; 180ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 1814eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley // Display cursor and flush output 182ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley highlight(x, y, ro ? 3 : side); 183d3a435e53c94ec25b4ae5fa2614f49ef8884e08aRob Landley xflush(); 1849ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley 185ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley // Wait for next key 186efb309d4cdb2f4c3926b0550d9dc1661c1e4a091Rob Landley key = scan_key(keybuf, -1); 187ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley // Exit for q, ctrl-c, ctrl-d, escape, or EOF 188ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley if (key==-1 || key==3 || key==4 || key==27 || key=='q') break; 189ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley highlight(x, y, 2); 190ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 1913b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley // Hex digit? 192ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley if (key>='a' && key<='f') key-=32; 193ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley if (!ro && ((key>='0' && key<='9') || (key>='A' && key<='F'))) { 1943b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (!side) { 1953b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley long long *ll = (long long *)toybuf; 1963b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley 1973b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley ll[TT.undo] = pos; 1983b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley toybuf[(sizeof(long long)*UNDO_LEN)+TT.undo++] = TT.data[pos]; 1993b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (TT.undolen < UNDO_LEN) TT.undolen++; 2003b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley TT.undo %= UNDO_LEN; 2013b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley } 2023b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley 203ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley i = key - '0'; 204ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley if (i>9) i -= 7; 205ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley TT.data[pos] &= 15<<(4*side); 206ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley TT.data[pos] |= i<<(4*!side); 207ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley 2083b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (++side==2) { 2093b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley highlight(x, y, side); 210ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley side = 0; 2114eab65b911caf1f192d2ad6432d8b2473961be0dRob Landley ++pos; 212ed753aaa5481e487a23c9e0e6a855c09612eb7ceRob Landley } 2133b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley } else side = 0; 2143b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (key=='u') { 2153b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (TT.undolen) { 2163b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley long long *ll = (long long *)toybuf; 2173b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley 2183b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley TT.undolen--; 2193b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley if (!TT.undo) TT.undo = UNDO_LEN; 2203b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley pos = ll[--TT.undo]; 2213b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley TT.data[pos] = toybuf[sizeof(long long)*UNDO_LEN+TT.undo]; 2223b5cb96b1080d26be10675227d6a6f91acf82519Rob Landley } 2234b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley } 224544c1ec1614cd9a8dcedac3478701e4b97b0f8a0Rob Landley if (key>=256) { 2254b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley key -= 256; 2264b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley 2274b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley if (key==KEY_UP) pos -= 16; 2284b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley else if (key==KEY_DOWN) pos += 16; 2294b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley else if (key==KEY_RIGHT) { 2304b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley if (x<15) pos++; 2314b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley } else if (key==KEY_LEFT) { 2324b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley if (x) pos--; 2334b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley } else if (key==KEY_PGUP) pos -= 16*TT.height; 2344b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley else if (key==KEY_PGDN) pos += 16*TT.height; 2354b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley else if (key==KEY_HOME) pos = 0; 2364b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley else if (key==KEY_END) pos = TT.len-1; 2374b4ab6a50998219cd94139c5669ef9a624c8f58fRob Landley } 2389ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley } 2399ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley munmap(TT.data, TT.len); 2409ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley close(fd); 241b20c80b603c1795c473b3957fd2538485ec4eb90Rob Landley tty_reset(); 2429ac2d6546a2154a6797e12dfe86f36cc9420d6d4Rob Landley} 243