From 9e3a36537d07700ec49f432940b95cf2ee9689e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Dec 2009 08:13:06 -0800 Subject: First insert of the various lua files. --- iupe-hexview.lua | 552 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 552 insertions(+) create mode 100644 iupe-hexview.lua (limited to 'iupe-hexview.lua') diff --git a/iupe-hexview.lua b/iupe-hexview.lua new file mode 100644 index 0000000..12ec90c --- /dev/null +++ b/iupe-hexview.lua @@ -0,0 +1,552 @@ +loadmodule "luaiup" +loadmodule "luahandle" +loadmodule "lualibs" + +load "iupe-dbuffer.lua" + +if not iupe then iupe = {} end +if not iupep then iupep = {} end + +local cursorcolors = { + GREEN = cd.EncodeColor(0, 224, 0), + LIGHTGREEN = cd.EncodeColor(224, 255, 224), +} + +local mousecolors = { + YELLOW = cd.EncodeColor(255, 255, 0), + LIGHTYELLOW = cd.EncodeColor(255, 255, 192), +} + +markercolors = { + [-2] = cursorcolors.GREEN, + [-1] = mousecolors.YELLOW, + [0] = cd.EncodeColor(0, 255, 178), -- 0.45 + [1] = cd.EncodeColor(0, 255, 255), -- 0.50 + [2] = cd.EncodeColor(0, 178, 255), -- 0.55 + [3] = cd.EncodeColor(0, 102, 255), -- 0.60 + [4] = cd.EncodeColor(0, 25, 255), -- 0.65 + [5] = cd.EncodeColor(50, 0, 255), -- 0.70 + [6] = cd.EncodeColor(127, 0, 255), -- 0.75 + [7] = cd.EncodeColor(204, 0, 255), -- 0.80 + [8] = cd.EncodeColor(255, 0, 229), -- 0.85 + [9] = cd.EncodeColor(255, 0, 152), -- 0.90 + [10] = cd.EncodeColor(255, 0, 76), -- 0.95 +} + +iupep.hexview = { + printgrid = function (self, msg, y, x) + local cvdb = self.cvdb + if not x then x = self.textcursor.x end + if not y then y = self.textcursor.y end + cvdb:Foreground(cd.BLACK) + cvdb:Text(x * self.gridsize.x, self.height - self.gridsize.y * (y + 1), msg) + self.textcursor.x = x + msg:len() + self.textcursor.y = y + end, + + colorgrid = function (self, color, len, y, x, height) + local cvdb = self.cvdb + if not len then len = 1 end + if not height then height = 1 end + if not x then x = self.textcursor.x end + if not y then y = self.textcursor.y end + cvdb:Foreground(color) + local xmin, xmax, ymin, ymax = x * self.gridsize.x, (x + len) * self.gridsize.x - 1, self.height - self.gridsize.y * (y + 1 - height) - 2, self.height - self.gridsize.y * (y + 1) - 1 + cvdb:Box(xmin, xmax, ymin, ymax) + end, + + byte2char = function(self, b) + if b >= 32 and b <= 127 then + return string.char(b) + else + return "." + end + end, + + draw = function (self) + local cvdb = self.cvdb + if not cvdb then return iup.DEFAULT end + cvdb:Clear() + local handle = self.handle + local filecursor = self.filecursor + 0 + local nbbytes = self.nbbytes + 0 + local filesize = self.filesize + 0 + local oldfilecursor = self.oldfilecursor + 0 + local buf = self.buf + local max_bytes = math.max(math.min(filesize - filecursor, nbbytes), 0) + local old_max_bytes = (self.old_max_bytes or -1) + 0 + if handle then + handle:seek(filecursor) + if ((filecursor ~= oldfilecursor or max_bytes ~= old_max_bytes) and max_bytes ~= 0) or not buf then + if buf then buf:destroy() end + buf = Buffer(true) + self.buf = buf + handle:copyto(buf, max_bytes) + self.oldfilecursor = filecursor + self.old_max_bytes = max_bytes + else + buf:seek(0) + end + end + local line = 0 + local rcursor = 0 + local b + local kline, kcolumn + local mline, mcolumn + local krcursor = self.kcursor - filecursor + local mrcursor = self.mcursor - filecursor + local columns = self.columns + 0 + local nblines = self.nblines + 0 + kline = math.floor(krcursor / columns) + kcolumn = krcursor % columns + mline = math.floor(mrcursor / columns) + mcolumn = mrcursor % columns + + if self.mcursor ~= "-1" then + self:colorgrid(mousecolors.LIGHTYELLOW, 12 + columns * 4, mline, 0) + self:colorgrid(mousecolors.LIGHTYELLOW, 2, nblines - 1, mcolumn * 3 + 10, nblines) + self:colorgrid(mousecolors.LIGHTYELLOW, 1, nblines - 1, mcolumn + 12 + columns * 3, nblines) + self:colorgrid(mousecolors.YELLOW, 2, mline, mcolumn * 3 + 10) + self:colorgrid(mousecolors.YELLOW, 1, mline, mcolumn + 12 + columns * 3) + end + + self:colorgrid(cursorcolors.LIGHTGREEN, 12 + columns * 4, kline, 0) + self:colorgrid(cursorcolors.LIGHTGREEN, 2, nblines - 1, kcolumn * 3 + 10, nblines) + self:colorgrid(cursorcolors.LIGHTGREEN, 1, nblines - 1, kcolumn + 12 + columns * 3, nblines) + self:colorgrid(cursorcolors.GREEN, 2, kline, kcolumn * 3 + 10) + self:colorgrid(cursorcolors.GREEN, 1, kline, kcolumn + 12 + columns * 3) + + local marker + for i = 0, 10 do + marker = self.markers[i] + if marker ~= -1 then + mline = math.floor(marker / columns) + mcolumn = marker % columns + self:colorgrid(markercolors[i], 2, mline, mcolumn * 3 + 10) + self:colorgrid(markercolors[i], 1, mline, mcolumn + 12 + columns * 3) + end + end + + while rcursor < max_bytes do + local dstring = "" + self:printgrid(hex(buf:tell() + filecursor, "%08x "), line, 0) + for c = 1, columns do + b = buf:readU8() + self:printgrid(hex(b, "%02x ")) + dstring = dstring .. self:byte2char(b) + rcursor = rcursor + 1 + if rcursor >= max_bytes then break end + end + self:printgrid(dstring, line, 12 + columns * 3) + line = line + 1 + end + + cvdb:Flush() + + return iup.DEFAULT + end, + + updatescrollbar = function (self) + self.ymax = math.floor(self.filesize / self.columns) + self.dy = 1 + self.posy = math.floor(self.filecursor / self.columns) + iup.Update(self) + end, + + resize_cb = function (self, width, height) + local displaylines = self.displaylines + 0 + self.nblines = displaylines > 0 and displaylines or math.floor(height / self.gridsize.y) + self.nbbytes = self.nblines * self.columns + self:updatescrollbar() + iupep.dbuffer.resize_cb(self, width, height) + end, + + keypress_cb = function (self, c, press) + if press == 0 then return iup.DEFAULT end + local kaction = false + local raction = false + local kcursor = self.kcursor + 0 + local columns = self.columns + 0 + local filesize = self.filesize + 0 + local filecursor = self.filecursor + 0 + local nbbytes = self.nbbytes + 0 + if c == iup.K_UP then + kaction = true + kcursor = math.max(kcursor - columns, 0) + elseif c == iup.K_DOWN then + kaction = true + kcursor = math.min(kcursor + columns, filesize - 1) + elseif c == iup.K_LEFT then + kaction = true + kcursor = math.max(kcursor - 1, 0) + elseif c == iup.K_RIGHT then + kaction = true + kcursor = math.min(kcursor + 1, filesize - 1) + elseif c == iup.K_PGUP then + kaction = true + kcursor = math.max(kcursor - nbbytes + columns, 0) + elseif c == iup.K_PGDN then + kaction = true + kcursor = math.min(kcursor + nbbytes - columns, filesize - 1) + elseif c == iup.K_HOME then + kaction = true + kcursor = kcursor - (kcursor % columns) + elseif c == iup.K_END then + kaction = true + kcursor = math.min(kcursor + columns - (kcursor % columns) - 1, filesize - 1) + elseif c == iup.K_cUP then + kaction = true + if filecursor - columns >= 0 then + kcursor = kcursor - columns + filecursor = filecursor - columns + end + elseif c == iup.K_cDOWN then + kaction = true + if filecursor + columns < filesize then + kcursor = kcursor + columns + filecursor = filecursor + columns + end + elseif c == iup.K_cLEFT then + kaction = true + kcursor = math.max(kcursor - 1, 0) + filecursor = math.max(filecursor - 1, 0) + elseif c == iup.K_cRIGHT then + kaction = true + kcursor = math.min(kcursor + 1, filesize - 1) + filecursor = math.min(filecursor + 1, filesize) + elseif c == iup.K_cPGUP then + kaction = true + if filecursor - nbbytes >= 0 then + kcursor = math.max(kcursor - nbbytes, 0) + filecursor = math.max(filecursor - nbbytes, 0) + end + elseif c == iup.K_cPGDN then + kaction = true + if filecursor + nbbytes < filesize then + kcursor = math.min(kcursor + nbbytes, filesize - 1) + filecursor = math.min(filecursor + nbbytes, filesize) + end + elseif c == iup.K_cHOME then + kaction = true + kcursor = 0 + elseif c == iup.K_cEND then + kaction = true + kcursor = filesize - 1 + elseif c == iup.K_mLEFT then + raction = true + columns = columns - 1 + elseif c == iup.K_mRIGHT then + raction = true + columns = columns + 1 + elseif c == iup.K_mUP then + raction = true + filecursor = math.max(filecursor - columns, 0) + elseif c == iup.K_mDOWN then + raction = true + filecursor = math.min(filecursor + columns, filesize) + elseif c == iup.K_mPGUP then + raction = true + filecursor = math.max(filecursor - nbbytes, 0) + elseif c == iup.K_mPGDN then + raction = true + filecursor = math.min(filecursor + nbbytes, filesize) + elseif c == iup.K_1 then + kaction = true + local m = self.markers[1] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_2 then + kaction = true + local m = self.markers[2] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_3 then + kaction = true + local m = self.markers[3] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_4 then + kaction = true + local m = self.markers[4] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_5 then + kaction = true + local m = self.markers[5] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_6 then + kaction = true + local m = self.markers[6] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_7 then + kaction = true + local m = self.markers[7] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_8 then + kaction = true + local m = self.markers[8] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_9 then + kaction = true + local m = self.markers[9] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_0 then + kaction = true + local m = self.markers[10] + if m ~= -1 then + kcursor = m + end + elseif c == iup.K_m1 then + kaction = true + self.markers[1] = kcursor + elseif c == iup.K_m2 then + kaction = true + self.markers[2] = kcursor + elseif c == iup.K_m3 then + kaction = true + self.markers[3] = kcursor + elseif c == iup.K_m4 then + kaction = true + self.markers[4] = kcursor + elseif c == iup.K_m5 then + kaction = true + self.markers[5] = kcursor + elseif c == iup.K_m6 then + kaction = true + self.markers[6] = kcursor + elseif c == iup.K_m7 then + kaction = true + self.markers[7] = kcursor + elseif c == iup.K_m8 then + kaction = true + self.markers[8] = kcursor + elseif c == iup.K_m9 then + kaction = true + self.markers[9] = kcursor + elseif c == iup.K_m0 then + kaction = true + self.markers[10] = kcursor + elseif c == iup.K_SP then + kaction = true + end + if kaction then + while kcursor < filecursor do filecursor = filecursor - columns end + while (kcursor - filecursor) >= nbbytes do filecursor = filecursor + columns end + filecursor = math.min(math.max(filecursor, 0), filesize) + self.kcursor = kcursor + self.filecursor = filecursor + self.columns = columns + self:setcursor() + return iup.IGNORE + end + if raction then + self.filecursor = filecursor + self:updatescrollbar() + self:updatecolumns(columns) + self:draw() + return iup.IGNORE + end + return iup.DEFAULT + end, + + updatehandle = function (self, handle) + self.handle = handle + self.filesize = handle and handle:getsize() or 0 + self.old_max_bytes = -1 + self.old_filecursor = -1 + self:updatescrollbar() + self:draw() + end, + + map_cb = function (self) + iupep.dbuffer.map_cb(self) + local cvdb = self.cvdb + if not cvdb then return iup.DEFAULT end + cvdb:Font("Courier", cd.PLAIN, -self.gridsize.y) + -- self.rastersize = (self.gridsize.x * (self.columns * 4 + 14)) .. "x" -- will not allow the control to be shrinked. + -- self.gridsize.x = cvdb:GetFontDim() -- doesn't work as expected + end, + + setcursor = function (self, markerid, value) + if markerid then + markerid = markerid + 0 + if markerid >= 0 and markerid <= 10 then + self.markers[markerid] = value + 0 + elseif markerid == -2 then + self.kcursor = value + 0 + self:keypress_cb(iup.K_SP, 1) + end + end + for _, v in ipairs(self.cbs) do + v.cb(v.opaque, self) + end + self:updatescrollbar() + self:draw() + end, + + registercb = function (self, cb, opaque) + table.insert(self.cbs, { cb = cb, opaque = opaque }) + end, + + wheel_cb = function (self, delta, x, y, status) + if delta > 0 then + for i = 1, delta do self:keypress_cb(iup.K_cPGUP) end + else + for i = 1, -delta do self:keypress_cb(iup.K_cPGDN) end + end + end, + + scroll_cb = function (self, op, posx, posy) + if op == iup.SBUP then + self:keypress_cb(iup.K_mUP, 1) + elseif op == iup.SBDN then + self:keypress_cb(iup.K_mDOWN, 1) + elseif op == iup.SBPGUP then + self:keypress_cb(iup.K_mPGUP, 1) + elseif op == iup.SBPGDN then + self:keypress_cb(iup.K_mPGDN, 1) + else + local columns = self.columns + 0 + local startoffset = self.filecursor % columns + self.filecursor = math.min(math.max(math.floor(self.posy) * columns + startoffset, 0), self.filesize) + self:draw() + end + return iup.DEFAULT + end, + + motion_cb = function (self, x, y, status) + local r = self:resolvepos(x, y) + if r ~= -1 then self.mcursor = r end + self:setcursor() + return iup.DEFAULT + end, + + resolvepos = function (self, x, y) + local line = math.floor(y / self.gridsize.y) + local column = math.floor(x / self.gridsize.x) + local filecursor = self.filecursor + 0 + local columns = self.columns + 0 + + -- offset display + if column <= 7 then + return filecursor + columns * line + end + + -- gap 1 + if column <= 9 then return -1 end + + -- hex display + if column <= (columns * 3 + 10) then + -- interhex gap + if (column - 10) % 3 == 2 then return -1 end + return math.floor((column - 10) / 3) + filecursor + columns * line + end + + -- gap 2 + if column <= (columns * 3 + 11) then return -1 end + + -- ascii display + if column <= (columns * 4 + 11) then + return column - columns * 3 - 12 + filecursor + columns * line + end + + return -1 + end, + + button_cb = function (self, button, pressed, x, y, status) + if pressed == 1 then return iup.DEFAULT end + if button == iup.BUTTON1 then + local newpos = self:resolvepos(x, y) + if newpos ~= -1 then + self.kcursor = newpos + self:setcursor() + return iup.IGNORE + end + elseif button == iup.BUTTON3 then + local newpos = self:resolvepos(x, y) + if newpos ~= -1 then + self.markers[0] = newpos + self:setcursor() + return iup.IGNORE + end + end + return iup.DEFAULT + end, + + updategridsize = function (self, gridsize) + self.gridsize = gridsize or { x = 8, y = 14 } + self:resize_cb(self.width, self.height) + end, + + updatecolumns = function (self, columns) + self.columns = columns or 16 + self:resize_cb(self.width, self.height) + end, + + create = function (tab) + local handle = tab.handle + local columns = tab.columns + local gridsize = tab.gridsize + tab.handle = nil + tab.columns = nil + tab.gridsize = nil + tab.cursor = "TEXT" + tab.expand = "Yes" + tab.shrink = "Yes" + tab.border = "No" + tab.minsize = "0x0" + tab.size = "0x0" + tab.scrollbar = "vertical" + local r = iup.canvas(tab) + r.action = iupep.dbuffer.action + r.draw = iupep.hexview.draw + r.resize_cb = iupep.hexview.resize_cb + r.keypress_cb = iupep.hexview.keypress_cb + r.button_cb = iupep.hexview.button_cb + r.map_cb = iupep.hexview.map_cb + r.unmap_cb = iupep.dbuffer.unmap_cb + r.scroll_cb = iupep.hexview.scroll_cb + r.motion_cb = iupep.hexview.motion_cb + r.wheel_cb = iupep.hexview.wheel_cb + r.printgrid = iupep.hexview.printgrid + r.colorgrid = iupep.hexview.colorgrid + r.updatehandle = iupep.hexview.updatehandle + r.updategridsize = iupep.hexview.updategridsize + r.updatecolumns = iupep.hexview.updatecolumns + r.updatescrollbar = iupep.hexview.updatescrollbar + r.resolvepos = iupep.hexview.resolvepos + r.setcursor = iupep.hexview.setcursor + r.registercb = iupep.hexview.registercb + r.byte2char = iupep.hexview.byte2char + r.cbs = {} + r.handle = handle + r.columns = columns or 16 + r.filecursor = 0 + r.oldfilecursor = -1 + r.kcursor = 0 + r.filesize = handle and handle:getsize() or 0 + r.mcursor = -1 + r.markers = {} + r.displaylines = -1 + for i = 0, 10 do r.markers[i] = -1 end + r.gridsize = gridsize or { x = 8, y = 14 } + r.textcursor = { x = 0, y = 0 } + return r + end, +} + +iupe.hexview = iupep.hexview.create -- cgit v1.2.3