Fri Sep 1 21:03:53 PDT 2000 Michael Jennings <mej@eterm.org>

I'm working on some deallocators now.  The idea is that when Eterm
	exits and memory debugging is on, several routines get called to free
	the in-use memory (menus, font cache, etc.) that we still know about.
	Anything left after that would be either unavoidable leaks (like
	environment variables...read the putenv() man page sometime...sigh)
	or genuine memory leaks that need fixing.  I'm down to about 4.5K of
	leftover malloc'd memory now.  Making progress....


SVN revision: 3295
This commit is contained in:
Michael Jennings 2000-09-02 04:12:16 +00:00
parent e1573e95c8
commit c567ebcf33
14 changed files with 292 additions and 120 deletions

View File

@ -3875,3 +3875,14 @@ Fri Sep 1 15:25:28 PDT 2000 Michael Jennings <mej@eterm.org>
shot.
-------------------------------------------------------------------------------
Fri Sep 1 21:03:53 PDT 2000 Michael Jennings <mej@eterm.org>
I'm working on some deallocators now. The idea is that when Eterm
exits and memory debugging is on, several routines get called to free
the in-use memory (menus, font cache, etc.) that we still know about.
Anything left after that would be either unavoidable leaks (like
environment variables...read the putenv() man page sometime...sigh)
or genuine memory leaks that need fixing. I'm down to about 4.5K of
leftover malloc'd memory now. Making progress....
-------------------------------------------------------------------------------

View File

@ -98,6 +98,9 @@
#define FIXME_NOP(x)
#define FIXME_BLOCK 0
/* An "unused block" marker similar to the above. */
#define UNUSED_BLOCK 0
/* The basic debugging output leader. */
#if defined(__FILE__) && defined(__LINE__)
# ifdef __GNUC__

View File

@ -7,3 +7,4 @@ for i in *.c src/*.c utils/*.c ; do
fi
done
perl -p -i.bak -e 's/(\w+)_t (\*+)\s+/$1_t ($2)/g;' */*.[ch]

View File

@ -137,7 +137,7 @@ bbar_event_init_dispatcher(void)
}
unsigned char
bbar_handle_enter_notify(event_t * ev)
bbar_handle_enter_notify(event_t *ev)
{
button_t *b;
Window unused_root, unused_child;
@ -158,7 +158,7 @@ bbar_handle_enter_notify(event_t * ev)
}
unsigned char
bbar_handle_leave_notify(event_t * ev)
bbar_handle_leave_notify(event_t *ev)
{
D_EVENTS(("bbar_handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -172,7 +172,7 @@ bbar_handle_leave_notify(event_t * ev)
}
unsigned char
bbar_handle_button_press(event_t * ev)
bbar_handle_button_press(event_t *ev)
{
D_EVENTS(("bbar_handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -187,7 +187,7 @@ bbar_handle_button_press(event_t * ev)
}
unsigned char
bbar_handle_button_release(event_t * ev)
bbar_handle_button_release(event_t *ev)
{
button_t *b;
Window unused_root, unused_child;
@ -214,7 +214,7 @@ bbar_handle_button_release(event_t * ev)
}
unsigned char
bbar_handle_motion_notify(event_t * ev)
bbar_handle_motion_notify(event_t *ev)
{
button_t *b;
Window unused_root, unused_child;
@ -247,7 +247,7 @@ bbar_handle_motion_notify(event_t * ev)
}
unsigned char
bbar_dispatch_event(event_t * ev)
bbar_dispatch_event(event_t *ev)
{
if (buttonbar->event_data.handlers[ev->type] != NULL) {
return ((buttonbar->event_data.handlers[ev->type]) (ev));
@ -587,7 +587,7 @@ button_create(char *text)
}
unsigned char
button_set_icon(button_t *button, simage_t * icon)
button_set_icon(button_t *button, simage_t *icon)
{
ASSERT_RVAL(button != NULL, 0);
ASSERT_RVAL(icon != NULL, 0);

View File

@ -116,7 +116,7 @@ extern unsigned char bbar_set_font(buttonbar_t *bbar, const char *fontname);
extern button_t *find_button_by_text(buttonbar_t *bbar, char *text);
extern button_t *find_button_by_coords(buttonbar_t *bbar, int x, int y);
extern button_t *button_create(char *text);
extern unsigned char button_set_icon(button_t *button, simage_t * icon);
extern unsigned char button_set_icon(button_t *button, simage_t *icon);
extern unsigned char button_set_action(button_t *button, action_type_t type, char *action);
extern void bbar_select_button(buttonbar_t *bbar, button_t *button);
extern void bbar_deselect_button(buttonbar_t *bbar, button_t *button);

View File

@ -1119,7 +1119,16 @@ install_handlers(void)
void
clean_exit(void)
{
scr_release();
#if DEBUG >= DEBUG_MEM
if (DEBUG_LEVEL >= DEBUG_MEM) {
/* Deallocate all our crap to help find memory leaks */
scr_release();
menulist_clear(menu_list);
font_cache_clear();
eterm_font_list_clear();
}
#endif
privileges(INVOKE);
#ifndef __CYGWIN32__
@ -1471,7 +1480,7 @@ get_tty(void)
} while (0)
# define SHOW_CONT_CHAR(entry, name) fprintf(stderr, "%s=%#3o ", name, ttymode->c_cc[entry])
static void
debug_ttymode(ttymode_t * ttymode)
debug_ttymode(ttymode_t *ttymode)
{
/* c_iflag bits */
@ -1541,7 +1550,7 @@ debug_ttymode(ttymode_t * ttymode)
/* get_ttymode() */
static void
get_ttymode(ttymode_t * tio)
get_ttymode(ttymode_t *tio)
{
#ifdef HAVE_TERMIOS_H
/*

View File

@ -77,7 +77,7 @@ event_register_dispatcher(event_dispatcher_t func, event_dispatcher_init_t init)
}
void
event_dispatch(event_t * event)
event_dispatch(event_t *event)
{
register unsigned char i;
@ -93,7 +93,7 @@ event_dispatch(event_t * event)
}
void
event_data_add_mywin(event_dispatcher_data_t * data, Window win)
event_data_add_mywin(event_dispatcher_data_t *data, Window win)
{
ASSERT(data != NULL);
@ -110,7 +110,7 @@ event_data_add_mywin(event_dispatcher_data_t * data, Window win)
}
void
event_data_add_parent(event_dispatcher_data_t * data, Window win)
event_data_add_parent(event_dispatcher_data_t *data, Window win)
{
ASSERT(data != NULL);
@ -163,7 +163,7 @@ event_init_primary_dispatcher(void)
}
unsigned char
event_win_is_mywin(register event_dispatcher_data_t * data, Window win)
event_win_is_mywin(register event_dispatcher_data_t *data, Window win)
{
register unsigned short i;
@ -179,7 +179,7 @@ event_win_is_mywin(register event_dispatcher_data_t * data, Window win)
}
unsigned char
event_win_is_parent(register event_dispatcher_data_t * data, Window win)
event_win_is_parent(register event_dispatcher_data_t *data, Window win)
{
register unsigned short i;
@ -195,7 +195,7 @@ event_win_is_parent(register event_dispatcher_data_t * data, Window win)
}
unsigned char
handle_key_press(event_t * ev)
handle_key_press(event_t *ev)
{
#ifdef COUNT_X_EVENTS
static unsigned long keypress_cnt = 0;
@ -215,7 +215,7 @@ handle_key_press(event_t * ev)
}
unsigned char
handle_property_notify(event_t * ev)
handle_property_notify(event_t *ev)
{
Atom prop;
@ -281,7 +281,7 @@ handle_property_notify(event_t * ev)
}
unsigned char
handle_destroy_notify(event_t * ev)
handle_destroy_notify(event_t *ev)
{
D_EVENTS(("handle_destroy_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -296,7 +296,7 @@ handle_destroy_notify(event_t * ev)
}
unsigned char
handle_client_message(event_t * ev)
handle_client_message(event_t *ev)
{
D_EVENTS(("handle_client_message(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -337,7 +337,7 @@ handle_client_message(event_t * ev)
}
unsigned char
handle_mapping_notify(event_t * ev)
handle_mapping_notify(event_t *ev)
{
D_EVENTS(("handle_mapping_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -348,7 +348,7 @@ handle_mapping_notify(event_t * ev)
}
unsigned char
handle_visibility_notify(event_t * ev)
handle_visibility_notify(event_t *ev)
{
D_EVENTS(("handle_visibility_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -372,7 +372,7 @@ handle_visibility_notify(event_t * ev)
}
unsigned char
handle_enter_notify(event_t * ev)
handle_enter_notify(event_t *ev)
{
D_EVENTS(("handle_enter_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -390,7 +390,7 @@ handle_enter_notify(event_t * ev)
}
unsigned char
handle_leave_notify(event_t * ev)
handle_leave_notify(event_t *ev)
{
D_EVENTS(("handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -408,7 +408,7 @@ handle_leave_notify(event_t * ev)
}
unsigned char
handle_focus_in(event_t * ev)
handle_focus_in(event_t *ev)
{
D_EVENTS(("handle_focus_in(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -449,7 +449,7 @@ handle_focus_in(event_t * ev)
}
unsigned char
handle_focus_out(event_t * ev)
handle_focus_out(event_t *ev)
{
D_EVENTS(("handle_focus_out(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -477,7 +477,7 @@ handle_focus_out(event_t * ev)
}
unsigned char
handle_configure_notify(event_t * ev)
handle_configure_notify(event_t *ev)
{
D_EVENTS(("handle_configure_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -520,7 +520,7 @@ handle_configure_notify(event_t * ev)
}
unsigned char
handle_selection_clear(event_t * ev)
handle_selection_clear(event_t *ev)
{
D_EVENTS(("handle_selection_clear(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -530,7 +530,7 @@ handle_selection_clear(event_t * ev)
}
unsigned char
handle_selection_notify(event_t * ev)
handle_selection_notify(event_t *ev)
{
D_EVENTS(("handle_selection_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -540,7 +540,7 @@ handle_selection_notify(event_t * ev)
}
unsigned char
handle_selection_request(event_t * ev)
handle_selection_request(event_t *ev)
{
D_EVENTS(("handle_selection_request(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -550,7 +550,7 @@ handle_selection_request(event_t * ev)
}
unsigned char
handle_expose(event_t * ev)
handle_expose(event_t *ev)
{
PROF_INIT(handle_expose);
D_EVENTS(("handle_expose(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -578,7 +578,7 @@ handle_expose(event_t * ev)
}
unsigned char
handle_button_press(event_t * ev)
handle_button_press(event_t *ev)
{
D_EVENTS(("handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -662,7 +662,7 @@ handle_button_press(event_t * ev)
}
unsigned char
handle_button_release(event_t * ev)
handle_button_release(event_t *ev)
{
D_EVENTS(("handle_button_release(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -715,7 +715,7 @@ handle_button_release(event_t * ev)
}
unsigned char
handle_motion_notify(event_t * ev)
handle_motion_notify(event_t *ev)
{
#ifdef COUNT_X_EVENTS
static unsigned long motion_cnt = 0;
@ -754,7 +754,7 @@ handle_motion_notify(event_t * ev)
}
unsigned char
process_x_event(event_t * ev)
process_x_event(event_t *ev)
{
#ifdef COUNT_X_EVENTS
static unsigned long event_cnt = 0;

View File

@ -59,18 +59,23 @@ static cachefont_t *font_cache_find(const char *name, unsigned char type);
static void *font_cache_find_info(const char *name, unsigned char type);
static unsigned char get_corner(const char *corner);
/* The eterm_font_(add|delete) functions keep track of the names of the terminal fonts
as defined in the attributes/multicharset contexts. They do NOT call the cache
routines. The caller is responsible for adding/removing fonts to/from the cache. */
void
eterm_font_add(char ***plist, const char *fontname, unsigned char idx) {
char **flist;
D_FONT(("Adding \"%s\" at %u (%8p)\n", NONULL(fontname), (unsigned int) idx, plist));
ASSERT(plist != NULL);
flist = *plist;
ASSERT(plist != NULL); /* plist is the address of either etfonts or etmfonts */
/* If we're adding the font at an index we don't have yet, we must resize to fit it. */
if (idx >= font_cnt) {
unsigned char new_size = sizeof(char *) * (idx + 1);
/* The below looks messy with all the cpp stuff, but it really just malloc's/realloc's
both etfonts and etmfonts at the same time to the same size, then prints some goop. */
if (etfonts) {
etfonts = (char **) REALLOC(etfonts, new_size);
#ifdef MULTI_CHARSET
@ -88,22 +93,25 @@ eterm_font_add(char ***plist, const char *fontname, unsigned char idx) {
D_FONT((" -> Allocating font list: %u bytes at %8p\n", new_size, etfonts));
#endif
}
/* Initialize the new memory so we don't think it's got valid font info. */
MEMSET(etfonts + font_cnt, 0, sizeof(char *) * (idx - font_cnt + 1));
#ifdef MULTI_CHARSET
MEMSET(etmfonts + font_cnt, 0, sizeof(char *) * (idx - font_cnt + 1));
#endif
font_cnt = idx + 1;
font_cnt = idx + 1; /* Update the font count. */
#ifdef MULTI_CHARSET
flist = ((plist == &etfonts) ? (etfonts) : (etmfonts));
#else
flist = etfonts;
#endif
} else {
flist = *plist;
if (flist[idx]) {
if ((flist[idx] == fontname) || (!strcasecmp(flist[idx], fontname))) {
return;
return; /* We've already got the right font. */
}
FREE(flist[idx]);
FREE(flist[idx]); /* We're replacing an old font. Get rid of the old name. */
}
}
flist[idx] = STRDUP(fontname);
@ -121,6 +129,25 @@ eterm_font_delete(char **flist, unsigned char idx) {
flist[idx] = NULL;
}
void
eterm_font_list_clear(void)
{
unsigned char idx;
for (idx = 0; idx < font_cnt; idx++) {
eterm_font_delete(etfonts, idx);
#ifdef MULTI_CHARSET
eterm_font_delete(etmfonts, idx);
#endif
}
FREE(etfonts);
#ifdef MULTI_CHARSET
FREE(etmfonts);
#endif
}
/* These font caching routines keep track of all the various fonts we allocate
in the X server so that we only allocate each font once. Saves memory. */
static void
font_cache_add(const char *name, unsigned char type, void *info) {
@ -128,6 +155,7 @@ font_cache_add(const char *name, unsigned char type, void *info) {
D_FONT(("font_cache_add(%s, %d, %8p) called.\n", NONULL(name), type, info));
/* Allocate the cache info for the font and store the data */
font = (cachefont_t *) MALLOC(sizeof(cachefont_t));
font->name = STRDUP(name);
font->type = type;
@ -139,6 +167,8 @@ font_cache_add(const char *name, unsigned char type, void *info) {
default: break;
}
D_FONT((" -> Created new cachefont_t struct at %p: \"%s\", %d, %p\n", font, font->name, font->type, font->fontinfo.xfontinfo));
/* Actually add the struct to the end of our cache linked list. */
if (font_cache == NULL) {
font_cache = cur_font = font;
font->next = NULL;
@ -162,10 +192,13 @@ font_cache_del(const void *info) {
D_FONT(("font_cache_del(%8p) called.\n", info));
if (font_cache == NULL) {
return;
return; /* No fonts in the cache. Theoretically this should never happen, but... */
}
/* Check the very first entry for a match. It's a special case. */
if (((font_cache->type == FONT_TYPE_X) && (font_cache->fontinfo.xfontinfo == (XFontStruct *) info))) {
D_FONT((" -> Match found at font_cache (%8p). Font name is \"%s\"\n", font_cache, NONULL(font_cache->name)));
/* We've got a match. Decrement the reference count, and if it goes to 0, remove it from the cache. */
if (--(font_cache->ref_cnt) == 0) {
D_FONT((" -> Reference count is now 0. Deleting from cache.\n"));
current = font_cache;
@ -177,9 +210,13 @@ font_cache_del(const void *info) {
D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
}
return;
#if UNUSED_BLOCK
} else if ((font_cache->type == FONT_TYPE_TTF) && (0)) {
} else if ((font_cache->type == FONT_TYPE_FNLIB) && (0)) {
#endif
} else {
/* Search for a match. We test current->next, not current, so that we can
update the "next" pointer of the font prior to the one we're actually deleting. */
for (current = font_cache; current->next; current = current->next) {
if (((current->next->type == FONT_TYPE_X) && (current->next->fontinfo.xfontinfo == (XFontStruct *) info))) {
D_FONT((" -> Match found at current->next (%8p, current == %8p). Font name is \"%s\"\n", current->next, current, NONULL(current->next->name)));
@ -197,11 +234,37 @@ font_cache_del(const void *info) {
D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
}
return;
#if UNUSED_BLOCK
} else if ((current->next->type == FONT_TYPE_TTF) && (0)) {
} else if ((current->next->type == FONT_TYPE_FNLIB) && (0)) {
#endif
}
}
}
/* If we get here, there was no match. No big deal. */
}
void
font_cache_clear(void)
{
cachefont_t *current, *tmp;
D_FONT(("Clearing the font cache.\n"));
for (current = font_cache; current; ) {
D_FONT((" -> Deleting \"%s\" from cache.\n", current->name));
tmp = current;
current = current->next;
if (tmp->type == FONT_TYPE_X) {
XFreeFont(Xdisplay, (XFontStruct *) tmp->fontinfo.xfontinfo);
FREE(tmp->name);
FREE(tmp);
#if UNUSED_BLOCK
} else if (current->next->type == FONT_TYPE_TTF) {
} else if (current->next->type == FONT_TYPE_FNLIB) {
#endif
}
}
font_cache = cur_font = NULL;
}
static cachefont_t *
@ -213,6 +276,7 @@ font_cache_find(const char *name, unsigned char type) {
D_FONT(("font_cache_find(%s, %d) called.\n", NONULL(name), type));
/* Find a matching name/type in the cache. Just a search; no reference counting happens here. */
for (current = font_cache; current; current = current->next) {
D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name)));
if ((current->type == type) && !strcasecmp(current->name, name)) {
@ -233,6 +297,7 @@ font_cache_find_info(const char *name, unsigned char type) {
D_FONT(("font_cache_find_info(%s, %d) called.\n", NONULL(name), type));
/* This is also a simple search, but it returns the fontinfo rather than the cache entry. */
for (current = font_cache; current; current = current->next) {
D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name)));
if ((current->type == type) && !strcasecmp(current->name, name)) {
@ -249,6 +314,7 @@ font_cache_find_info(const char *name, unsigned char type) {
return (NULL);
}
/* load_font() is the function that should be used to allocate fonts. */
void *
load_font(const char *name, const char *fallback, unsigned char type)
{
@ -258,9 +324,12 @@ load_font(const char *name, const char *fallback, unsigned char type)
D_FONT(("load_font(%s, %s, %d) called.\n", NONULL(name), NONULL(fallback), type));
/* Default type is X font. */
if (type == 0) {
type = FONT_TYPE_X;
}
/* Specify some sane fallbacks */
if (name == NULL) {
if (fallback) {
name = fallback;
@ -278,6 +347,8 @@ load_font(const char *name, const char *fallback, unsigned char type)
}
D_FONT((" -> Using name == \"%s\" and fallback == \"%s\"\n", name, fallback));
/* Look for the font name in the cache. If it's there, add one to the
reference count and return the existing fontinfo pointer to the caller. */
if ((font = font_cache_find(name, type)) != NULL) {
font_cache_add_ref(font);
D_FONT((" -> Font found in cache. Incrementing reference count to %d and returning existing data.\n", font->ref_cnt));
@ -288,6 +359,8 @@ load_font(const char *name, const char *fallback, unsigned char type)
default: return (NULL); break;
}
}
/* No match in the cache, so we'll have to add it. */
if (type == FONT_TYPE_X) {
if ((xfont = XLoadQueryFont(Xdisplay, name)) == NULL) {
print_error("Unable to load font \"%s\". Falling back on \"%s\"\n", name, fallback);
@ -300,23 +373,26 @@ load_font(const char *name, const char *fallback, unsigned char type)
font_cache_add(name, type, (void *) xfont);
}
return ((void *) xfont);
#if UNUSED_BLOCK
} else if (type == FONT_TYPE_TTF) {
return (NULL);
} else if (type == FONT_TYPE_FNLIB) {
return (NULL);
#endif
}
ASSERT_NOTREACHED_RVAL(NULL);
}
/* free_font() is the external function for deallocating fonts. */
void
free_font(const void *info)
{
ASSERT(info != NULL);
font_cache_del(info);
}
/* change_font() handles the font changing escape sequences. It's also called to
initialize the terminal fonts (loading and setting up size hints/info).*/
void
change_font(int init, const char *fontname)
{
@ -340,12 +416,13 @@ change_font(int init, const char *fontname)
ASSERT(fontname != NULL);
switch (*fontname) {
/* Empty font name. Reset to default. */
case '\0':
font_idx = def_font_idx;
fontname = NULL;
break;
/* special (internal) prefix for font commands */
/* A font escape sequence. See which one it is. */
case FONT_CMD:
idx = atoi(++fontname);
switch (*fontname) {
@ -359,15 +436,18 @@ change_font(int init, const char *fontname)
default:
if (*fontname != '\0' && !isdigit(*fontname))
return;
return; /* It's not a number. Punt. */
/* Set current font to font N */
BOUND(idx, 0, (font_cnt - 1));
font_idx = idx;
break;
}
/* NULL out the fontname so we don't try to load it */
fontname = NULL;
break;
default:
/* Change to the named font. See if we already have it, and if so, just set the index. */
for (idx = 0; idx < font_cnt; idx++) {
if (!strcasecmp(etfonts[idx], fontname)) {
font_idx = idx;
@ -377,31 +457,38 @@ change_font(int init, const char *fontname)
}
break;
}
/* If we get here with a non-NULL fontname, we have to load a new font. Rats. */
if (fontname != NULL) {
eterm_font_add(&etfonts, fontname, font_idx);
} else if (font_idx == old_idx) {
/* Sigh. What a waste of time, changing to the same font. */
D_FONT((" -> Change to the same font index (%d) we had before? I don't think so.\n", font_idx));
return;
}
}
D_FONT((" -> Changing to font index %u (\"%s\")\n", (unsigned int) font_idx, NONULL(etfonts[font_idx])));
if (TermWin.font) {
/* If we have a terminal font, but it's not our new current font, free it and load the new one. */
if (font_cache_find_info(etfonts[font_idx], FONT_TYPE_X) != TermWin.font) {
free_font(TermWin.font);
TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X);
}
} else {
/* Load the new font. */
TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X);
}
#ifndef NO_BOLDFONT
if (init && rs_boldFont != NULL) {
/* If we're initializing, load the bold font too. */
boldFont = load_font(rs_boldFont, "-misc-fixed-bold-r-semicondensed--13-120-75-75-c-60-iso8859-1", FONT_TYPE_X);
}
#endif
#ifdef MULTI_CHARSET
if (TermWin.mfont) {
/* Ditto the above, but for the multi-byte fonts. */
if (font_cache_find_info(etmfonts[font_idx], FONT_TYPE_X) != TermWin.mfont) {
free_font(TermWin.mfont);
TermWin.mfont = load_font(etmfonts[font_idx], "k14", FONT_TYPE_X);
@ -410,6 +497,7 @@ change_font(int init, const char *fontname)
TermWin.mfont = load_font(etmfonts[font_idx], "k14", FONT_TYPE_X);
}
# ifdef USE_XIM
/* Changing fonts requires updating the FontSet */
if (xim_input_context) {
if (TermWin.fontset) {
XFreeFontSet(Xdisplay, TermWin.fontset);
@ -421,9 +509,11 @@ change_font(int init, const char *fontname)
#endif /* MULTI_CHARSET */
if (!init) {
/* Unless we're initializing, set the font ID in the GC to our new font. */
XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid);
}
/* Check the font dimensions to update our TermWin info */
fw = TermWin.font->min_bounds.width;
#ifdef MULTI_CHARSET
fh = (MAX((encoding_method == LATIN1 ? 0 : TermWin.mfont->ascent), TermWin.font->ascent)
@ -440,6 +530,7 @@ change_font(int init, const char *fontname)
else
TermWin.fprop = 1; /* Proportional font */
/* For proportional fonts with large size variations, do some math-fu to try and help the appearance */
if (TermWin.fprop && TermWin.font->per_char && (TermWin.font->max_bounds.width - TermWin.font->min_bounds.width >= 3)) {
int cw, n = 0, sum = 0, sumsq = 0, min_w, max_w;
unsigned int i;
@ -469,16 +560,16 @@ change_font(int init, const char *fontname)
LOWER_BOUND(fw, TermWin.font->max_bounds.width);
}
/* not the first time thru and sizes haven't changed */
/* If the sizes haven't changed, we don't have to update the hints */
if (fw == TermWin.fwidth && fh == TermWin.fheight)
return;
TermWin.fwidth = fw;
TermWin.fheight = fh;
/* check that size of boldFont is okay */
/* Check the bold font size and make sure it matches the normal font */
#ifndef NO_BOLDFONT
TermWin.boldFont = NULL;
TermWin.boldFont = NULL; /* FIXME: Memory leak? Not that anyone uses bold fonts.... */
if (boldFont != NULL) {
fw = boldFont->min_bounds.width;
@ -502,6 +593,7 @@ change_font(int init, const char *fontname)
TermWin.height = TermWin.nrow * TermWin.fheight;
D_FONT((" -> New font width/height = %ldx%ld, making the terminal size %ldx%ld\n", TermWin.fwidth, TermWin.fheight, TermWin.width, TermWin.height));
/* If we're initializing, *we* do the size hints. If not, resize the parent window. */
if (init) {
szHint.width_inc = TermWin.fwidth;
szHint.height_inc = TermWin.fheight;

View File

@ -46,6 +46,7 @@
#define SHADOW_BOTTOM_LEFT 2
#define SHADOW_BOTTOM_RIGHT 3
/* The macros are used to advance to the next/previous font as with Ctrl-> and Ctrl-< */
#define NEXT_FONT(i) do { if (font_idx + ((i)?(i):1) >= font_cnt) {font_idx = font_cnt - 1;} else {font_idx += ((i)?(i):1);} \
while (!etfonts[font_idx]) {if (font_idx == font_cnt) {font_idx--; break;} font_idx++;} } while (0)
#define PREV_FONT(i) do { if (font_idx - ((i)?(i):1) < 0) {font_idx = 0;} else {font_idx -= ((i)?(i):1);} \
@ -55,10 +56,11 @@
/************ Structures ************/
typedef struct cachefont_struct {
char *name;
unsigned char type;
unsigned char ref_cnt;
char *name; /* Font name in canonical format */
unsigned char type; /* Font type (FONT_TYPE_* from above */
unsigned char ref_cnt; /* Reference count */
union {
/* This union will eventually have members for TTF/Fnlib fonts */
XFontStruct *xfontinfo;
} fontinfo;
struct cachefont_struct *next;
@ -86,6 +88,8 @@ _XFUNCPROTOBEGIN
extern void eterm_font_add(char ***plist, const char *fontname, unsigned char idx);
extern void eterm_font_delete(char **flist, unsigned char idx);
extern void eterm_font_list_clear(void);
extern void font_cache_clear(void);
extern void *load_font(const char *, const char *, unsigned char);
extern void free_font(const void *);
extern void change_font(int, const char *);

View File

@ -156,7 +156,7 @@ menu_event_init_dispatcher(void)
}
unsigned char
menu_handle_enter_notify(event_t * ev)
menu_handle_enter_notify(event_t *ev)
{
register menu_t *menu;
@ -181,7 +181,7 @@ menu_handle_enter_notify(event_t * ev)
}
unsigned char
menu_handle_leave_notify(event_t * ev)
menu_handle_leave_notify(event_t *ev)
{
D_EVENTS(("menu_handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -195,7 +195,7 @@ menu_handle_leave_notify(event_t * ev)
}
unsigned char
menu_handle_focus_in(event_t * ev)
menu_handle_focus_in(event_t *ev)
{
D_EVENTS(("menu_handle_focus_in(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -206,7 +206,7 @@ menu_handle_focus_in(event_t * ev)
}
unsigned char
menu_handle_focus_out(event_t * ev)
menu_handle_focus_out(event_t *ev)
{
D_EVENTS(("menu_handle_focus_out(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -218,7 +218,7 @@ menu_handle_focus_out(event_t * ev)
#if 0
unsigned char
menu_handle_expose(event_t * ev)
menu_handle_expose(event_t *ev)
{
XEvent unused_xevent;
@ -234,7 +234,7 @@ menu_handle_expose(event_t * ev)
#endif
unsigned char
menu_handle_button_press(event_t * ev)
menu_handle_button_press(event_t *ev)
{
D_EVENTS(("menu_handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -270,7 +270,7 @@ menu_handle_button_press(event_t * ev)
}
unsigned char
menu_handle_button_release(event_t * ev)
menu_handle_button_release(event_t *ev)
{
menuitem_t *item;
@ -333,7 +333,7 @@ menu_handle_button_release(event_t * ev)
}
unsigned char
menu_handle_motion_notify(event_t * ev)
menu_handle_motion_notify(event_t *ev)
{
register menuitem_t *item = NULL;
@ -392,7 +392,7 @@ menu_handle_motion_notify(event_t * ev)
}
unsigned char
menu_dispatch_event(event_t * ev)
menu_dispatch_event(event_t *ev)
{
if (menu_event_data.handlers[ev->type] != NULL) {
return ((menu_event_data.handlers[ev->type]) (ev));
@ -401,9 +401,8 @@ menu_dispatch_event(event_t * ev)
}
menulist_t *
menulist_add_menu(menulist_t * list, menu_t * menu)
menulist_add_menu(menulist_t *list, menu_t *menu)
{
ASSERT_RVAL(menu != NULL, list);
if (list) {
@ -418,10 +417,25 @@ menulist_add_menu(menulist_t * list, menu_t * menu)
return list;
}
void
menulist_clear(menulist_t *list)
{
unsigned long i;
ASSERT(list != NULL);
for (i = 0; i < list->nummenus; i++) {
menu_delete(list->menus[i]);
}
FREE(list->menus);
LIBMEJ_X_FREE_GC(topShadowGC);
LIBMEJ_X_FREE_GC(botShadowGC);
FREE(list);
}
menu_t *
menu_create(char *title)
{
menu_t *menu;
static Cursor cursor;
static long mask;
@ -456,6 +470,43 @@ menu_create(char *title)
return menu;
}
void
menu_delete(menu_t *menu)
{
unsigned short i;
ASSERT(menu != NULL);
for (i = 0; i < menu->numitems; i++) {
menuitem_delete(menu->items[i]);
}
FREE(menu->items);
if (menu->title) {
FREE(menu->title);
}
if (menu->bg) {
LIBMEJ_X_FREE_PIXMAP(menu->bg);
}
if (menu->gc) {
LIBMEJ_X_FREE_GC(menu->gc);
}
#ifdef MULTI_CHARSET
if (menu->fontset) {
XFreeFontSet(Xdisplay, menu->fontset);
}
#endif
if (menu->font) {
free_font(menu->font);
}
if (menu->win) {
XDestroyWindow(Xdisplay, menu->win);
}
if (menu->swin) {
XDestroyWindow(Xdisplay, menu->swin);
}
FREE(menu);
}
unsigned char
menu_set_title(menu_t *menu, const char *title)
{
@ -469,9 +520,8 @@ menu_set_title(menu_t *menu, const char *title)
}
unsigned char
menu_set_font(menu_t * menu, const char *fontname)
menu_set_font(menu_t *menu, const char *fontname)
{
XFontStruct *font;
XGCValues gcvalue;
@ -494,9 +544,8 @@ menu_set_font(menu_t * menu, const char *fontname)
}
unsigned char
menu_add_item(menu_t * menu, menuitem_t * item)
menu_add_item(menu_t *menu, menuitem_t *item)
{
ASSERT_RVAL(menu != NULL, 0);
ASSERT_RVAL(item != NULL, 0);
@ -515,9 +564,8 @@ menu_add_item(menu_t * menu, menuitem_t * item)
/* Return 1 if submenu is a child of menu, 0 if not. */
unsigned char
menu_is_child(menu_t * menu, menu_t * submenu)
menu_is_child(menu_t *menu, menu_t *submenu)
{
register unsigned char i;
register menuitem_t *item;
@ -538,9 +586,8 @@ menu_is_child(menu_t * menu, menu_t * submenu)
}
menu_t *
find_menu_by_title(menulist_t * list, char *title)
find_menu_by_title(menulist_t *list, char *title)
{
register unsigned char i;
REQUIRE_RVAL(list != NULL, NULL);
@ -554,9 +601,8 @@ find_menu_by_title(menulist_t * list, char *title)
}
menu_t *
find_menu_by_window(menulist_t * list, Window win)
find_menu_by_window(menulist_t *list, Window win)
{
register unsigned char i;
REQUIRE_RVAL(list != NULL, NULL);
@ -570,9 +616,8 @@ find_menu_by_window(menulist_t * list, Window win)
}
menuitem_t *
find_item_by_coords(menu_t * menu, int x, int y)
find_item_by_coords(menu_t *menu, int x, int y)
{
register unsigned char i;
register menuitem_t *item;
@ -588,9 +633,8 @@ find_item_by_coords(menu_t * menu, int x, int y)
}
unsigned short
find_item_in_menu(menu_t * menu, menuitem_t * item)
find_item_in_menu(menu_t *menu, menuitem_t *item)
{
register unsigned char i;
ASSERT_RVAL(menu != NULL, (unsigned short) -1);
@ -646,7 +690,6 @@ menuitem_change_current(menuitem_t *item)
menuitem_t *
menuitem_create(char *text)
{
menuitem_t *menuitem;
menuitem = (menuitem_t *) MALLOC(sizeof(menuitem_t));
@ -659,8 +702,28 @@ menuitem_create(char *text)
return menuitem;
}
void
menuitem_delete(menuitem_t *item)
{
ASSERT(item != NULL);
if (item->icon) {
free_simage(item->icon);
}
if (item->type == MENUITEM_STRING || item->type == MENUITEM_ECHO) {
FREE(item->action.string);
}
if (item->text) {
FREE(item->text);
}
if (item->rtext) {
FREE(item->rtext);
}
FREE(item);
}
unsigned char
menuitem_set_text(menuitem_t * item, const char *text)
menuitem_set_text(menuitem_t *item, const char *text)
{
ASSERT_RVAL(item != NULL, 0);
REQUIRE_RVAL(text != NULL, 0);
@ -674,9 +737,8 @@ menuitem_set_text(menuitem_t * item, const char *text)
}
unsigned char
menuitem_set_icon(menuitem_t * item, simage_t * icon)
menuitem_set_icon(menuitem_t *item, simage_t *icon)
{
ASSERT_RVAL(item != NULL, 0);
ASSERT_RVAL(icon != NULL, 0);
@ -685,9 +747,8 @@ menuitem_set_icon(menuitem_t * item, simage_t * icon)
}
unsigned char
menuitem_set_action(menuitem_t * item, unsigned char type, char *action)
menuitem_set_action(menuitem_t *item, unsigned char type, char *action)
{
ASSERT_RVAL(item != NULL, 0);
item->type = type;
@ -708,9 +769,8 @@ menuitem_set_action(menuitem_t * item, unsigned char type, char *action)
}
unsigned char
menuitem_set_rtext(menuitem_t * item, char *rtext)
menuitem_set_rtext(menuitem_t *item, char *rtext)
{
ASSERT_RVAL(item != NULL, 0);
ASSERT_RVAL(rtext != NULL, 0);
@ -720,9 +780,8 @@ menuitem_set_rtext(menuitem_t * item, char *rtext)
}
void
menu_reset(menu_t * menu)
menu_reset(menu_t *menu)
{
ASSERT(menu != NULL);
D_MENU(("menu_reset(menu %8p \"%s\"), window 0x%08x\n", menu, menu->title, menu->win));
@ -736,7 +795,7 @@ menu_reset(menu_t * menu)
}
void
menu_reset_all(menulist_t * list)
menu_reset_all(menulist_t *list)
{
register unsigned short i;
@ -756,9 +815,8 @@ menu_reset_all(menulist_t * list)
}
void
menu_reset_tree(menu_t * menu)
menu_reset_tree(menu_t *menu)
{
register unsigned short i;
register menuitem_t *item;
@ -778,9 +836,8 @@ menu_reset_tree(menu_t * menu)
}
void
menu_reset_submenus(menu_t * menu)
menu_reset_submenus(menu_t *menu)
{
register unsigned short i;
register menuitem_t *item;
@ -796,7 +853,7 @@ menu_reset_submenus(menu_t * menu)
}
void
menuitem_select(menu_t * menu)
menuitem_select(menu_t *menu)
{
static Pixel top = 0, bottom = 0;
menuitem_t *item;
@ -822,9 +879,6 @@ menuitem_select(menu_t * menu)
draw_shadow_from_colors(menu->swin, top, bottom, 0, 0, item->w - MENU_VGAP, item->h, 2);
draw_arrow_from_colors(menu->swin, top, bottom, item->w - 3 * MENU_HGAP, (item->h - MENU_VGAP) / 2, MENU_VGAP, 2, DRAW_ARROW_RIGHT);
}
#if 0
paste_simage(images[image_submenu].selected, image_submenu, menu->swin, 0, 0, item->w - MENU_VGAP, item->h);
#endif
} else {
if (image_mode_is(image_menu, MODE_MASK)) {
render_simage(images[image_menu].selected, menu->swin, item->w - MENU_VGAP, item->h, image_menu, 0);
@ -844,7 +898,7 @@ menuitem_select(menu_t * menu)
}
void
menuitem_deselect(menu_t * menu)
menuitem_deselect(menu_t *menu)
{
menuitem_t *item;
@ -858,7 +912,7 @@ menuitem_deselect(menu_t * menu)
}
void
menu_display_submenu(menu_t * menu, menuitem_t * item)
menu_display_submenu(menu_t *menu, menuitem_t *item)
{
menu_t *submenu;
@ -893,9 +947,8 @@ menu_move(menu_t *menu, unsigned short x, unsigned short y) {
}
void
menu_draw(menu_t * menu)
menu_draw(menu_t *menu)
{
register unsigned short i, len;
unsigned long width, height;
#if 0
@ -1070,9 +1123,8 @@ menu_draw(menu_t * menu)
}
void
menu_display(int x, int y, menu_t * menu)
menu_display(int x, int y, menu_t *menu)
{
ASSERT(menu != NULL);
menu->state |= (MENU_STATE_IS_CURRENT);
@ -1091,9 +1143,8 @@ menu_display(int x, int y, menu_t * menu)
}
void
menu_action(menuitem_t * item)
menu_action(menuitem_t *item)
{
ASSERT(item != NULL);
D_MENU(("menu_action() called to invoke %s\n", item->text));
@ -1117,9 +1168,8 @@ menu_action(menuitem_t * item)
}
void
menu_invoke(int x, int y, Window win, menu_t * menu, Time timestamp)
menu_invoke(int x, int y, Window win, menu_t *menu, Time timestamp)
{
int root_x, root_y;
Window unused;
@ -1138,7 +1188,6 @@ menu_invoke(int x, int y, Window win, menu_t * menu, Time timestamp)
void
menu_invoke_by_title(int x, int y, Window win, char *title, Time timestamp)
{
menu_t *menu;
REQUIRE(title != NULL);

View File

@ -106,7 +106,9 @@ extern unsigned char menu_handle_button_release(event_t *);
extern unsigned char menu_handle_motion_notify(event_t *);
extern unsigned char menu_dispatch_event(event_t *);
extern menulist_t *menulist_add_menu(menulist_t *, menu_t *);
extern void menulist_clear(menulist_t *);
extern menu_t *menu_create(char *);
extern void menu_delete(menu_t *);
extern unsigned char menu_set_title(menu_t *, const char *);
extern unsigned char menu_set_font(menu_t *, const char *);
extern unsigned char menu_add_item(menu_t *, menuitem_t *);
@ -117,6 +119,7 @@ extern menuitem_t *find_item_by_coords(menu_t *, int, int);
extern unsigned short find_item_in_menu(menu_t *, menuitem_t *);
extern void menuitem_change_current(menuitem_t *);
extern menuitem_t *menuitem_create(char *);
extern void menuitem_delete(menuitem_t *);
extern unsigned char menuitem_set_text(menuitem_t *, const char *);
extern unsigned char menuitem_set_icon(menuitem_t *, simage_t *);
extern unsigned char menuitem_set_action(menuitem_t *, unsigned char, char *);

View File

@ -344,7 +344,7 @@ create_simage(void)
}
void
reset_simage(simage_t * simg, unsigned long mask)
reset_simage(simage_t *simg, unsigned long mask)
{
ASSERT(simg != NULL);
@ -818,7 +818,7 @@ copy_buffer_pixmap(unsigned char mode, unsigned long fill, unsigned short width,
}
void
render_simage(simage_t * simg, Window win, unsigned short width, unsigned short height, unsigned char which, renderop_t renderop)
render_simage(simage_t *simg, Window win, unsigned short width, unsigned short height, unsigned char which, renderop_t renderop)
{
XGCValues gcvalue;

View File

@ -102,7 +102,7 @@ encoding_t encoding_method = LATIN1;
/* Fill part/all of a drawn line with blanks. */
inline void blank_line(text_t *, rend_t *, int, rend_t);
inline void
blank_line(text_t * et, rend_t * er, int width, rend_t efs)
blank_line(text_t *et, rend_t *er, int width, rend_t efs)
{
/* int i = width; */