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. 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_NOP(x)
#define FIXME_BLOCK 0 #define FIXME_BLOCK 0
/* An "unused block" marker similar to the above. */
#define UNUSED_BLOCK 0
/* The basic debugging output leader. */ /* The basic debugging output leader. */
#if defined(__FILE__) && defined(__LINE__) #if defined(__FILE__) && defined(__LINE__)
# ifdef __GNUC__ # ifdef __GNUC__

View File

@ -7,3 +7,4 @@ for i in *.c src/*.c utils/*.c ; do
fi fi
done 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 unsigned char
bbar_handle_enter_notify(event_t * ev) bbar_handle_enter_notify(event_t *ev)
{ {
button_t *b; button_t *b;
Window unused_root, unused_child; Window unused_root, unused_child;
@ -158,7 +158,7 @@ bbar_handle_enter_notify(event_t * ev)
} }
unsigned char 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)); 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 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)); 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 unsigned char
bbar_handle_button_release(event_t * ev) bbar_handle_button_release(event_t *ev)
{ {
button_t *b; button_t *b;
Window unused_root, unused_child; Window unused_root, unused_child;
@ -214,7 +214,7 @@ bbar_handle_button_release(event_t * ev)
} }
unsigned char unsigned char
bbar_handle_motion_notify(event_t * ev) bbar_handle_motion_notify(event_t *ev)
{ {
button_t *b; button_t *b;
Window unused_root, unused_child; Window unused_root, unused_child;
@ -247,7 +247,7 @@ bbar_handle_motion_notify(event_t * ev)
} }
unsigned char unsigned char
bbar_dispatch_event(event_t * ev) bbar_dispatch_event(event_t *ev)
{ {
if (buttonbar->event_data.handlers[ev->type] != NULL) { if (buttonbar->event_data.handlers[ev->type] != NULL) {
return ((buttonbar->event_data.handlers[ev->type]) (ev)); return ((buttonbar->event_data.handlers[ev->type]) (ev));
@ -587,7 +587,7 @@ button_create(char *text)
} }
unsigned char 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(button != NULL, 0);
ASSERT_RVAL(icon != 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_text(buttonbar_t *bbar, char *text);
extern button_t *find_button_by_coords(buttonbar_t *bbar, int x, int y); extern button_t *find_button_by_coords(buttonbar_t *bbar, int x, int y);
extern button_t *button_create(char *text); 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 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_select_button(buttonbar_t *bbar, button_t *button);
extern void bbar_deselect_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 void
clean_exit(void) clean_exit(void)
{ {
#if DEBUG >= DEBUG_MEM
if (DEBUG_LEVEL >= DEBUG_MEM) {
/* Deallocate all our crap to help find memory leaks */
scr_release(); scr_release();
menulist_clear(menu_list);
font_cache_clear();
eterm_font_list_clear();
}
#endif
privileges(INVOKE); privileges(INVOKE);
#ifndef __CYGWIN32__ #ifndef __CYGWIN32__
@ -1471,7 +1480,7 @@ get_tty(void)
} while (0) } while (0)
# define SHOW_CONT_CHAR(entry, name) fprintf(stderr, "%s=%#3o ", name, ttymode->c_cc[entry]) # define SHOW_CONT_CHAR(entry, name) fprintf(stderr, "%s=%#3o ", name, ttymode->c_cc[entry])
static void static void
debug_ttymode(ttymode_t * ttymode) debug_ttymode(ttymode_t *ttymode)
{ {
/* c_iflag bits */ /* c_iflag bits */
@ -1541,7 +1550,7 @@ debug_ttymode(ttymode_t * ttymode)
/* get_ttymode() */ /* get_ttymode() */
static void static void
get_ttymode(ttymode_t * tio) get_ttymode(ttymode_t *tio)
{ {
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
/* /*

View File

@ -77,7 +77,7 @@ event_register_dispatcher(event_dispatcher_t func, event_dispatcher_init_t init)
} }
void void
event_dispatch(event_t * event) event_dispatch(event_t *event)
{ {
register unsigned char i; register unsigned char i;
@ -93,7 +93,7 @@ event_dispatch(event_t * event)
} }
void 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); ASSERT(data != NULL);
@ -110,7 +110,7 @@ event_data_add_mywin(event_dispatcher_data_t * data, Window win)
} }
void 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); ASSERT(data != NULL);
@ -163,7 +163,7 @@ event_init_primary_dispatcher(void)
} }
unsigned char 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; register unsigned short i;
@ -179,7 +179,7 @@ event_win_is_mywin(register event_dispatcher_data_t * data, Window win)
} }
unsigned char 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; register unsigned short i;
@ -195,7 +195,7 @@ event_win_is_parent(register event_dispatcher_data_t * data, Window win)
} }
unsigned char unsigned char
handle_key_press(event_t * ev) handle_key_press(event_t *ev)
{ {
#ifdef COUNT_X_EVENTS #ifdef COUNT_X_EVENTS
static unsigned long keypress_cnt = 0; static unsigned long keypress_cnt = 0;
@ -215,7 +215,7 @@ handle_key_press(event_t * ev)
} }
unsigned char unsigned char
handle_property_notify(event_t * ev) handle_property_notify(event_t *ev)
{ {
Atom prop; Atom prop;
@ -281,7 +281,7 @@ handle_property_notify(event_t * ev)
} }
unsigned char 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 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)); 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 unsigned char
handle_expose(event_t * ev) handle_expose(event_t *ev)
{ {
PROF_INIT(handle_expose); PROF_INIT(handle_expose);
D_EVENTS(("handle_expose(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); 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 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)); 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 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)); 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 unsigned char
handle_motion_notify(event_t * ev) handle_motion_notify(event_t *ev)
{ {
#ifdef COUNT_X_EVENTS #ifdef COUNT_X_EVENTS
static unsigned long motion_cnt = 0; static unsigned long motion_cnt = 0;
@ -754,7 +754,7 @@ handle_motion_notify(event_t * ev)
} }
unsigned char unsigned char
process_x_event(event_t * ev) process_x_event(event_t *ev)
{ {
#ifdef COUNT_X_EVENTS #ifdef COUNT_X_EVENTS
static unsigned long event_cnt = 0; 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 void *font_cache_find_info(const char *name, unsigned char type);
static unsigned char get_corner(const char *corner); 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 void
eterm_font_add(char ***plist, const char *fontname, unsigned char idx) { eterm_font_add(char ***plist, const char *fontname, unsigned char idx) {
char **flist; char **flist;
D_FONT(("Adding \"%s\" at %u (%8p)\n", NONULL(fontname), (unsigned int) idx, plist)); D_FONT(("Adding \"%s\" at %u (%8p)\n", NONULL(fontname), (unsigned int) idx, plist));
ASSERT(plist != NULL); ASSERT(plist != NULL); /* plist is the address of either etfonts or etmfonts */
flist = *plist;
/* If we're adding the font at an index we don't have yet, we must resize to fit it. */
if (idx >= font_cnt) { if (idx >= font_cnt) {
unsigned char new_size = sizeof(char *) * (idx + 1); 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) { if (etfonts) {
etfonts = (char **) REALLOC(etfonts, new_size); etfonts = (char **) REALLOC(etfonts, new_size);
#ifdef MULTI_CHARSET #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)); D_FONT((" -> Allocating font list: %u bytes at %8p\n", new_size, etfonts));
#endif #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)); MEMSET(etfonts + font_cnt, 0, sizeof(char *) * (idx - font_cnt + 1));
#ifdef MULTI_CHARSET #ifdef MULTI_CHARSET
MEMSET(etmfonts + font_cnt, 0, sizeof(char *) * (idx - font_cnt + 1)); MEMSET(etmfonts + font_cnt, 0, sizeof(char *) * (idx - font_cnt + 1));
#endif #endif
font_cnt = idx + 1; font_cnt = idx + 1; /* Update the font count. */
#ifdef MULTI_CHARSET #ifdef MULTI_CHARSET
flist = ((plist == &etfonts) ? (etfonts) : (etmfonts)); flist = ((plist == &etfonts) ? (etfonts) : (etmfonts));
#else #else
flist = etfonts; flist = etfonts;
#endif #endif
} else { } else {
flist = *plist;
if (flist[idx]) { if (flist[idx]) {
if ((flist[idx] == fontname) || (!strcasecmp(flist[idx], fontname))) { 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); flist[idx] = STRDUP(fontname);
@ -121,6 +129,25 @@ eterm_font_delete(char **flist, unsigned char idx) {
flist[idx] = NULL; 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 static void
font_cache_add(const char *name, unsigned char type, void *info) { 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)); 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 = (cachefont_t *) MALLOC(sizeof(cachefont_t));
font->name = STRDUP(name); font->name = STRDUP(name);
font->type = type; font->type = type;
@ -139,6 +167,8 @@ font_cache_add(const char *name, unsigned char type, void *info) {
default: break; default: break;
} }
D_FONT((" -> Created new cachefont_t struct at %p: \"%s\", %d, %p\n", font, font->name, font->type, font->fontinfo.xfontinfo)); 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) { if (font_cache == NULL) {
font_cache = cur_font = font; font_cache = cur_font = font;
font->next = NULL; font->next = NULL;
@ -162,10 +192,13 @@ font_cache_del(const void *info) {
D_FONT(("font_cache_del(%8p) called.\n", info)); D_FONT(("font_cache_del(%8p) called.\n", info));
if (font_cache == NULL) { 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))) { 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))); 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) { if (--(font_cache->ref_cnt) == 0) {
D_FONT((" -> Reference count is now 0. Deleting from cache.\n")); D_FONT((" -> Reference count is now 0. Deleting from cache.\n"));
current = font_cache; 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)); D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
} }
return; return;
#if UNUSED_BLOCK
} else if ((font_cache->type == FONT_TYPE_TTF) && (0)) { } else if ((font_cache->type == FONT_TYPE_TTF) && (0)) {
} else if ((font_cache->type == FONT_TYPE_FNLIB) && (0)) { } else if ((font_cache->type == FONT_TYPE_FNLIB) && (0)) {
#endif
} else { } 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) { for (current = font_cache; current->next; current = current->next) {
if (((current->next->type == FONT_TYPE_X) && (current->next->fontinfo.xfontinfo == (XFontStruct *) info))) { 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))); 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)); D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
} }
return; return;
#if UNUSED_BLOCK
} else if ((current->next->type == FONT_TYPE_TTF) && (0)) { } else if ((current->next->type == FONT_TYPE_TTF) && (0)) {
} else if ((current->next->type == FONT_TYPE_FNLIB) && (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 * 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)); 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) { for (current = font_cache; current; current = current->next) {
D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name))); D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name)));
if ((current->type == type) && !strcasecmp(current->name, 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)); 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) { for (current = font_cache; current; current = current->next) {
D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name))); D_FONT((" -> Checking current (%8p), type == %d, name == %s\n", current, current->type, NONULL(current->name)));
if ((current->type == type) && !strcasecmp(current->name, 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); return (NULL);
} }
/* load_font() is the function that should be used to allocate fonts. */
void * void *
load_font(const char *name, const char *fallback, unsigned char type) 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)); D_FONT(("load_font(%s, %s, %d) called.\n", NONULL(name), NONULL(fallback), type));
/* Default type is X font. */
if (type == 0) { if (type == 0) {
type = FONT_TYPE_X; type = FONT_TYPE_X;
} }
/* Specify some sane fallbacks */
if (name == NULL) { if (name == NULL) {
if (fallback) { if (fallback) {
name = 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)); 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) { if ((font = font_cache_find(name, type)) != NULL) {
font_cache_add_ref(font); font_cache_add_ref(font);
D_FONT((" -> Font found in cache. Incrementing reference count to %d and returning existing data.\n", font->ref_cnt)); 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; default: return (NULL); break;
} }
} }
/* No match in the cache, so we'll have to add it. */
if (type == FONT_TYPE_X) { if (type == FONT_TYPE_X) {
if ((xfont = XLoadQueryFont(Xdisplay, name)) == NULL) { if ((xfont = XLoadQueryFont(Xdisplay, name)) == NULL) {
print_error("Unable to load font \"%s\". Falling back on \"%s\"\n", name, fallback); 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); font_cache_add(name, type, (void *) xfont);
} }
return ((void *) xfont); return ((void *) xfont);
#if UNUSED_BLOCK
} else if (type == FONT_TYPE_TTF) { } else if (type == FONT_TYPE_TTF) {
return (NULL); return (NULL);
} else if (type == FONT_TYPE_FNLIB) { } else if (type == FONT_TYPE_FNLIB) {
return (NULL); return (NULL);
#endif
} }
ASSERT_NOTREACHED_RVAL(NULL); ASSERT_NOTREACHED_RVAL(NULL);
} }
/* free_font() is the external function for deallocating fonts. */
void void
free_font(const void *info) free_font(const void *info)
{ {
ASSERT(info != NULL); ASSERT(info != NULL);
font_cache_del(info); 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 void
change_font(int init, const char *fontname) change_font(int init, const char *fontname)
{ {
@ -340,12 +416,13 @@ change_font(int init, const char *fontname)
ASSERT(fontname != NULL); ASSERT(fontname != NULL);
switch (*fontname) { switch (*fontname) {
/* Empty font name. Reset to default. */
case '\0': case '\0':
font_idx = def_font_idx; font_idx = def_font_idx;
fontname = NULL; fontname = NULL;
break; break;
/* special (internal) prefix for font commands */ /* A font escape sequence. See which one it is. */
case FONT_CMD: case FONT_CMD:
idx = atoi(++fontname); idx = atoi(++fontname);
switch (*fontname) { switch (*fontname) {
@ -359,15 +436,18 @@ change_font(int init, const char *fontname)
default: default:
if (*fontname != '\0' && !isdigit(*fontname)) 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)); BOUND(idx, 0, (font_cnt - 1));
font_idx = idx; font_idx = idx;
break; break;
} }
/* NULL out the fontname so we don't try to load it */
fontname = NULL; fontname = NULL;
break; break;
default: 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++) { for (idx = 0; idx < font_cnt; idx++) {
if (!strcasecmp(etfonts[idx], fontname)) { if (!strcasecmp(etfonts[idx], fontname)) {
font_idx = idx; font_idx = idx;
@ -377,31 +457,38 @@ change_font(int init, const char *fontname)
} }
break; break;
} }
/* If we get here with a non-NULL fontname, we have to load a new font. Rats. */
if (fontname != NULL) { if (fontname != NULL) {
eterm_font_add(&etfonts, fontname, font_idx); eterm_font_add(&etfonts, fontname, font_idx);
} else if (font_idx == old_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)); D_FONT((" -> Change to the same font index (%d) we had before? I don't think so.\n", font_idx));
return; return;
} }
} }
D_FONT((" -> Changing to font index %u (\"%s\")\n", (unsigned int) font_idx, NONULL(etfonts[font_idx]))); D_FONT((" -> Changing to font index %u (\"%s\")\n", (unsigned int) font_idx, NONULL(etfonts[font_idx])));
if (TermWin.font) { 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) { if (font_cache_find_info(etfonts[font_idx], FONT_TYPE_X) != TermWin.font) {
free_font(TermWin.font); free_font(TermWin.font);
TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X); TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X);
} }
} else { } else {
/* Load the new font. */
TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X); TermWin.font = load_font(etfonts[font_idx], "fixed", FONT_TYPE_X);
} }
#ifndef NO_BOLDFONT #ifndef NO_BOLDFONT
if (init && rs_boldFont != NULL) { 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); boldFont = load_font(rs_boldFont, "-misc-fixed-bold-r-semicondensed--13-120-75-75-c-60-iso8859-1", FONT_TYPE_X);
} }
#endif #endif
#ifdef MULTI_CHARSET #ifdef MULTI_CHARSET
if (TermWin.mfont) { 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) { if (font_cache_find_info(etmfonts[font_idx], FONT_TYPE_X) != TermWin.mfont) {
free_font(TermWin.mfont); free_font(TermWin.mfont);
TermWin.mfont = load_font(etmfonts[font_idx], "k14", FONT_TYPE_X); 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); TermWin.mfont = load_font(etmfonts[font_idx], "k14", FONT_TYPE_X);
} }
# ifdef USE_XIM # ifdef USE_XIM
/* Changing fonts requires updating the FontSet */
if (xim_input_context) { if (xim_input_context) {
if (TermWin.fontset) { if (TermWin.fontset) {
XFreeFontSet(Xdisplay, TermWin.fontset); XFreeFontSet(Xdisplay, TermWin.fontset);
@ -421,9 +509,11 @@ change_font(int init, const char *fontname)
#endif /* MULTI_CHARSET */ #endif /* MULTI_CHARSET */
if (!init) { if (!init) {
/* Unless we're initializing, set the font ID in the GC to our new font. */
XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid); XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid);
} }
/* Check the font dimensions to update our TermWin info */
fw = TermWin.font->min_bounds.width; fw = TermWin.font->min_bounds.width;
#ifdef MULTI_CHARSET #ifdef MULTI_CHARSET
fh = (MAX((encoding_method == LATIN1 ? 0 : TermWin.mfont->ascent), TermWin.font->ascent) fh = (MAX((encoding_method == LATIN1 ? 0 : TermWin.mfont->ascent), TermWin.font->ascent)
@ -440,6 +530,7 @@ change_font(int init, const char *fontname)
else else
TermWin.fprop = 1; /* Proportional font */ 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)) { 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; int cw, n = 0, sum = 0, sumsq = 0, min_w, max_w;
unsigned int i; unsigned int i;
@ -469,16 +560,16 @@ change_font(int init, const char *fontname)
LOWER_BOUND(fw, TermWin.font->max_bounds.width); 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) if (fw == TermWin.fwidth && fh == TermWin.fheight)
return; return;
TermWin.fwidth = fw; TermWin.fwidth = fw;
TermWin.fheight = fh; 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 #ifndef NO_BOLDFONT
TermWin.boldFont = NULL; TermWin.boldFont = NULL; /* FIXME: Memory leak? Not that anyone uses bold fonts.... */
if (boldFont != NULL) { if (boldFont != NULL) {
fw = boldFont->min_bounds.width; fw = boldFont->min_bounds.width;
@ -502,6 +593,7 @@ change_font(int init, const char *fontname)
TermWin.height = TermWin.nrow * TermWin.fheight; 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)); 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) { if (init) {
szHint.width_inc = TermWin.fwidth; szHint.width_inc = TermWin.fwidth;
szHint.height_inc = TermWin.fheight; szHint.height_inc = TermWin.fheight;

View File

@ -46,6 +46,7 @@
#define SHADOW_BOTTOM_LEFT 2 #define SHADOW_BOTTOM_LEFT 2
#define SHADOW_BOTTOM_RIGHT 3 #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);} \ #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) 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);} \ #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 ************/ /************ Structures ************/
typedef struct cachefont_struct { typedef struct cachefont_struct {
char *name; char *name; /* Font name in canonical format */
unsigned char type; unsigned char type; /* Font type (FONT_TYPE_* from above */
unsigned char ref_cnt; unsigned char ref_cnt; /* Reference count */
union { union {
/* This union will eventually have members for TTF/Fnlib fonts */
XFontStruct *xfontinfo; XFontStruct *xfontinfo;
} fontinfo; } fontinfo;
struct cachefont_struct *next; 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_add(char ***plist, const char *fontname, unsigned char idx);
extern void eterm_font_delete(char **flist, 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 *load_font(const char *, const char *, unsigned char);
extern void free_font(const void *); extern void free_font(const void *);
extern void change_font(int, const char *); extern void change_font(int, const char *);

View File

@ -156,7 +156,7 @@ menu_event_init_dispatcher(void)
} }
unsigned char unsigned char
menu_handle_enter_notify(event_t * ev) menu_handle_enter_notify(event_t *ev)
{ {
register menu_t *menu; register menu_t *menu;
@ -181,7 +181,7 @@ menu_handle_enter_notify(event_t * ev)
} }
unsigned char 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)); 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 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)); 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 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)); 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 #if 0
unsigned char unsigned char
menu_handle_expose(event_t * ev) menu_handle_expose(event_t *ev)
{ {
XEvent unused_xevent; XEvent unused_xevent;
@ -234,7 +234,7 @@ menu_handle_expose(event_t * ev)
#endif #endif
unsigned char 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)); 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 unsigned char
menu_handle_button_release(event_t * ev) menu_handle_button_release(event_t *ev)
{ {
menuitem_t *item; menuitem_t *item;
@ -333,7 +333,7 @@ menu_handle_button_release(event_t * ev)
} }
unsigned char unsigned char
menu_handle_motion_notify(event_t * ev) menu_handle_motion_notify(event_t *ev)
{ {
register menuitem_t *item = NULL; register menuitem_t *item = NULL;
@ -392,7 +392,7 @@ menu_handle_motion_notify(event_t * ev)
} }
unsigned char unsigned char
menu_dispatch_event(event_t * ev) menu_dispatch_event(event_t *ev)
{ {
if (menu_event_data.handlers[ev->type] != NULL) { if (menu_event_data.handlers[ev->type] != NULL) {
return ((menu_event_data.handlers[ev->type]) (ev)); return ((menu_event_data.handlers[ev->type]) (ev));
@ -401,9 +401,8 @@ menu_dispatch_event(event_t * ev)
} }
menulist_t * 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); ASSERT_RVAL(menu != NULL, list);
if (list) { if (list) {
@ -418,10 +417,25 @@ menulist_add_menu(menulist_t * list, menu_t * menu)
return list; 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_t *
menu_create(char *title) menu_create(char *title)
{ {
menu_t *menu; menu_t *menu;
static Cursor cursor; static Cursor cursor;
static long mask; static long mask;
@ -456,6 +470,43 @@ menu_create(char *title)
return menu; 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 unsigned char
menu_set_title(menu_t *menu, const char *title) menu_set_title(menu_t *menu, const char *title)
{ {
@ -469,9 +520,8 @@ menu_set_title(menu_t *menu, const char *title)
} }
unsigned char unsigned char
menu_set_font(menu_t * menu, const char *fontname) menu_set_font(menu_t *menu, const char *fontname)
{ {
XFontStruct *font; XFontStruct *font;
XGCValues gcvalue; XGCValues gcvalue;
@ -494,9 +544,8 @@ menu_set_font(menu_t * menu, const char *fontname)
} }
unsigned char 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(menu != NULL, 0);
ASSERT_RVAL(item != 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. */ /* Return 1 if submenu is a child of menu, 0 if not. */
unsigned char 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 unsigned char i;
register menuitem_t *item; register menuitem_t *item;
@ -538,9 +586,8 @@ menu_is_child(menu_t * menu, menu_t * submenu)
} }
menu_t * menu_t *
find_menu_by_title(menulist_t * list, char *title) find_menu_by_title(menulist_t *list, char *title)
{ {
register unsigned char i; register unsigned char i;
REQUIRE_RVAL(list != NULL, NULL); REQUIRE_RVAL(list != NULL, NULL);
@ -554,9 +601,8 @@ find_menu_by_title(menulist_t * list, char *title)
} }
menu_t * menu_t *
find_menu_by_window(menulist_t * list, Window win) find_menu_by_window(menulist_t *list, Window win)
{ {
register unsigned char i; register unsigned char i;
REQUIRE_RVAL(list != NULL, NULL); REQUIRE_RVAL(list != NULL, NULL);
@ -570,9 +616,8 @@ find_menu_by_window(menulist_t * list, Window win)
} }
menuitem_t * 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 unsigned char i;
register menuitem_t *item; register menuitem_t *item;
@ -588,9 +633,8 @@ find_item_by_coords(menu_t * menu, int x, int y)
} }
unsigned short 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; register unsigned char i;
ASSERT_RVAL(menu != NULL, (unsigned short) -1); ASSERT_RVAL(menu != NULL, (unsigned short) -1);
@ -646,7 +690,6 @@ menuitem_change_current(menuitem_t *item)
menuitem_t * menuitem_t *
menuitem_create(char *text) menuitem_create(char *text)
{ {
menuitem_t *menuitem; menuitem_t *menuitem;
menuitem = (menuitem_t *) MALLOC(sizeof(menuitem_t)); menuitem = (menuitem_t *) MALLOC(sizeof(menuitem_t));
@ -659,8 +702,28 @@ menuitem_create(char *text)
return menuitem; 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 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); ASSERT_RVAL(item != NULL, 0);
REQUIRE_RVAL(text != NULL, 0); REQUIRE_RVAL(text != NULL, 0);
@ -674,9 +737,8 @@ menuitem_set_text(menuitem_t * item, const char *text)
} }
unsigned char 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(item != NULL, 0);
ASSERT_RVAL(icon != NULL, 0); ASSERT_RVAL(icon != NULL, 0);
@ -685,9 +747,8 @@ menuitem_set_icon(menuitem_t * item, simage_t * icon)
} }
unsigned char 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); ASSERT_RVAL(item != NULL, 0);
item->type = type; item->type = type;
@ -708,9 +769,8 @@ menuitem_set_action(menuitem_t * item, unsigned char type, char *action)
} }
unsigned char 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(item != NULL, 0);
ASSERT_RVAL(rtext != NULL, 0); ASSERT_RVAL(rtext != NULL, 0);
@ -720,9 +780,8 @@ menuitem_set_rtext(menuitem_t * item, char *rtext)
} }
void void
menu_reset(menu_t * menu) menu_reset(menu_t *menu)
{ {
ASSERT(menu != NULL); ASSERT(menu != NULL);
D_MENU(("menu_reset(menu %8p \"%s\"), window 0x%08x\n", menu, menu->title, menu->win)); 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 void
menu_reset_all(menulist_t * list) menu_reset_all(menulist_t *list)
{ {
register unsigned short i; register unsigned short i;
@ -756,9 +815,8 @@ menu_reset_all(menulist_t * list)
} }
void void
menu_reset_tree(menu_t * menu) menu_reset_tree(menu_t *menu)
{ {
register unsigned short i; register unsigned short i;
register menuitem_t *item; register menuitem_t *item;
@ -778,9 +836,8 @@ menu_reset_tree(menu_t * menu)
} }
void void
menu_reset_submenus(menu_t * menu) menu_reset_submenus(menu_t *menu)
{ {
register unsigned short i; register unsigned short i;
register menuitem_t *item; register menuitem_t *item;
@ -796,7 +853,7 @@ menu_reset_submenus(menu_t * menu)
} }
void void
menuitem_select(menu_t * menu) menuitem_select(menu_t *menu)
{ {
static Pixel top = 0, bottom = 0; static Pixel top = 0, bottom = 0;
menuitem_t *item; 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_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); 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 { } else {
if (image_mode_is(image_menu, MODE_MASK)) { 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); 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 void
menuitem_deselect(menu_t * menu) menuitem_deselect(menu_t *menu)
{ {
menuitem_t *item; menuitem_t *item;
@ -858,7 +912,7 @@ menuitem_deselect(menu_t * menu)
} }
void void
menu_display_submenu(menu_t * menu, menuitem_t * item) menu_display_submenu(menu_t *menu, menuitem_t *item)
{ {
menu_t *submenu; menu_t *submenu;
@ -893,9 +947,8 @@ menu_move(menu_t *menu, unsigned short x, unsigned short y) {
} }
void void
menu_draw(menu_t * menu) menu_draw(menu_t *menu)
{ {
register unsigned short i, len; register unsigned short i, len;
unsigned long width, height; unsigned long width, height;
#if 0 #if 0
@ -1070,9 +1123,8 @@ menu_draw(menu_t * menu)
} }
void void
menu_display(int x, int y, menu_t * menu) menu_display(int x, int y, menu_t *menu)
{ {
ASSERT(menu != NULL); ASSERT(menu != NULL);
menu->state |= (MENU_STATE_IS_CURRENT); menu->state |= (MENU_STATE_IS_CURRENT);
@ -1091,9 +1143,8 @@ menu_display(int x, int y, menu_t * menu)
} }
void void
menu_action(menuitem_t * item) menu_action(menuitem_t *item)
{ {
ASSERT(item != NULL); ASSERT(item != NULL);
D_MENU(("menu_action() called to invoke %s\n", item->text)); D_MENU(("menu_action() called to invoke %s\n", item->text));
@ -1117,9 +1168,8 @@ menu_action(menuitem_t * item)
} }
void 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; int root_x, root_y;
Window unused; Window unused;
@ -1138,7 +1188,6 @@ menu_invoke(int x, int y, Window win, menu_t * menu, Time timestamp)
void void
menu_invoke_by_title(int x, int y, Window win, char *title, Time timestamp) menu_invoke_by_title(int x, int y, Window win, char *title, Time timestamp)
{ {
menu_t *menu; menu_t *menu;
REQUIRE(title != NULL); 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_handle_motion_notify(event_t *);
extern unsigned char menu_dispatch_event(event_t *); extern unsigned char menu_dispatch_event(event_t *);
extern menulist_t *menulist_add_menu(menulist_t *, menu_t *); extern menulist_t *menulist_add_menu(menulist_t *, menu_t *);
extern void menulist_clear(menulist_t *);
extern menu_t *menu_create(char *); 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_title(menu_t *, const char *);
extern unsigned char menu_set_font(menu_t *, const char *); extern unsigned char menu_set_font(menu_t *, const char *);
extern unsigned char menu_add_item(menu_t *, menuitem_t *); 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 unsigned short find_item_in_menu(menu_t *, menuitem_t *);
extern void menuitem_change_current(menuitem_t *); extern void menuitem_change_current(menuitem_t *);
extern menuitem_t *menuitem_create(char *); 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_text(menuitem_t *, const char *);
extern unsigned char menuitem_set_icon(menuitem_t *, simage_t *); extern unsigned char menuitem_set_icon(menuitem_t *, simage_t *);
extern unsigned char menuitem_set_action(menuitem_t *, unsigned char, char *); extern unsigned char menuitem_set_action(menuitem_t *, unsigned char, char *);

View File

@ -344,7 +344,7 @@ create_simage(void)
} }
void void
reset_simage(simage_t * simg, unsigned long mask) reset_simage(simage_t *simg, unsigned long mask)
{ {
ASSERT(simg != NULL); ASSERT(simg != NULL);
@ -818,7 +818,7 @@ copy_buffer_pixmap(unsigned char mode, unsigned long fill, unsigned short width,
} }
void 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; XGCValues gcvalue;

View File

@ -102,7 +102,7 @@ encoding_t encoding_method = LATIN1;
/* Fill part/all of a drawn line with blanks. */ /* 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 *, rend_t *, int, rend_t);
inline void 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; */ /* int i = width; */
register unsigned int i = width; register unsigned int i = width;
@ -2713,7 +2713,7 @@ selection_click(int clicks, int x, int y)
#endif #endif
void void
selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) selection_delimit_word(int col, int row, row_col_t *beg, row_col_t *end)
{ {
int beg_col, beg_row, end_col, end_row, last_col; int beg_col, beg_row, end_col, end_row, last_col;
int row_offset, w1; int row_offset, w1;

View File

@ -94,7 +94,7 @@ scrollbar_event_init_dispatcher(void)
} }
unsigned char unsigned char
sb_handle_enter_notify(event_t * ev) sb_handle_enter_notify(event_t *ev)
{ {
D_EVENTS(("sb_handle_enter_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_enter_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -114,7 +114,7 @@ sb_handle_enter_notify(event_t * ev)
} }
unsigned char unsigned char
sb_handle_leave_notify(event_t * ev) sb_handle_leave_notify(event_t *ev)
{ {
D_EVENTS(("sb_handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -134,7 +134,7 @@ sb_handle_leave_notify(event_t * ev)
} }
unsigned char unsigned char
sb_handle_focus_in(event_t * ev) sb_handle_focus_in(event_t *ev)
{ {
D_EVENTS(("sb_handle_focus_in(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_focus_in(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -145,7 +145,7 @@ sb_handle_focus_in(event_t * ev)
} }
unsigned char unsigned char
sb_handle_focus_out(event_t * ev) sb_handle_focus_out(event_t *ev)
{ {
D_EVENTS(("sb_handle_focus_out(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_focus_out(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -156,7 +156,7 @@ sb_handle_focus_out(event_t * ev)
} }
unsigned char unsigned char
sb_handle_expose(event_t * ev) sb_handle_expose(event_t *ev)
{ {
XEvent unused_xevent; XEvent unused_xevent;
@ -181,7 +181,7 @@ sb_handle_expose(event_t * ev)
} }
unsigned char unsigned char
sb_handle_button_press(event_t * ev) sb_handle_button_press(event_t *ev)
{ {
D_EVENTS(("sb_handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -282,7 +282,7 @@ sb_handle_button_press(event_t * ev)
} }
unsigned char unsigned char
sb_handle_button_release(event_t * ev) sb_handle_button_release(event_t *ev)
{ {
Window root, child; Window root, child;
@ -321,7 +321,7 @@ sb_handle_button_release(event_t * ev)
} }
unsigned char unsigned char
sb_handle_motion_notify(event_t * ev) sb_handle_motion_notify(event_t *ev)
{ {
D_EVENTS(("sb_handle_motion_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); D_EVENTS(("sb_handle_motion_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window));
@ -349,7 +349,7 @@ sb_handle_motion_notify(event_t * ev)
} }
unsigned char unsigned char
scrollbar_dispatch_event(event_t * ev) scrollbar_dispatch_event(event_t *ev)
{ {
if (scrollbar_event_data.handlers[ev->type] != NULL) { if (scrollbar_event_data.handlers[ev->type] != NULL) {
return ((scrollbar_event_data.handlers[ev->type]) (ev)); return ((scrollbar_event_data.handlers[ev->type]) (ev));