summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine/skin_buffer.c
blob: eb33cbe293a982089835d16e68b95d8c6d265739 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id: wps_parser.c 19880 2009-01-29 20:49:43Z mcuelenaere $
 *
 * Copyright (C) 2002 by Linus Nielsen Feltzing
 * Copyright (C) 2009 Jonathan Gordon
 *
 * 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 <string.h>
#include <stdlib.h>
#include "config.h"
#include "buffer.h"
#include "settings.h"
#include "screen_access.h"
#include "wps_internals.h"
#include "skin_tokens.h"
#include "skin_buffer.h"

/* skin buffer management.
 * This module is used to allocate space in a single global skin buffer for
 * tokens for both/all screens.
 *
 * This is mostly just copy/paste from firmware/buffer.c
 *
 *
 * MAIN_ and REMOTE_BUFFER are just for reasonable size calibration,
 * both screens can use the whole buffer as they need; it's not split
 * between screens
 *
 * Buffer can be allocated from either "end" of the global buffer.
 * items with unknown sizes get allocated from the start (0->)      (data)
 * items with known sizes get allocated from the end (<-buf_size)   (tokens)
 * After loading 2 skins the buffer will look like this:
 *  |tokens skin1|images skin2|---SPACE---|data skin2|data skin1|
 * Make sure to never start allocating from the beginning before letting us know
 * how much was used. and RESPECT THE buf_free RETURN VALUES!
 *
 */


#ifdef HAVE_LCD_BITMAP
#define MAIN_BUFFER ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
                            + (2*LCD_HEIGHT*LCD_WIDTH/8))

#if (NB_SCREENS > 1)
#define REMOTE_BUFFER ((LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8) \
                            + (2*LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH/8))
#else
#define REMOTE_BUFFER 0
#endif


#define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER) + \
                         (WPS_MAX_TOKENS * sizeof(struct wps_token))
#endif

#ifdef HAVE_LCD_CHARCELLS
#define SKIN_BUFFER_SIZE (LCD_HEIGHT * LCD_WIDTH) * 64 + \
                         (WPS_MAX_TOKENS * sizeof(struct wps_token))
#endif

static unsigned char buffer[SKIN_BUFFER_SIZE];
static unsigned char *buffer_front = NULL; /* start of the free space,
                                              increases with allocation*/
static unsigned char *buffer_back  = NULL; /* end of the free space
                                              decreases with allocation */
static size_t buf_size = SKIN_BUFFER_SIZE;

void skin_buffer_init(void)
{
#if 0 /* this will go in again later probably */
    if (buffer == NULL)
    {
        buf_size = SKIN_BUFFER_SIZE;/* global_settings.skin_buf_size */

        buffer = buffer_alloc(buf_size);
        buffer_front = buffer;
        buffer_back = bufer + buf_size;
    }
    else
#endif
    {
        /* reset the buffer.... */
        buffer_front = buffer;
        buffer_back = buffer + buf_size;
    }
}

/* get the number of bytes currently being used */
size_t skin_buffer_usage(void)
{
    return buf_size - (buffer_back-buffer_front);
}

size_t skin_buffer_freespace(void)
{
    return buffer_back-buffer_front;
}

/* Allocate size bytes from the buffer
 * allocates from the back end (data end)
 */
void* skin_buffer_alloc(size_t size)
{
    if (skin_buffer_freespace() <= size)
    {
        return NULL;
    }
    buffer_back -= size;
    /* 32-bit aligned */
    buffer_back = (void *)(((unsigned long)buffer_back) & ~3);

    memset(buffer_back, 0, size);
    return buffer_back;
}

/* Get a pointer to the skin buffer and the count of how much is free
 * used to do your own buffer management.
 * Any memory used will be overwritten next time wps_buffer_alloc()
 * is called unless skin_buffer_increment() is called first
 *
 * This is from the start of the buffer, it is YOUR responsility to make
 * sure you dont ever use more then *freespace, and bear in mind this will only
 * be valid untill skin_buffer_alloc() is next called...
 * so call skin_buffer_increment() and skin_buffer_freespace() regularly
 */
void* skin_buffer_grab(size_t *freespace)
{
    *freespace = buf_size - skin_buffer_usage();
    return buffer_front;
}

/* Use after skin_buffer_grab() to specify how much buffer was used */
void skin_buffer_increment(size_t used, bool align)
{
    buffer_front += used;
    if (align)
    {
        /* 32-bit aligned */
        buffer_front = (void *)(((unsigned long)buffer_front + 3) & ~3);
    }
}

/* free previously skin_buffer_increment()'ed space. This just moves the pointer
 * back 'used' bytes so make sure you actually want to do this */
void skin_buffer_free_from_front(size_t used)
{
    buffer_front -= used;
    /* 32-bit aligned */
    buffer_front = (void *)(((unsigned long)buffer_front + 3) & ~3);
}