diff --git a/src/jinete/jaccel.c b/src/jinete/jaccel.c index 5d46440f0..75aa5fd31 100644 --- a/src/jinete/jaccel.c +++ b/src/jinete/jaccel.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -91,6 +91,7 @@ void jaccel_free(JAccel accel) jfree(link->data); } jlist_free(accel->key_list); + jfree(accel); } void jaccel_add_key(JAccel accel, int shifts, int ascii, int scancode) diff --git a/src/jinete/jbase.h b/src/jinete/jbase.h index 300d26b33..6bf8a0bfc 100644 --- a/src/jinete/jbase.h +++ b/src/jinete/jbase.h @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -254,12 +254,11 @@ typedef struct jxmltext *JXmlText; typedef bool (*JMessageFunc) (JWidget widget, JMessage msg); typedef void (*JDrawFunc) (JWidget widget); -/* memory routines */ +/* without leak detection */ void *jmalloc (unsigned long n_bytes); void *jmalloc0(unsigned long n_bytes); void *jrealloc(void *mem, unsigned long n_bytes); void jfree (void *mem); - char *jstrdup (const char *string); #define jnew(struct_type, n_structs) \ diff --git a/src/jinete/jcombox.c b/src/jinete/jcombox.c index 98ea960a8..6260b9d36 100644 --- a/src/jinete/jcombox.c +++ b/src/jinete/jcombox.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -430,10 +430,10 @@ static bool combobox_listbox_msg_proc(JWidget widget, JMessage msg) { int index = jcombobox_get_selected_index(combo_widget); + combobox_close_window(combo_widget); + if (IS_VALID_ITEM(combo_widget, index)) jwidget_emit_signal(combo_widget, JI_SIGNAL_COMBOBOX_SELECT); - - combobox_close_window(combo_widget); } return TRUE; diff --git a/src/jinete/jfile.c b/src/jinete/jfile.c index 78ebdfee6..9dcfed7d6 100644 --- a/src/jinete/jfile.c +++ b/src/jinete/jfile.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -312,6 +312,7 @@ static JWidget convert_tag_to_widget(Tag *tag) /* the widget was created? */ if (widget) { Attr *name = tag_get_attr(tag, "name"); + Attr *tooltip = tag_get_attr(tag, "tooltip"); Attr *expansive = tag_get_attr(tag, "expansive"); Attr *magnetic = tag_get_attr(tag, "magnetic"); Attr *noborders = tag_get_attr(tag, "noborders"); @@ -326,6 +327,9 @@ static JWidget convert_tag_to_widget(Tag *tag) if (name) jwidget_set_name(widget, name->value); + if (tooltip) + jwidget_add_tooltip_text(widget, tooltip->value); + if (expansive) jwidget_expansive(widget, TRUE); @@ -580,7 +584,7 @@ static Tag *tag_new_from_string(char *tag_string) bool go_next = FALSE; /* see for the translation prefix _() */ - if (strncmp (s, "_(\"", 3) == 0) { + if (strncmp(s, "_(\"", 3) == 0) { translatable = TRUE; s += 2; } @@ -593,6 +597,11 @@ static Tag *tag_new_from_string(char *tag_string) while (*s) { if (*s == '\\') { memmove(s, s+1, strlen(s)-1); + switch (*s) { + case 'n': *s = '\n'; break; + case 'r': *s = '\r'; break; + case 't': *s = '\t'; break; + } } else if (*s == '\"') { go_next = TRUE; diff --git a/src/jinete/jfile.h b/src/jinete/jfile.h index b7ab307cc..58d21ce45 100644 --- a/src/jinete/jfile.h +++ b/src/jinete/jfile.h @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/jinete/jimage.c b/src/jinete/jimage.c index 9e42f4ff2..8726963e0 100644 --- a/src/jinete/jimage.c +++ b/src/jinete/jimage.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/jinete/jimage.h b/src/jinete/jimage.h index 4749d6dcb..13d679d27 100644 --- a/src/jinete/jimage.h +++ b/src/jinete/jimage.h @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/jinete/jinete.h b/src/jinete/jinete.h index 218967c86..834d96535 100644 --- a/src/jinete/jinete.h +++ b/src/jinete/jinete.h @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,6 +65,7 @@ #include "jinete/jtextbox.h" #include "jinete/jtheme.h" #include "jinete/jthread.h" +#include "jinete/jtooltips.h" #include "jinete/jview.h" #include "jinete/jwidget.h" #include "jinete/jwindow.h" diff --git a/src/jinete/jintern.h b/src/jinete/jintern.h index d1c71b0b6..faff7eeae 100644 --- a/src/jinete/jintern.h +++ b/src/jinete/jintern.h @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,7 +98,8 @@ void _ji_theme_rectfill_exclude(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int ex1, int ey1, int ex2, int ey2, int color); -void _ji_theme_textbox_draw(struct BITMAP *bmp, JWidget textbox, int *w, int *h); +void _ji_theme_textbox_draw(struct BITMAP *bmp, JWidget textbox, + int *w, int *h, int bg, int fg); /**********************************************************************/ /* jfontbmp.c */ diff --git a/src/jinete/jlist.c b/src/jinete/jlist.c index bd1bce4e7..c61ce247a 100644 --- a/src/jinete/jlist.c +++ b/src/jinete/jlist.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,6 +85,7 @@ void jlist_free(JList list) JI_LIST_FOR_EACH_SAFE(list, link, next) { jlink_free(link); } + jlink_free(list->end); jfree(list); } @@ -166,7 +167,7 @@ void jlist_insert_before(JList list, JLink sibling, void *data) void jlist_remove(JList list, const void *data) { - JLink link, prev = list->end; + JLink link; JI_LIST_FOR_EACH(list, link) { if (link->data == data) { link->prev->next = link->next; @@ -175,13 +176,12 @@ void jlist_remove(JList list, const void *data) list->length--; return; } - prev = link; } } void jlist_remove_all(JList list, const void *data) { - JLink link, next, prev = list->end; + JLink link, next; JI_LIST_FOR_EACH_SAFE(list, link, next) { if (link->data == data) { link->prev->next = link->next; @@ -189,8 +189,6 @@ void jlist_remove_all(JList list, const void *data) jlink_free(link); list->length--; } - else - prev = link; } } diff --git a/src/jinete/jmanager.c b/src/jinete/jmanager.c index ddaae2046..a440745b9 100644 --- a/src/jinete/jmanager.c +++ b/src/jinete/jmanager.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -216,9 +216,6 @@ void jmanager_free(JWidget widget) /* no more cursor */ jmouse_set_cursor(JI_CURSOR_NULL); - /* TODO destroy the AUTODESTROY windows in these lists */ - jlist_free(new_windows); - /* destroy filters */ for (c=0; cany.widgets); sub_msg->any.widgets = jlist_copy(msg->any.widgets); jmessage_set_sub_msg(msg, sub_msg); @@ -928,8 +930,10 @@ void jmanager_remove_msg_filter(int message, JWidget widget) JI_LIST_FOR_EACH_SAFE(msg_filters[c], link, next) { Filter *filter = link->data; - if (filter->widget == widget) + if (filter->widget == widget) { + filter_free(filter); jlist_delete_link(msg_filters[c], link); + } } } @@ -938,10 +942,13 @@ void _jmanager_open_window(JWidget manager, JWidget window) { JMessage msg; + /* TODO check if this is necessary... */ /* free all widgets of special states */ - jmanager_free_capture(); - jmanager_free_mouse(); - jmanager_free_focus(); + if (jwindow_is_wantfocus(window)) { + jmanager_free_capture(); + jmanager_free_mouse(); + jmanager_free_focus(); + } /* add the window to manager */ jlist_prepend(manager->children, window); diff --git a/src/jinete/jmem.c b/src/jinete/jmem.c index f7d9765b9..bfaaab2f7 100644 --- a/src/jinete/jmem.c +++ b/src/jinete/jmem.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,10 +29,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include +#include "jinete/jbase.h" +#include "jinete/jmutex.h" + +#if !defined MEMLEAK + +/**********************************************************************/ +/* with outleak detection */ +/**********************************************************************/ + void *jmalloc(unsigned long n_bytes) { if (n_bytes) { @@ -62,13 +72,13 @@ void *jmalloc0(unsigned long n_bytes) void *jrealloc(void *mem, unsigned long n_bytes) { if (n_bytes) { - mem = realloc(mem, n_bytes); - if (mem) - return mem; + void *newmem = realloc(mem, n_bytes); + if (newmem) + return newmem; } if (mem) - free(mem); + jfree(mem); return NULL; } @@ -84,3 +94,149 @@ char *jstrdup(const char *string) return ustrdup(string); } +#else + +/**********************************************************************/ +/* with leak detection */ +/**********************************************************************/ + +typedef struct slot_t +{ + void *backtrace[4]; + void *ptr; + unsigned long size; + struct slot_t *next; +} slot_t; + +static slot_t *headslot; +static JMutex mutex; + +void jmemleak_init() +{ + headslot = NULL; + mutex = jmutex_new(); +} + +void jmemleak_exit() +{ + FILE *f = fopen("_ase_memlog.txt", "wt"); + slot_t *it; + + if (f) { + /* memory leaks */ + for (it=headslot; it!=NULL; it=it->next) { + fprintf(f, + "Leak:\n%p\n%p\n%p\n%p\nptr: %p, size: %lu\n", + it->backtrace[0], + it->backtrace[1], + it->backtrace[2], + it->backtrace[3], + it->ptr, it->size); + } + fclose(f); + } + + jmutex_free(mutex); +} + +static void addslot(void *ptr, unsigned long size) +{ + slot_t *p = malloc(sizeof(slot_t)); + + p->backtrace[0] = __builtin_return_address(4); /* a GCC extension */ + p->backtrace[1] = __builtin_return_address(3); + p->backtrace[2] = __builtin_return_address(2); + p->backtrace[3] = __builtin_return_address(1); + p->ptr = ptr; + p->size = size; + p->next = headslot; + + jmutex_lock(mutex); + headslot = p; + jmutex_unlock(mutex); +} + +static void delslot(void *ptr) +{ + slot_t *it, *prev = NULL; + + jmutex_lock(mutex); + + for (it=headslot; it!=NULL; prev=it, it=it->next) { + if (it->ptr == ptr) { + if (prev) + prev->next = it->next; + else + headslot = it->next; + + free(it); + break; + } + } + + jmutex_unlock(mutex); +} + +void *jmalloc(unsigned long n_bytes) +{ + if (n_bytes) { + void *mem; + + mem = malloc(n_bytes); + if (mem) { + addslot(mem, n_bytes); + return mem; + } + } + + return NULL; +} + +void *jmalloc0(unsigned long n_bytes) +{ + if (n_bytes) { + void *mem; + + mem = calloc(1, n_bytes); + if (mem) { + addslot(mem, n_bytes); + return mem; + } + } + + return NULL; +} + +void *jrealloc(void *mem, unsigned long n_bytes) +{ + if (n_bytes) { + void *newmem = realloc(mem, n_bytes); + if (newmem) { + if (mem) delslot(mem); + addslot(newmem, n_bytes); + return newmem; + } + } + + if (mem) + jfree(mem); + + return NULL; +} + +void jfree(void *mem) +{ + delslot(mem); + if (mem) + free(mem); +} + +char *jstrdup(const char *string) +{ + void *mem = ustrdup(string); + if (mem) + addslot(mem, strlen(mem)); + return mem; +} + +#endif diff --git a/src/jinete/jmenu.c b/src/jinete/jmenu.c index 78be1e628..eabe66855 100644 --- a/src/jinete/jmenu.c +++ b/src/jinete/jmenu.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,8 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include #include #include #include @@ -370,20 +369,22 @@ static bool menu_msg_proc(JWidget widget, JMessage msg) { switch (msg->type) { - case JM_DESTROY: - assert(MENU(widget) != NULL); + case JM_DESTROY: { + Menu *menu = MENU(widget); + assert(menu != NULL); - if (MENU(widget)->menuitem) { - if (MITEM(MENU(widget)->menuitem)->submenu == widget) { - MITEM(MENU(widget)->menuitem)->submenu = NULL; + if (menu->menuitem) { + if (MITEM(menu->menuitem)->submenu == widget) { + MITEM(menu->menuitem)->submenu = NULL; } else { - assert(MITEM(MENU(widget)->menuitem)->submenu == NULL); + assert(MITEM(menu->menuitem)->submenu == NULL); } } - jfree(MENU(widget)); + jfree(menu); break; + } case JM_REQSIZE: menu_request_size(widget, &msg->reqsize.w, &msg->reqsize.h); diff --git a/src/jinete/jtextbox.c b/src/jinete/jtextbox.c index f02aa8909..0ddc991b8 100644 --- a/src/jinete/jtextbox.c +++ b/src/jinete/jtextbox.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -196,7 +196,7 @@ static void textbox_request_size(JWidget widget, int *w, int *h) *w = 0; *h = 0; - _ji_theme_textbox_draw(NULL, widget, w, h); + _ji_theme_textbox_draw(NULL, widget, w, h, 0, 0); if (widget->align & JI_WORDWRAP) { JWidget view = jwidget_get_view(widget); @@ -212,7 +212,7 @@ static void textbox_request_size(JWidget widget, int *w, int *h) } *w = MAX(min, width); - _ji_theme_textbox_draw(NULL, widget, w, h); + _ji_theme_textbox_draw(NULL, widget, w, h, 0, 0); *w = min; } diff --git a/src/jinete/jtheme.c b/src/jinete/jtheme.c index 4ff8e6e5e..9a134ea08 100644 --- a/src/jinete/jtheme.c +++ b/src/jinete/jtheme.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -295,15 +295,14 @@ void _ji_theme_rectfill_exclude(BITMAP *bmp, } } -void _ji_theme_textbox_draw(BITMAP *bmp, JWidget widget, int *w, int *h) +void _ji_theme_textbox_draw(BITMAP *bmp, JWidget widget, + int *w, int *h, int bg, int fg) { JWidget view = jwidget_get_view(widget); char *text = widget->text; int x1, y1, x2, y2; int x, y, chr, len; char *beg, *end; - int bg = widget->theme->textbox_bg_color; - int fg = widget->theme->textbox_fg_color; int scroll_x, scroll_y; int viewport_w, viewport_h; int textheight = jwidget_get_text_height(widget); @@ -321,10 +320,10 @@ void _ji_theme_textbox_draw(BITMAP *bmp, JWidget widget, int *w, int *h) jrect_free(vp); } else { - x1 = widget->rc->x1; - y1 = widget->rc->y1; - viewport_w = jrect_w(widget->rc); - viewport_h = jrect_h(widget->rc); + x1 = widget->rc->x1 + widget->border_width.l; + y1 = widget->rc->y1 + widget->border_width.t; + viewport_w = jrect_w(widget->rc) - widget->border_width.l - widget->border_width.r; + viewport_h = jrect_h(widget->rc) - widget->border_width.t - widget->border_width.b; scroll_x = scroll_y = 0; } x2 = x1+viewport_w-1; @@ -448,8 +447,11 @@ void _ji_theme_textbox_draw(BITMAP *bmp, JWidget widget, int *w, int *h) if (h) *h = (y-y1+scroll_y); + if (w) *w += widget->border_width.l + widget->border_width.r; + if (h) *h += widget->border_width.t + widget->border_width.b; + + /* fill bottom area */ if (bmp) { - /* fill bottom area */ if (y <= y2) rectfill(bmp, x1, y, x2, y2, bg); } diff --git a/src/jinete/themes/jstandard_theme.c b/src/jinete/themes/jstandard_theme.c index 452ee9575..1fdab3a65 100644 --- a/src/jinete/themes/jstandard_theme.c +++ b/src/jinete/themes/jstandard_theme.c @@ -1,5 +1,5 @@ /* Jinete - a GUI library - * Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello. + * Copyright (C) 2003-2008 David A. Capello. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -388,7 +388,7 @@ static void theme_init_widget(JWidget widget) break; case JI_TEXTBOX: - BORDER(2); + BORDER(0); widget->child_spacing = 0; break; @@ -1161,7 +1161,9 @@ static void theme_draw_slider(JWidget widget) static void theme_draw_textbox(JWidget widget) { - _ji_theme_textbox_draw(ji_screen, widget, NULL, NULL); + _ji_theme_textbox_draw(ji_screen, widget, NULL, NULL, + widget->theme->textbox_bg_color, + widget->theme->textbox_fg_color); } static void theme_draw_view(JWidget widget)