# HG changeset patch # User daveb # Date 1281053316 -34200 # Node ID fbabd1957c895ddb86abfd202d5f63b039602a32 # Parent 4dadc3c03b7e82d681d21b7233c9a26e0a96ff8f# Parent 576b9fba46771e8a7f4a85c427abf062afbe2afa Merge diff -r 576b9fba4677 -r fbabd1957c89 doodle/core/backtrace.d --- a/doodle/core/backtrace.d Thu Aug 05 22:49:41 2010 +0930 +++ b/doodle/core/backtrace.d Fri Aug 06 09:38:36 2010 +0930 @@ -12,201 +12,19 @@ // private { - import core.sys.posix.unistd; - import core.sys.posix.fcntl; - import core.sys.posix.sys.stat; - import core.sys.posix.sys.mman; - - import core.stdc.string; - import core.stdc.signal; - - import core.runtime; - - import std.stdio; - import std.string; - import std.demangle; - import std.algorithm; - - immutable int EI_NIDENT = 16; - - immutable int SHT_SYMTAB = 2; - immutable int SHT_STRTAB = 3; - - immutable int STT_FUNC = 2; - - alias ushort Elf32_Half; - alias uint Elf32_Word; - alias uint Elf32_Addr; - alias uint Elf32_Off; - alias ushort Elf32_Section; - - struct Elf32_Ehdr { - ubyte[EI_NIDENT] e_ident; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ - }; - - struct Elf32_Shdr { - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ - }; - - struct Elf32_Sym { - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - ubyte st_info; /* Symbol type and binding */ - ubyte st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ - }; - - extern (C) int backtrace(void**, size_t); - - struct Symbol { - this(void * a, size_t s, char * n) { - address = a; - size = s; - name = n; - } - void * address; - size_t size; - char * name; - void * end_address() { return address + size; } - }; - - // Newton-Raphson - Symbol nr_lookup(Symbol[] symbols, void * addr, int depth = 0) { - if (symbols.length == 0 || - addr < symbols[0].address || - addr >= symbols[$-1].end_address) - { - throw new Exception("Symbol not found"); - } - else if (symbols.length == 1) { - return symbols[0]; - } - else { - void * begin_addr = symbols[0].address; - void * end_addr = symbols[$-1].end_address; - int i = ((addr - begin_addr) * symbols.length) / (end_addr - begin_addr); - if (!(depth % 2) && i < symbols.length - 1) { ++i; } // Some wiggle to force convergence - - if (addr < symbols[i].address) { - return nr_lookup(symbols[0..i], addr, depth + 1); - } - else { - return nr_lookup(symbols[i..$], addr, depth + 1); - } - } - } - - int generate(void*[] addresses, scope int delegate(ref char[]) dg) { - static char[] get_exe() { - char buf[1024]; - ssize_t s = readlink("/proc/self/exe", buf.ptr, buf.length); - if (s == -1) { throw new Exception(""); } - return buf[0..s]; - } - - int fd = open(toStringz(get_exe()), O_RDONLY); - if (fd == -1) { throw new Exception(""); } - scope(exit) close(fd); - - stat_t st; - if (fstat(fd, &st) == -1) { throw new Exception(""); } - - void * contents = mmap(null, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (!contents) { throw new Exception(""); } - scope(exit) munmap(contents, st.st_size); - - Elf32_Ehdr * elf_hdr = cast(Elf32_Ehdr *)(contents); - - Elf32_Shdr * sec_hdr = cast(Elf32_Shdr *)(contents + elf_hdr.e_shoff); - - int symtab_idx = 0; - for (int i = 0; i < elf_hdr.e_shnum; ++i) { - if (sec_hdr[i].sh_type == SHT_SYMTAB) { - symtab_idx = i; - break; - } - } - if (symtab_idx == 0) { throw new Exception(""); } - - int strtab_idx = sec_hdr[symtab_idx].sh_link; - if (strtab_idx == 0) { throw new Exception(""); } // No associated string table + import core.stdc.signal; + import core.stdc.stdlib : free; + import core.stdc.string : strlen; + import core.runtime; + import std.demangle; + import std.string; - if (sec_hdr[strtab_idx].sh_type != SHT_STRTAB) { throw new Exception(""); } // invalid string table - - Elf32_Sym * sym_ent = cast(Elf32_Sym *)(contents + sec_hdr[symtab_idx].sh_offset); - char * strtab = cast(char *)(contents + sec_hdr[strtab_idx].sh_offset); - int num_syms = sec_hdr[symtab_idx].sh_size / sec_hdr[symtab_idx].sh_entsize; - - if (num_syms == 0) { throw new Exception(""); } // No symbols - - Symbol symbols[]; - - for (int i = 0; i < num_syms; ++i) { - if ((sym_ent[i].st_info & 0xf) != STT_FUNC) { - continue; - } - - if (sym_ent[i].st_shndx == 0) { - continue; - } - - void * address = cast(void *)(sym_ent[i].st_value); // inclusive - size_t size = sym_ent[i].st_size; - char * name = strtab + sym_ent[i].st_name; - - symbols ~= Symbol(address, size, name); - } - - sort!("a.address < b.address")(symbols); - - int ret; - foreach (address; addresses) { - string str = format("[0x%0.8x] ", address); - try { - Symbol symbol = nr_lookup(symbols, address); - char[] s1 = symbol.name[0..strlen(symbol.name)]; - str ~= format("%s", demangle(s1.idup)); - } - catch (Exception e) { - str ~= ""; - } - char[] cstr = str.dup; - ret = dg(cstr); - if (ret) { - break; - } - } - - return ret; - } - + extern (C) int backtrace(void**, size_t); + extern (C) char** backtrace_symbols(void**, int); // signal handler for otherwise-fatal thread-specific signals - extern (C) void arghh(int sig) { + extern (C) void signal_handler(int sig) { string name() { switch (sig) { case SIGSEGV: return "SIGSEGV"; @@ -222,40 +40,63 @@ shared static this() { // set up shared signal handlers for fatal thread-specific signals - //writeln("setting up shared signal handlers for ABRT, FPE, ILL, SEGV"); - signal(SIGABRT, &arghh); - signal(SIGFPE, &arghh); - signal(SIGILL, &arghh); - signal(SIGSEGV, &arghh); + signal(SIGABRT, &signal_handler); + signal(SIGFPE, &signal_handler); + signal(SIGILL, &signal_handler); + signal(SIGSEGV, &signal_handler); } static this() { // register our trace handler for each thread - //writeln("installing our traceHandler"); Runtime.traceHandler = &traceHandler; } - // Captures backtrace info at the point of construction, stripping - // off the bits that concern itself and the ininteresting early stuff. - // Also provides opApply to traverse a nice text representation of the backtrace. - class TraceInfo : Throwable.TraceInfo { - void*[256] callstack; - int numframes; - - this() { - numframes = backtrace(callstack.ptr, callstack.length); - } - - override string toString() const { - return "Why does dmd require an override of this?"; - } - - override int opApply(scope int delegate(ref char[]) dg) { - return generate(callstack[4..numframes-5], dg); - } - } - Throwable.TraceInfo traceHandler(void * ptr = null) { return new TraceInfo; } + + class TraceInfo : Throwable.TraceInfo { + this() { + immutable MAXFRAMES = 128; + void*[MAXFRAMES] callstack; + + numframes = backtrace(callstack.ptr, MAXFRAMES); + framelist = backtrace_symbols(callstack.ptr, numframes); + } + + ~this() { + free(framelist); + } + + override string toString() const { return null; } // Why does toString require overriding? + + override int opApply(scope int delegate(ref char[]) dg) { + // NOTE: The first 5 frames with the current implementation are + // inside core.runtime and the object code, so eliminate + // these for readability. + immutable FIRSTFRAME = 5; + int ret = 0; + + for(int i = FIRSTFRAME; i < numframes; ++i) { + char[] text = framelist[i][0 .. strlen(framelist[i])]; + + int a = text.lastIndexOf('('); + int b = text.lastIndexOf('+'); + + if (a != -1 && b != -1) { + ++a; + text = format("%s%s%s", text[0..a], demangle(text[a..b].idup), text[b..$]).dup; + } + + ret = dg(text); + if (ret) + break; + } + return ret; + } + + private: + int numframes; + char** framelist; + } } diff -r 576b9fba4677 -r fbabd1957c89 doodle/core/logging.d --- a/doodle/core/logging.d Thu Aug 05 22:49:41 2010 +0930 +++ b/doodle/core/logging.d Fri Aug 06 09:38:36 2010 +0930 @@ -31,7 +31,7 @@ mixin(defineEnum!("Severity", "TRACE", "INFO", "MESSAGE", "WARNING", "ERROR", "FATAL")); - string mod_string(in Severity s) { + string severityString(in Severity s) { switch (s) { case Severity.TRACE: return modifierString(Modifier.DIM) ~ fgColorString(Color.CYAN); @@ -52,7 +52,7 @@ } void log(in Severity severity, in string message) { - write(mod_string(severity)); + write(severityString(severity)); write(message); writeln(modifierString(Modifier.RESET)); } @@ -78,11 +78,11 @@ WHITE = 7 } - string modifierString(Modifier m) { return std.string.format("\033[%dm", 0 + m); } - string fgColorString(Color c) { return std.string.format("\033[%dm", 30 + c); } - string bgColorString(Color c) { return std.string.format("\033[%dm", 40 + c); } + string modifierString(in Modifier m) { return std.string.format("\033[%dm", 0 + m); } + string fgColorString(in Color c) { return std.string.format("\033[%dm", 30 + c); } + string bgColorString(in Color c) { return std.string.format("\033[%dm", 40 + c); } - private const(char)[] right(in char[] str, int n) { + private string right(in string str, in int n) { int pos = str.length < n ? 0 : str.length - n; return str[pos..$]; } diff -r 576b9fba4677 -r fbabd1957c89 doodle/gtk/palette.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doodle/gtk/palette.d Fri Aug 06 09:38:36 2010 +0930 @@ -0,0 +1,61 @@ +module doodle.gtk.palette; + +public { + import doodle.tk.palette; + import gtk.Toolbar; +} + +private { + import gtk.ToolButton; + import glib.ListSG; + import std.stdio; + import gtk.RadioToolButton; + import gtk.Image; +} + +class Palette : Toolbar, IPalette { + this() { + setIconSize(GtkIconSize.LARGE_TOOLBAR); + setStyle(GtkToolbarStyle.ICONS); + setOrientation(GtkOrientation.HORIZONTAL); + setTooltips(true); + } + + //void set( + + int add(in string iconPath, in string tooltipText, void delegate(int) dg) { + auto button = new RadioToolButton(_group); + auto image = new Image(iconBase ~ "/" ~ iconPath); + button.setLabelWidget(image); + int * i = new int; + *i = _delegates.length; + _delegates[*i] = dg; + button.objectGSetDataFull(indexStr, cast(gpointer)i); + button.addOnClicked(&onClicked); + insert(button); + return *i; + } + + void remove(in int id) { + } + + void activate(in int id) { + } + + private { + immutable iconBase = "/home/daveb/source/d/doodle/source/doodle/gtk/data"; + immutable indexStr = "index"; + ListSG _group; + void delegate(int) _delegates[int]; + + void onClicked(ToolButton tool_button) { + int * i = cast(int *)tool_button.getData(indexStr); + _delegates[*i](*i); + } + + /* + ToolButton find(int index) { + } + */ + } +} diff -r 576b9fba4677 -r fbabd1957c89 doodle/main/prog/doodler.d --- a/doodle/main/prog/doodler.d Thu Aug 05 22:49:41 2010 +0930 +++ b/doodle/main/prog/doodler.d Fri Aug 06 09:38:36 2010 +0930 @@ -10,6 +10,7 @@ import doodle.gtk.canvas; import doodle.gtk.toolbar; + import doodle.gtk.palette; import gtk.Main; import gtk.MainWindow; @@ -19,47 +20,39 @@ } void main(string[] args) { - trace("Test trace"); + Main.init(args); + auto window = new MainWindow("Doodle"); + auto vbox = new VBox(false, 0); /+ - trace("Test trace"); - info("Test trace"); - message("Test trace"); - warning("Test trace"); - error("Test trace"); - fatal("Test trace"); + auto toolBar = new ToolBar; + vbox.packStart(toolBar, false, false, 0); +/ - trace("Test trace1"); - Main.init(args); - trace("Test trace2"); - auto window = new MainWindow("Doodle"); - trace("Test trace3"); - auto vbox = new VBox(false, 0); - trace("Test trace4"); - auto toolBar = new ToolBar; - trace("Test trace5"); - vbox.packStart(toolBar, false, false, 0); + auto palette = new Palette; + palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); }); + palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); }); + palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); }); + palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); }); + palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); }); + vbox.packStart(palette, false, false, 0); + Tool[] tools; tools ~= new PanTool; tools ~= new ZoomTool; tools ~= new LassoTool; - trace("Test trace4"); auto toolLayer = new ToolLayer(tools, "Tools"); + auto gridLayer = new GridLayer("Grid"); + Layer[] layers; - trace("Test trace5"); layers ~= new PageLayer("Page"); layers ~= gridLayer; layers ~= toolLayer; - trace("Test trace6"); auto canvas = new Canvas(layers, toolLayer, gridLayer, 120.0); - trace("Test trace7"); + vbox.packStart(canvas, true, true, 0); - trace("Test trace8"); window.add(vbox); - trace("Test trace9"); window.setDefaultSize(380, 380); window.showAll(); - trace("Test trace8"); Main.run(); } diff -r 576b9fba4677 -r fbabd1957c89 doodle/tk/geometry.d --- a/doodle/tk/geometry.d Thu Aug 05 22:49:41 2010 +0930 +++ b/doodle/tk/geometry.d Fri Aug 06 09:38:36 2010 +0930 @@ -24,15 +24,9 @@ // struct Point { - static immutable Point DEFAULT; - - static this() { - DEFAULT = Point(0.0, 0.0); - } + static immutable Point DEFAULT = Point(0.0, 0.0); this(in double x, in double y) { - assert(!isnan(x)); - assert(!isnan(y)); _x = x; _y = y; } @@ -74,15 +68,9 @@ // struct Vector { - static Vector DEFAULT; - - static this() { - DEFAULT = Vector(0.0, 0.0); - } + static Vector DEFAULT = Vector(0.0, 0.0); this(in double x, in double y) { - assert(!isnan(x)); - assert(!isnan(y)); _x = x; _y = y; } @@ -344,7 +332,7 @@ } private { - Point _point; // Arbitrary point along line + Point _point; // Arbitrary point along line Vector _gradient; } } diff -r 576b9fba4677 -r fbabd1957c89 doodle/tk/palette.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doodle/tk/palette.d Fri Aug 06 09:38:36 2010 +0930 @@ -0,0 +1,7 @@ +module doodle.tk.palette; + +interface IPalette { + int add(in string iconPath, in string tooltipText, void delegate(int) dg); + void remove(in int id); + void activate(in int id); +}