2010-09-14 11:59:52 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
2013-02-11 12:58:52 +00:00
|
|
|
* Copyright (C) 2010 Jonathan Gordon
|
2010-09-14 11:59:52 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include "inttypes.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "action.h"
|
|
|
|
#include "crc32.h"
|
|
|
|
#include "settings.h"
|
2021-04-10 14:42:38 +00:00
|
|
|
#include "rbpaths.h"
|
2010-09-14 11:59:52 +00:00
|
|
|
#include "wps.h"
|
|
|
|
#include "file.h"
|
2020-11-01 17:25:39 +00:00
|
|
|
#include "misc.h"
|
2010-09-14 11:59:52 +00:00
|
|
|
#if CONFIG_TUNER
|
|
|
|
#include "radio.h"
|
|
|
|
#endif
|
2022-10-02 17:02:27 +00:00
|
|
|
#include "gui/list.h"
|
2010-09-14 11:59:52 +00:00
|
|
|
#include "skin_engine.h"
|
|
|
|
#include "skin_buffer.h"
|
|
|
|
#include "statusbar-skinned.h"
|
2022-10-02 17:02:27 +00:00
|
|
|
#include "wps_internals.h"
|
2010-09-14 11:59:52 +00:00
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
#define FAILSAFENAME "rockbox_failsafe"
|
2010-09-14 11:59:52 +00:00
|
|
|
|
2011-09-15 13:48:17 +00:00
|
|
|
void skin_data_free_buflib_allocs(struct wps_data *wps_data);
|
2019-02-07 11:30:11 +00:00
|
|
|
#ifdef HAVE_ALBUMART
|
|
|
|
void playback_release_aa_slot(int slot);
|
|
|
|
#endif
|
2010-09-14 11:59:52 +00:00
|
|
|
char* wps_default_skin(enum screen_type screen);
|
|
|
|
char* default_radio_skin(enum screen_type screen);
|
2011-11-28 10:44:16 +00:00
|
|
|
static bool skins_initialised = false;
|
2010-09-14 12:21:56 +00:00
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
static char* get_skin_filename(char *buf, size_t buf_size,
|
|
|
|
enum skinnable_screens skin, enum screen_type screen);
|
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
static struct gui_skin_helper {
|
|
|
|
int (*preproccess)(enum screen_type screen, struct wps_data *data);
|
|
|
|
int (*postproccess)(enum screen_type screen, struct wps_data *data);
|
|
|
|
char* (*default_skin)(enum screen_type screen);
|
2011-11-21 10:03:36 +00:00
|
|
|
bool load_on_boot;
|
2010-09-14 11:59:52 +00:00
|
|
|
} skin_helpers[SKINNABLE_SCREENS_COUNT] = {
|
2011-11-21 10:03:36 +00:00
|
|
|
[CUSTOM_STATUSBAR] = { sb_preproccess, sb_postproccess, sb_create_from_settings, true },
|
|
|
|
[WPS] = { NULL, NULL, wps_default_skin, true },
|
2010-09-14 11:59:52 +00:00
|
|
|
#if CONFIG_TUNER
|
2011-11-21 10:03:36 +00:00
|
|
|
[FM_SCREEN] = { NULL, NULL, default_radio_skin, false }
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
|
|
|
};
|
2011-11-21 10:02:23 +00:00
|
|
|
|
2010-10-16 15:23:41 +00:00
|
|
|
static struct gui_skin {
|
2010-09-14 11:59:52 +00:00
|
|
|
struct gui_wps gui_wps;
|
|
|
|
struct wps_data data;
|
2013-02-12 10:00:05 +00:00
|
|
|
struct skin_stats stats;
|
2011-11-21 10:02:23 +00:00
|
|
|
bool failsafe_loaded;
|
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
bool needs_full_update;
|
|
|
|
} skins[SKINNABLE_SCREENS_COUNT][NB_SCREENS];
|
|
|
|
|
2013-02-12 10:00:05 +00:00
|
|
|
int skin_get_num_skins(void)
|
|
|
|
{
|
|
|
|
return SKINNABLE_SCREENS_COUNT;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct skin_stats *skin_get_stats(int number, int screen)
|
|
|
|
{
|
|
|
|
return &skins[number][screen].stats;
|
|
|
|
}
|
2010-09-14 11:59:52 +00:00
|
|
|
|
2011-12-20 20:35:28 +00:00
|
|
|
static void gui_skin_reset(struct gui_skin *skin)
|
2010-09-14 11:59:52 +00:00
|
|
|
{
|
2013-05-14 05:03:44 +00:00
|
|
|
struct wps_data *data;
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->failsafe_loaded = false;
|
|
|
|
skin->needs_full_update = true;
|
2013-05-14 05:03:44 +00:00
|
|
|
skin->gui_wps.data = data = &skin->data;
|
2013-06-09 19:01:17 +00:00
|
|
|
#ifdef HAVE_ALBUMART
|
2013-06-09 19:08:49 +00:00
|
|
|
struct skin_albumart *aa_save;
|
2013-06-20 05:14:14 +00:00
|
|
|
unsigned char *buffer = get_skin_buffer(data);
|
2013-06-09 19:08:49 +00:00
|
|
|
/* copy to temp var to protect against memset */
|
2013-06-20 05:14:14 +00:00
|
|
|
if (buffer && (aa_save = SKINOFFSETTOPTR(buffer, data->albumart)))
|
2013-05-14 05:03:44 +00:00
|
|
|
{
|
|
|
|
short old_width, old_height;
|
|
|
|
old_width = aa_save->width;
|
|
|
|
old_height = aa_save->height;
|
|
|
|
memset(data, 0, sizeof(struct wps_data));
|
|
|
|
data->last_albumart_width = old_width;
|
|
|
|
data->last_albumart_height = old_height;
|
|
|
|
}
|
|
|
|
else
|
2013-06-09 19:01:17 +00:00
|
|
|
#endif
|
2013-05-14 05:03:44 +00:00
|
|
|
memset(data, 0, sizeof(struct wps_data));
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->data.wps_loaded = false;
|
|
|
|
skin->data.buflib_handle = -1;
|
|
|
|
skin->data.tree = -1;
|
2011-11-15 14:11:08 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->data.touchregions = -1;
|
2011-11-15 14:11:08 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SKIN_VARIABLES
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->data.skinvars = -1;
|
2011-11-15 14:11:08 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->data.font_ids = -1;
|
|
|
|
skin->data.images = -1;
|
2010-09-14 11:59:52 +00:00
|
|
|
#ifdef HAVE_ALBUMART
|
2011-11-21 10:02:23 +00:00
|
|
|
skin->data.albumart = -1;
|
|
|
|
skin->data.playback_aa_slot = -1;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_BACKDROP_IMAGE
|
|
|
|
skin->gui_wps.data->backdrop_id = -1;
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
void gui_sync_skin_init(void)
|
2011-09-15 13:48:17 +00:00
|
|
|
{
|
2011-10-15 19:35:02 +00:00
|
|
|
int j;
|
2011-09-24 13:19:34 +00:00
|
|
|
for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
|
2011-09-15 13:48:17 +00:00
|
|
|
{
|
2011-09-24 13:19:34 +00:00
|
|
|
FOR_NB_SCREENS(i)
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
2011-09-15 13:48:17 +00:00
|
|
|
skin_data_free_buflib_allocs(&skins[j][i].data);
|
2013-12-30 12:35:23 +00:00
|
|
|
#ifdef HAVE_BACKDROP_IMAGE
|
2013-12-29 06:53:19 +00:00
|
|
|
if (skins[j][i].data.backdrop_id != -1)
|
|
|
|
skin_backdrop_unload(skins[j][i].data.backdrop_id);
|
2013-12-30 12:35:23 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
gui_skin_reset(&skins[j][i]);
|
|
|
|
skins[j][i].gui_wps.display = &screens[i];
|
|
|
|
}
|
2011-09-15 13:48:17 +00:00
|
|
|
}
|
2011-11-21 10:02:23 +00:00
|
|
|
}
|
2011-09-15 13:48:17 +00:00
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
void skin_unload_all(void)
|
|
|
|
{
|
2011-09-15 13:48:17 +00:00
|
|
|
gui_sync_skin_init();
|
2011-09-28 01:02:48 +00:00
|
|
|
}
|
|
|
|
|
2022-03-16 00:17:11 +00:00
|
|
|
static void skin_reset_buffers(int item, int screen)
|
|
|
|
{
|
|
|
|
skin_data_free_buflib_allocs(&skins[item][screen].data);
|
|
|
|
#ifdef HAVE_ALBUMART
|
|
|
|
if (skins[item][screen].data.playback_aa_slot >= 0)
|
|
|
|
playback_release_aa_slot(skins[item][screen].data.playback_aa_slot);
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_BACKDROP_IMAGE
|
|
|
|
if (skins[item][screen].data.backdrop_id >= 0)
|
|
|
|
skin_backdrop_unload(skins[item][screen].data.backdrop_id);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-09-28 01:02:48 +00:00
|
|
|
void settings_apply_skins(void)
|
|
|
|
{
|
2011-10-15 19:35:02 +00:00
|
|
|
int i;
|
2011-11-21 10:02:23 +00:00
|
|
|
char filename[MAX_PATH];
|
2011-09-15 13:48:17 +00:00
|
|
|
|
2021-10-21 21:38:44 +00:00
|
|
|
if (audio_status() & AUDIO_STATUS_PLAY)
|
|
|
|
audio_stop();
|
|
|
|
|
2022-03-16 00:17:11 +00:00
|
|
|
bool first_run = skin_backdrop_init();
|
2011-11-28 10:44:16 +00:00
|
|
|
skins_initialised = true;
|
|
|
|
|
2011-09-15 13:48:17 +00:00
|
|
|
/* Make sure each skin is loaded */
|
|
|
|
for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
|
|
|
|
{
|
|
|
|
FOR_NB_SCREENS(j)
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
|
|
|
get_skin_filename(filename, MAX_PATH, i,j);
|
|
|
|
|
2011-11-28 10:58:15 +00:00
|
|
|
if (!first_run)
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
2022-03-16 00:17:11 +00:00
|
|
|
skin_reset_buffers(i, j);
|
2011-11-21 10:02:23 +00:00
|
|
|
}
|
2011-11-28 10:58:15 +00:00
|
|
|
gui_skin_reset(&skins[i][j]);
|
|
|
|
skins[i][j].gui_wps.display = &screens[j];
|
|
|
|
if (skin_helpers[i].load_on_boot)
|
|
|
|
skin_get_gwps(i, j);
|
2011-11-21 10:02:23 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-16 00:17:11 +00:00
|
|
|
|
2014-01-22 15:58:47 +00:00
|
|
|
/* any backdrop that was loaded with "-" has to be reloaded because
|
|
|
|
* the setting may have changed */
|
|
|
|
skin_backdrop_load_setting();
|
2011-09-15 13:48:17 +00:00
|
|
|
viewportmanager_theme_changed(THEME_STATUSBAR);
|
2022-03-16 00:17:11 +00:00
|
|
|
|
2011-09-15 13:48:17 +00:00
|
|
|
FOR_NB_SCREENS(i)
|
|
|
|
skin_backdrop_show(sb_get_backdrop(i));
|
|
|
|
}
|
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
void skin_load(enum skinnable_screens skin, enum screen_type screen,
|
|
|
|
const char *buf, bool isfile)
|
|
|
|
{
|
|
|
|
bool loaded = false;
|
2011-11-21 10:02:23 +00:00
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
if (skin_helpers[skin].preproccess)
|
|
|
|
skin_helpers[skin].preproccess(screen, &skins[skin][screen].data);
|
2011-11-21 10:02:23 +00:00
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
if (buf && *buf)
|
2013-02-12 10:00:05 +00:00
|
|
|
loaded = skin_data_load(screen, &skins[skin][screen].data, buf, isfile,
|
|
|
|
&skins[skin][screen].stats);
|
2010-09-14 11:59:52 +00:00
|
|
|
|
|
|
|
if (!loaded && skin_helpers[skin].default_skin)
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
2010-09-14 11:59:52 +00:00
|
|
|
loaded = skin_data_load(screen, &skins[skin][screen].data,
|
2013-02-12 10:00:05 +00:00
|
|
|
skin_helpers[skin].default_skin(screen), false,
|
|
|
|
&skins[skin][screen].stats);
|
2011-11-21 10:02:23 +00:00
|
|
|
skins[skin][screen].failsafe_loaded = loaded;
|
|
|
|
}
|
|
|
|
|
2010-09-14 11:59:52 +00:00
|
|
|
skins[skin][screen].needs_full_update = true;
|
|
|
|
if (skin_helpers[skin].postproccess)
|
|
|
|
skin_helpers[skin].postproccess(screen, &skins[skin][screen].data);
|
2011-11-21 10:03:36 +00:00
|
|
|
#ifdef HAVE_BACKDROP_IMAGE
|
|
|
|
if (loaded)
|
|
|
|
skin_backdrops_preload();
|
|
|
|
#endif
|
2010-09-14 11:59:52 +00:00
|
|
|
}
|
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
static char* get_skin_filename(char *buf, size_t buf_size,
|
|
|
|
enum skinnable_screens skin, enum screen_type screen)
|
2010-09-14 11:59:52 +00:00
|
|
|
{
|
2011-11-21 10:02:23 +00:00
|
|
|
(void)screen;
|
|
|
|
char *setting = NULL, *ext = NULL;
|
|
|
|
switch (skin)
|
2010-09-14 11:59:52 +00:00
|
|
|
{
|
2012-06-19 19:51:59 +00:00
|
|
|
case CUSTOM_STATUSBAR:
|
2010-09-14 11:59:52 +00:00
|
|
|
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
2011-11-21 10:02:23 +00:00
|
|
|
if (screen == SCREEN_REMOTE)
|
|
|
|
{
|
|
|
|
setting = global_settings.rsbs_file;
|
|
|
|
ext = "rsbs";
|
|
|
|
}
|
|
|
|
else
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
|
|
|
setting = global_settings.sbs_file;
|
|
|
|
ext = "sbs";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WPS:
|
2010-09-14 11:59:52 +00:00
|
|
|
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
2011-11-21 10:02:23 +00:00
|
|
|
if (screen == SCREEN_REMOTE)
|
|
|
|
{
|
|
|
|
setting = global_settings.rwps_file;
|
|
|
|
ext = "rwps";
|
|
|
|
}
|
|
|
|
else
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
|
|
|
setting = global_settings.wps_file;
|
|
|
|
ext = "wps";
|
|
|
|
}
|
|
|
|
break;
|
2010-09-14 11:59:52 +00:00
|
|
|
#if CONFIG_TUNER
|
2011-11-21 10:02:23 +00:00
|
|
|
case FM_SCREEN:
|
2010-09-14 11:59:52 +00:00
|
|
|
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
2011-11-21 10:02:23 +00:00
|
|
|
if (screen == SCREEN_REMOTE)
|
|
|
|
{
|
|
|
|
setting = global_settings.rfms_file;
|
|
|
|
ext = "rfms";
|
|
|
|
}
|
|
|
|
else
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
{
|
|
|
|
setting = global_settings.fms_file;
|
|
|
|
ext = "fms";
|
|
|
|
}
|
|
|
|
break;
|
2010-09-14 11:59:52 +00:00
|
|
|
#endif
|
2011-11-21 10:02:23 +00:00
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[0] = '\0'; /* force it to reload the default */
|
|
|
|
if (strcmp(setting, FAILSAFENAME) && strcmp(setting, "-"))
|
|
|
|
{
|
|
|
|
snprintf(buf, buf_size, WPS_DIR "/%s.%s", setting, ext);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen)
|
|
|
|
{
|
2011-11-28 10:44:16 +00:00
|
|
|
if (skin == CUSTOM_STATUSBAR && !skins_initialised)
|
|
|
|
return &skins[skin][screen].gui_wps;
|
|
|
|
|
2011-11-21 10:02:23 +00:00
|
|
|
if (skins[skin][screen].data.wps_loaded == false)
|
|
|
|
{
|
|
|
|
char filename[MAX_PATH];
|
|
|
|
char *buf = get_skin_filename(filename, MAX_PATH, skin, screen);
|
2010-09-14 11:59:52 +00:00
|
|
|
cpu_boost(true);
|
|
|
|
skin_load(skin, screen, buf, true);
|
|
|
|
cpu_boost(false);
|
|
|
|
}
|
|
|
|
return &skins[skin][screen].gui_wps;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is called to find out if we the screen needs a full update.
|
|
|
|
* if true you MUST do a full update as the next call will return false */
|
|
|
|
bool skin_do_full_update(enum skinnable_screens skin,
|
|
|
|
enum screen_type screen)
|
|
|
|
{
|
2020-10-07 06:01:35 +00:00
|
|
|
struct viewport *vp = *(screens[screen].current_viewport);
|
|
|
|
|
2020-11-01 17:25:39 +00:00
|
|
|
bool vp_is_dirty = ((vp->flags & VP_FLAG_VP_SET_CLEAN) == VP_FLAG_VP_DIRTY) &&
|
|
|
|
get_current_activity() == ACTIVITY_WPS;
|
2020-10-07 06:01:35 +00:00
|
|
|
|
|
|
|
bool ret = (skins[skin][screen].needs_full_update || vp_is_dirty);
|
2010-09-14 11:59:52 +00:00
|
|
|
skins[skin][screen].needs_full_update = false;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* tell a skin to do a full update next time */
|
|
|
|
void skin_request_full_update(enum skinnable_screens skin)
|
|
|
|
{
|
|
|
|
FOR_NB_SCREENS(i)
|
|
|
|
skins[skin][i].needs_full_update = true;
|
|
|
|
}
|
2022-10-02 17:02:27 +00:00
|
|
|
|
|
|
|
bool dbg_skin_engine(void)
|
|
|
|
{
|
|
|
|
struct simplelist_info info;
|
|
|
|
int i, total = 0;
|
|
|
|
#if defined(HAVE_BACKDROP_IMAGE)
|
|
|
|
int ref_count;
|
|
|
|
char *path;
|
|
|
|
size_t bytes;
|
|
|
|
int path_prefix_len = strlen(ROCKBOX_DIR "/wps/");
|
|
|
|
#endif
|
|
|
|
simplelist_info_init(&info, "Skin engine usage", 0, NULL);
|
|
|
|
simplelist_set_line_count(0);
|
|
|
|
FOR_NB_SCREENS(j) {
|
|
|
|
#if NB_SCREENS > 1
|
|
|
|
simplelist_addline("%s display:",
|
|
|
|
j == 0 ? "Main" : "Remote");
|
|
|
|
#endif
|
|
|
|
for (i = 0; i < skin_get_num_skins(); i++) {
|
|
|
|
struct skin_stats *stats = skin_get_stats(i, j);
|
|
|
|
if (stats->buflib_handles)
|
|
|
|
{
|
|
|
|
simplelist_addline("Skin ID: %d, %d allocations",
|
|
|
|
i, stats->buflib_handles);
|
|
|
|
simplelist_addline("\tskin: %d bytes",
|
|
|
|
stats->tree_size);
|
|
|
|
simplelist_addline("\tImages: %d bytes",
|
|
|
|
stats->images_size);
|
|
|
|
simplelist_addline("\tTotal: %d bytes",
|
|
|
|
stats->tree_size + stats->images_size);
|
|
|
|
total += stats->tree_size + stats->images_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
simplelist_addline("Skin total usage: %d bytes", total);
|
|
|
|
#if defined(HAVE_BACKDROP_IMAGE)
|
|
|
|
simplelist_addline("Backdrop Images:");
|
|
|
|
i = 0;
|
|
|
|
while (skin_backdrop_get_debug(i++, &path, &ref_count, &bytes)) {
|
|
|
|
if (ref_count > 0) {
|
|
|
|
|
|
|
|
if (!strncasecmp(path, ROCKBOX_DIR "/wps/", path_prefix_len))
|
|
|
|
path += path_prefix_len;
|
|
|
|
simplelist_addline("%s", path);
|
|
|
|
simplelist_addline("\tref_count: %d", ref_count);
|
|
|
|
simplelist_addline("\tsize: %d", bytes);
|
|
|
|
total += bytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
simplelist_addline("Total usage: %d bytes", total);
|
|
|
|
#endif
|
|
|
|
return simplelist_show_list(&info);
|
|
|
|
}
|