/* * Dalos * Copyright (C) 2003-2005 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: Hexview.cc,v 1.5 2006-02-02 11:01:12 pixel Exp $ */ #include #include #include "Hexview.h" void hexview::hexview_keyevent::down(SDL_keysym k) { if (!CurrentHexview || !CurrentHexview->GetVisible()) { if (old_handler) old_handler->down(k); return; } switch (k.sym) { case SDLK_DOWN: CurrentHexview->change_offset(CurrentHexview->get_offset() + CurrentHexview->get_width()); break; case SDLK_UP: CurrentHexview->change_offset(CurrentHexview->get_offset() - CurrentHexview->get_width()); break; case SDLK_RIGHT: if (KMOD_ALT & k.mod) { CurrentHexview->change_width(CurrentHexview->get_width() + 1); } else if (KMOD_CTRL & k.mod) { CurrentHexview->change_shift(CurrentHexview->get_shift() - 1); } else { CurrentHexview->change_offset(CurrentHexview->get_offset() + 1); } break; case SDLK_LEFT: if (KMOD_ALT & k.mod) { CurrentHexview->change_width(CurrentHexview->get_width() - 1); } else if (KMOD_CTRL & k.mod) { CurrentHexview->change_shift(CurrentHexview->get_shift() + 1); } else { CurrentHexview->change_offset(CurrentHexview->get_offset() - 1); } break; case SDLK_PAGEDOWN: CurrentHexview->change_offset(CurrentHexview->get_offset() + CurrentHexview->get_width() * CurrentHexview->get_nlines()); break; case SDLK_PAGEUP: CurrentHexview->change_offset(CurrentHexview->get_offset() - CurrentHexview->get_width() * CurrentHexview->get_nlines()); break; case SDLK_HOME: CurrentHexview->change_offset(0); break; case SDLK_END: CurrentHexview->change_offset(CurrentHexview->get_size() - 1); break; default: if (old_handler) old_handler->down(k); return; } } void hexview::hexview_keyevent::up(SDL_keysym k) { if (old_handler) old_handler->up(k); } hexview::hexview(mogltk::shape * sh, mogltk::widget * father) : widget(father, 0, 0, father->GetW(), father->GetH(), 0, "hexview", sh), h(0), width(16), offset(0), offset_loaded(-1), size_loaded(0), data(0), virtual_base(0), shift(0) { nlines = GetH() / 13; CurrentHexview = this; } hexview::~hexview() throw (GeneralException) { free(data); CurrentHexview = 0; } void hexview::set_virtual_base(int _virtual_base) { virtual_base = _virtual_base; } int hexview::get_nlines() { return nlines; } int hexview::get_size() { if (!h) return 0; return h->GetSize(); } void hexview::change_width(int _width) { if (_width <= 0) _width = 1; if (width != _width) { free(data); width = _width; } } int hexview::get_width() { return width; } void hexview::change_offset(int _offset) { if ((_offset < 0) || !h) _offset = 0; if (h && (_offset >= h->GetSize())) _offset = h->GetSize() - 1; offset = _offset; } int hexview::get_offset() { return offset; } void hexview::change_shift(int _shift) { if (_shift < 0) _shift = 0; shift = _shift; } int hexview::get_shift() { return shift; } void hexview::bind_handle(Handle * _h) { h = _h; refresh_data(); } Uint8 * hexview::get_data() { if (!data) { data = (Uint8 *) malloc(nlines * width); } if ((offset_loaded == offset) && (size_loaded == (nlines * width))) return data; h->seek(offset); h->read(data, nlines * width); offset_loaded = offset; size_loaded = nlines * width; return data; } void hexview::refresh_data() { size_loaded = 0; get_data(); } void hexview::draw() { int i, max_o, j, k, start_o, l, c; if (!h) return; get_data(); mogltk::FixedFont->setcolor(WHITE); mogltk::FixedFont->putcursor(GetAX() - shift * 6, GetAY()); max_o = MIN(h->GetSize(), offset + nlines * width); for (i = start_o = offset, j = 0, l = 0; i < max_o; i++) { if ((j % width) == 0) { mogltk::FixedFont->printf("%08X ", i + virtual_base); } mogltk::FixedFont->printf("%02X ", data[j]); j++; if ((j % width) == 0) { for (k = start_o, c = 0; k < start_o + width; k++, c++) { mogltk::FixedFont->putcursor(GetAX() + (c + width * 3 + 14 - shift) * 6, GetAY() + l * 13); if (data[j - width + c] >= 0x20) // Have better font support here... mogltk::FixedFont->putentry(data[j - width + c] - 0x20); } l++; mogltk::FixedFont->putcursor(GetAX() - shift * 6, GetAY() + l * 13); start_o = i; } } } void hexview::resize_notify() { nlines = Father()->GetH() / 13; resize(Father()->GetW(), Father()->GetH()); } hexview * CurrentHexview;