1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 * Copyright (C) 2009 Jonathan Gordon
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
29 #include "screen_access.h"
30 #include "skin_engine.h"
31 #include "wps_internals.h"
32 #include "skin_tokens.h"
33 #include "skin_buffer.h"
35 /* skin buffer management.
36 * This module is used to allocate space in a single global skin buffer for
37 * tokens for both/all screens.
39 * This is mostly just copy/paste from firmware/buffer.c
42 * MAIN_ and REMOTE_BUFFER are just for reasonable size calibration,
43 * both screens can use the whole buffer as they need; it's not split
46 * Buffer can be allocated from either "end" of the global buffer.
47 * items with unknown sizes get allocated from the start (0->) (data)
48 * items with known sizes get allocated from the end (<-buf_size) (tokens)
49 * After loading 2 skins the buffer will look like this:
50 * |tokens skin1|images skin1|tokens s2|images s2|---SPACE---|data skin2|data skin1|
51 * Make sure to never start allocating from the beginning before letting us know
52 * how much was used. and RESPECT THE buf_free RETURN VALUES!
57 #ifdef HAVE_LCD_BITMAP
58 #define MAIN_BUFFER ((2*LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
59 + (SKINNABLE_SCREENS_COUNT * LCD_BACKDROP_BYTES))
62 #define REMOTE_BUFFER (2*(LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8) \
63 + (SKINNABLE_SCREENS_COUNT * REMOTE_LCD_BACKDROP_BYTES))
65 #define REMOTE_BUFFER 0
69 #define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER) + \
70 (WPS_MAX_TOKENS * sizeof(struct wps_token))
73 #ifdef HAVE_LCD_CHARCELLS
74 #define SKIN_BUFFER_SIZE (LCD_HEIGHT * LCD_WIDTH) * 64 + \
75 (WPS_MAX_TOKENS * sizeof(struct wps_token))
78 static unsigned char buffer
[SKIN_BUFFER_SIZE
];
79 static unsigned char *buffer_front
= NULL
; /* start of the free space,
80 increases with allocation*/
81 static unsigned char *buffer_back
= NULL
; /* end of the free space
82 decreases with allocation */
83 static size_t buf_size
= SKIN_BUFFER_SIZE
;
85 void skin_buffer_init(void)
87 #if 0 /* this will go in again later probably */
90 buf_size
= SKIN_BUFFER_SIZE
;/* global_settings.skin_buf_size */
92 buffer
= buffer_alloc(buf_size
);
93 buffer_front
= buffer
;
94 buffer_back
= bufer
+ buf_size
;
99 /* reset the buffer.... */
100 buffer_front
= buffer
;
101 buffer_back
= buffer
+ buf_size
;
105 /* get the number of bytes currently being used */
106 size_t skin_buffer_usage(void)
108 return buf_size
- (buffer_back
-buffer_front
);
111 size_t skin_buffer_freespace(void)
113 return buffer_back
-buffer_front
;
116 /* Allocate size bytes from the buffer
117 * allocates from the back end (data end)
119 void* skin_buffer_alloc(size_t size
)
121 if (skin_buffer_freespace() <= size
)
127 buffer_back
= (void *)(((unsigned long)buffer_back
) & ~3);
129 memset(buffer_back
, 0, size
);
133 /* Get a pointer to the skin buffer and the count of how much is free
134 * used to do your own buffer management.
135 * Any memory used will be overwritten next time wps_buffer_alloc()
136 * is called unless skin_buffer_increment() is called first
138 * This is from the start of the buffer, it is YOUR responsility to make
139 * sure you dont ever use more then *freespace, and bear in mind this will only
140 * be valid untill skin_buffer_alloc() is next called...
141 * so call skin_buffer_increment() and skin_buffer_freespace() regularly
143 void* skin_buffer_grab(size_t *freespace
)
145 *freespace
= buf_size
- skin_buffer_usage();
149 /* Use after skin_buffer_grab() to specify how much buffer was used */
150 void skin_buffer_increment(size_t used
, bool align
)
152 buffer_front
+= used
;
156 buffer_front
= (void *)(((unsigned long)buffer_front
+ 3) & ~3);
160 /* free previously skin_buffer_increment()'ed space. This just moves the pointer
161 * back 'used' bytes so make sure you actually want to do this */
162 void skin_buffer_free_from_front(size_t used
)
164 buffer_front
-= used
;
166 buffer_front
= (void *)(((unsigned long)buffer_front
+ 3) & ~3);