Cleaning up some OSK code to avoid leaking so much memory.

Note: Planning to make keyboards load once, rather than every
time a switch happens.
Some other memory leak fixes.
This commit is contained in:
William Kendrick 2014-04-23 08:20:50 +00:00
parent 25e582c438
commit 19f5adaf4d
3 changed files with 63 additions and 49 deletions

View file

@ -5,7 +5,6 @@
//#define DEBUG_OSK_COMPOSEMAP //#define DEBUG_OSK_COMPOSEMAP
static TTF_Font * osk_fonty;
static SDL_Color def_bgcolor = {255, 255, 255, 255}; static SDL_Color def_bgcolor = {255, 255, 255, 255};
static SDL_Color def_fgcolor = {0, 0, 0, 0}; static SDL_Color def_fgcolor = {0, 0, 0, 0};
@ -73,6 +72,8 @@ struct osk_keyboard *osk_create(char *layout_name, SDL_Surface *canvas, SDL_Surf
keyboard = malloc(sizeof(on_screen_keyboard)); keyboard = malloc(sizeof(on_screen_keyboard));
keyboard->osk_fonty = NULL;
keyboard->disable_change = disable_change; keyboard->disable_change = disable_change;
layout = load_layout(keyboard, layout_name); layout = load_layout(keyboard, layout_name);
if (!layout) if (!layout)
@ -155,6 +156,7 @@ static struct osk_layout *load_layout(on_screen_keyboard *keyboard, char *layout
osk_layout *layout; osk_layout *layout;
layout = malloc(sizeof(osk_layout)); layout = malloc(sizeof(osk_layout));
layout->name = NULL;
hlayout_loaded = 0; hlayout_loaded = 0;
#ifdef DEBUG #ifdef DEBUG
printf("load_layout %s\n", layout_name); printf("load_layout %s\n", layout_name);
@ -575,6 +577,7 @@ static void gettokens(char * line, char * delim, char ** pointer, osk_composenod
if (tok[0] == ':') /* End of precompose keysyms, next will be the result in UTF-8. */ if (tok[0] == ':') /* End of precompose keysyms, next will be the result in UTF-8. */
{ {
free(tok);
tok = strdup(strtok_r(line, ": \"\t", pointer)); tok = strdup(strtok_r(line, ": \"\t", pointer));
mbstowcs(wtok, tok, 255); mbstowcs(wtok, tok, 255);
@ -637,6 +640,7 @@ static void gettokens(char * line, char * delim, char ** pointer, osk_composenod
/* printf("size %d, keysym %ls =>", composenode->size, composenode->childs[composenode->size - 1]->keysym); */ /* printf("size %d, keysym %ls =>", composenode->size, composenode->childs[composenode->size - 1]->keysym); */
gettokens(NULL, delim, pointer, composenode->childs[composenode->size - 1], layout); gettokens(NULL, delim, pointer, composenode->childs[composenode->size - 1], layout);
free(tok);
return; return;
} }
} }
@ -988,40 +992,40 @@ static void keybd_prepare(on_screen_keyboard *keyboard)
char * fontname; char * fontname;
fontname = malloc(sizeof(char) * 255); fontname = malloc(sizeof(char) * 255);
if (keyboard->osk_fonty == NULL) {
if (keyboard->layout->fontpath) if (keyboard->layout->fontpath)
{ {
/* First try if it is an absolute path */ /* First try if it is an absolute path */
osk_fonty = TTF_OpenFont( keyboard->layout->fontpath, 12 ); keyboard->osk_fonty = TTF_OpenFont( keyboard->layout->fontpath, 12 );
if (osk_fonty == NULL) if (keyboard->osk_fonty == NULL)
{ {
/* Now trying if it is relative to DATA_PREFIX/fonts/ */ /* Now trying if it is relative to DATA_PREFIX/fonts/ */
snprintf(fontname, 255, "%s/fonts/%s", DATA_PREFIX, keyboard->layout->fontpath); snprintf(fontname, 255, "%s/fonts/%s", DATA_PREFIX, keyboard->layout->fontpath);
osk_fonty = TTF_OpenFont( fontname, 12 ); keyboard->osk_fonty = TTF_OpenFont( fontname, 12 );
if (osk_fonty == NULL) if (keyboard->osk_fonty == NULL)
{ {
/* Perhaps it is relative to DATA_PREFIX only? */ /* Perhaps it is relative to DATA_PREFIX only? */
snprintf(fontname, 255, "%s/%s", DATA_PREFIX, keyboard->layout->fontpath); snprintf(fontname, 255, "%s/%s", DATA_PREFIX, keyboard->layout->fontpath);
osk_fonty = TTF_OpenFont( fontname, 12 ); keyboard->osk_fonty = TTF_OpenFont( fontname, 12 );
if (osk_fonty == NULL) if (keyboard->osk_fonty == NULL)
{ {
/* Or to DATA_PREFIX/fonts/locale/ ? */ /* Or to DATA_PREFIX/fonts/locale/ ? */
snprintf(fontname, 255, "%s/fonts/locale/%s", DATA_PREFIX, keyboard->layout->fontpath); snprintf(fontname, 255, "%s/fonts/locale/%s", DATA_PREFIX, keyboard->layout->fontpath);
osk_fonty = TTF_OpenFont( fontname, 12 ); keyboard->osk_fonty = TTF_OpenFont( fontname, 12 );
} }
} }
} }
} }
if (osk_fonty == NULL) if (keyboard->osk_fonty == NULL)
{ {
/* Going with the default */ /* Going with the default */
sprintf(fontname, "%s/fonts/FreeSansBold.ttf", DATA_PREFIX); sprintf(fontname, "%s/fonts/FreeSansBold.ttf", DATA_PREFIX);
osk_fonty = TTF_OpenFont( fontname, 12 ); keyboard->osk_fonty = TTF_OpenFont( fontname, 12 );
} }
if (osk_fonty == NULL) if (keyboard->osk_fonty == NULL)
{ {
fprintf(stderr, "\nError: Can't open the font!\n" fprintf(stderr, "\nError: Can't open the font!\n"
"The Simple DirectMedia Layer error that occurred was:\n" "The Simple DirectMedia Layer error that occurred was:\n"
@ -1032,6 +1036,7 @@ static void keybd_prepare(on_screen_keyboard *keyboard)
free(fontname); free(fontname);
} }
}
static void apply_surface (int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip) static void apply_surface (int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip)
@ -1302,7 +1307,7 @@ static void label_key(osk_key key, on_screen_keyboard *keyboard)
else if( strncmp("SPACE", text, 5) != 0 && strncmp("NULL", text, 4) != 0) else if( strncmp("SPACE", text, 5) != 0 && strncmp("NULL", text, 4) != 0)
{ {
messager = TTF_RenderUTF8_Blended(osk_fonty, text, keyboard->layout->fgcolor); messager = TTF_RenderUTF8_Blended(keyboard->osk_fonty, text, keyboard->layout->fgcolor);
apply_surface( key.x + 5, key.y, messager, keyboard->surface, NULL); apply_surface( key.x + 5, key.y, messager, keyboard->surface, NULL);
SDL_FreeSurface(messager); SDL_FreeSurface(messager);
@ -1859,9 +1864,10 @@ static void free_keys(osk_layout *layout)
static void free_layout(osk_layout *layout) static void free_layout(osk_layout *layout)
{ {
// free(layout->name); if (layout->name != NULL)
free(layout->name);
// free(layout->rows); // free(layout->rows);
// free(layout->fontpath); free(layout->fontpath);
free_keys(layout); free_keys(layout);
free_keymap(layout->keymap); free_keymap(layout->keymap);
free_composemap(layout->composemap); free_composemap(layout->composemap);
@ -1887,6 +1893,8 @@ void osk_free(on_screen_keyboard *keyboard)
set_key(NULL, &keyboard->keymodifiers.altgr, 0); set_key(NULL, &keyboard->keymodifiers.altgr, 0);
set_key(NULL, &keyboard->keymodifiers.compose, 0); set_key(NULL, &keyboard->keymodifiers.compose, 0);
set_key(NULL, &keyboard->keymodifiers.dead, 0); set_key(NULL, &keyboard->keymodifiers.dead, 0);
if (keyboard->osk_fonty != NULL)
TTF_CloseFont(keyboard->osk_fonty);
free(keyboard); free(keyboard);
} }

View file

@ -123,6 +123,7 @@ typedef struct osk_keyboard
osk_kmdf kmdf; osk_kmdf kmdf;
osk_layout *layout; /* The layout struct */ osk_layout *layout; /* The layout struct */
char *layout_name[256]; /* The layout name */ char *layout_name[256]; /* The layout name */
TTF_Font * osk_fonty; /* Font */
int disable_change; /* If true, stay with the first layout found */ int disable_change; /* If true, stay with the first layout found */
wchar_t * key[256]; /* The text of the key */ wchar_t * key[256]; /* The text of the key */
int keycode; /* The unicode code corresponding to the key */ int keycode; /* The unicode code corresponding to the key */

View file

@ -852,12 +852,12 @@ static void setup_screen_layout(void)
#endif #endif
} }
static SDL_Surface *screen; static SDL_Surface *screen = NULL;
static SDL_Surface *canvas; static SDL_Surface *canvas = NULL;
static SDL_Surface *label; static SDL_Surface *label = NULL;
static SDL_Surface *save_canvas; static SDL_Surface *save_canvas = NULL;
static SDL_Surface *canvas_back; static SDL_Surface *canvas_back = NULL;
static SDL_Surface *img_starter, *img_starter_bkgd; static SDL_Surface *img_starter = NULL, *img_starter_bkgd = NULL;
/* Update a rect. based on two x/y coords (not necessarly in order): */ /* Update a rect. based on two x/y coords (not necessarly in order): */
static void update_screen(int x1, int y1, int x2, int y2) static void update_screen(int x1, int y1, int x2, int y2)
@ -7797,6 +7797,7 @@ static SDL_Surface *do_loadimage(const char *const fname, int abort_on_error)
"The Simple DirectMedia Layer error that occurred was:\n" "The Simple DirectMedia Layer error that occurred was:\n"
"%s\n\n", fname, SDL_GetError()); "%s\n\n", fname, SDL_GetError());
SDL_FreeSurface(s);
cleanup(); cleanup();
exit(1); exit(1);
} }
@ -12213,6 +12214,7 @@ static void cleanup(void)
free_surface(&img_starter); free_surface(&img_starter);
free_surface(&img_starter_bkgd); free_surface(&img_starter_bkgd);
free_surface(&canvas); free_surface(&canvas);
free_surface(&save_canvas);
free_surface(&img_cur_brush); free_surface(&img_cur_brush);
if (touched != NULL) if (touched != NULL)
@ -14620,7 +14622,7 @@ static int do_open(void)
starter_personal = 0; starter_personal = 0;
org_surf = SDL_DisplayFormat(img); /* Keep a copy of the original image org_surf = SDL_DisplayFormat(img); /* Keep a copy of the original image
unescaled to send to load_embedded_data */ unscaled to send to load_embedded_data */
autoscale_copy_smear_free(img, canvas, SDL_BlitSurface); autoscale_copy_smear_free(img, canvas, SDL_BlitSurface);
cur_undo = 0; cur_undo = 0;
@ -21167,6 +21169,7 @@ void load_embedded_data(char *fname, SDL_Surface * org_surf)
fp = fopen(fname, "rb"); fp = fopen(fname, "rb");
if (!fp) if (!fp)
{ {
SDL_FreeSurface(org_surf);
return; return;
} }
@ -21178,6 +21181,7 @@ void load_embedded_data(char *fname, SDL_Surface * org_surf)
fprintf(stderr, "\nError: Couldn't open the image!\n%s\n\n", fname); fprintf(stderr, "\nError: Couldn't open the image!\n%s\n\n", fname);
draw_tux_text(TUX_OOPS, strerror(errno), 0); draw_tux_text(TUX_OOPS, strerror(errno), 0);
SDL_FreeSurface(org_surf);
return; return;
} }
else else
@ -21192,6 +21196,7 @@ void load_embedded_data(char *fname, SDL_Surface * org_surf)
fprintf(stderr, "\nError: Couldn't open the image!\n%s\n\n", fname); fprintf(stderr, "\nError: Couldn't open the image!\n%s\n\n", fname);
draw_tux_text(TUX_OOPS, strerror(errno), 0); draw_tux_text(TUX_OOPS, strerror(errno), 0);
SDL_FreeSurface(org_surf);
return; return;
} }