Fix Rockblox plugin display issues on Clip Zip
[maemo-rb.git] / firmware / logf.c
blobfc81ced77940738a9796b779f80c576569aa2c9a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Daniel Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 * logf() logs entries in a circular buffer. Each logged string is null-terminated.
25 * When the length of log exceeds MAX_LOGF_SIZE bytes, the buffer wraps.
29 #include <string.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include "config.h"
33 #include "system.h"
34 #include "font.h"
35 #ifdef HAVE_REMOTE_LCD
36 #include "lcd-remote.h"
37 #endif
38 #include "logf.h"
39 #include "serial.h"
40 #include "format.h"
42 #ifdef HAVE_USBSTACK
43 #include "usb_core.h"
44 #include "usbstack/usb_serial.h"
45 #endif
47 /* Only provide all this if asked to */
48 #ifdef ROCKBOX_HAS_LOGF
50 #ifndef __PCTOOL__
51 unsigned char logfbuffer[MAX_LOGF_SIZE];
52 int logfindex;
53 bool logfwrap;
54 #endif
56 #ifdef HAVE_REMOTE_LCD
57 static void displayremote(void)
59 /* TODO: we should have a debug option that enables/disables this! */
60 int w, h, i;
61 int fontnr;
62 int cur_x, cur_y, delta_y, delta_x;
63 struct font* font;
64 int nb_lines;
65 char buf[2];
66 /* Memorize the pointer to the beginning of the last ... lines
67 I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically
68 I hope there is no font with height < 6 ! */
69 const int NB_ENTRIES=LCD_REMOTE_HEIGHT / 6;
70 int line_start_ptr[NB_ENTRIES];
72 fontnr = lcd_getfont();
73 font = font_get(fontnr);
75 /* get the horizontal size of each line */
76 font_getstringsize("A", NULL, &delta_y, fontnr);
78 /* font too small ? */
79 if(delta_y < 6)
80 return;
81 /* nothing to print ? */
82 if(logfindex == 0 && !logfwrap)
83 return;
85 w = LCD_REMOTE_WIDTH;
86 h = LCD_REMOTE_HEIGHT;
87 nb_lines = 0;
89 if(logfwrap)
90 i = logfindex;
91 else
92 i = 0;
94 cur_x = 0;
96 line_start_ptr[0] = i;
100 if(logfbuffer[i] == '\0')
102 line_start_ptr[++nb_lines % NB_ENTRIES] = i+1;
103 cur_x = 0;
105 else
107 /* does character fit on this line ? */
108 delta_x = font_get_width(font, logfbuffer[i]);
110 if(cur_x + delta_x > w)
112 cur_x = 0;
113 line_start_ptr[++nb_lines % NB_ENTRIES] = i;
115 /* update pointer */
116 cur_x += delta_x;
118 i++;
119 if(i >= MAX_LOGF_SIZE)
120 i = 0;
121 } while(i != logfindex);
123 lcd_remote_clear_display();
125 i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES];
126 cur_x = 0;
127 cur_y = 0;
128 buf[1] = '\0';
130 do {
131 if(logfbuffer[i] == '\0')
133 cur_y += delta_y;
134 cur_x = 0;
136 else
138 /* does character fit on this line ? */
139 delta_x = font_get_width(font, logfbuffer[i]);
141 if(cur_x + delta_x > w)
143 cur_y += delta_y;
144 cur_x = 0;
147 buf[0] = logfbuffer[i];
148 lcd_remote_putsxy(cur_x, cur_y, buf);
149 cur_x += delta_x;
152 i++;
153 if(i >= MAX_LOGF_SIZE)
154 i = 0;
155 } while(i != logfindex);
157 lcd_remote_update();
159 #else
160 #define displayremote()
161 #endif
163 #ifdef __PCTOOL__
164 void _logf(const char *format, ...)
166 char buf[1024];
167 va_list ap;
168 va_start(ap, format);
170 vsnprintf(buf, sizeof buf, format, ap);
171 printf("DEBUG: %s\n", buf);
173 #else
174 static void check_logfindex(void)
176 if(logfindex >= MAX_LOGF_SIZE)
178 /* wrap */
179 logfwrap = true;
180 logfindex = 0;
184 static int logf_push(void *userp, unsigned char c)
186 (void)userp;
188 logfbuffer[logfindex++] = c;
189 check_logfindex();
191 #if defined(HAVE_SERIAL) && !defined(SIMULATOR) && defined(LOGF_SERIAL)
192 if(c != '\0')
194 char buf[2];
195 buf[0] = c;
196 buf[1] = '\0';
197 serial_tx(buf);
199 #endif
201 return true;
204 void _logf(const char *fmt, ...)
206 #ifdef USB_ENABLE_SERIAL
207 int old_logfindex = logfindex;
208 #endif
209 va_list ap;
211 va_start(ap, fmt);
213 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
214 char buf[1024];
215 vsnprintf(buf, sizeof buf, fmt, ap);
216 DEBUGF("%s\n", buf);
217 /* restart va_list otherwise the result if undefined when vuprintf is called */
218 va_end(ap);
219 va_start(ap, fmt);
220 #endif
222 vuprintf(logf_push, NULL, fmt, ap);
223 va_end(ap);
225 /* add trailing zero */
226 logf_push(NULL, '\0');
228 #if defined(HAVE_SERIAL) && !defined(SIMULATOR) && defined(LOGF_SERIAL)
229 serial_tx("\r\n");
230 #endif
231 #ifdef USB_ENABLE_SERIAL
233 if(logfindex < old_logfindex)
235 usb_serial_send(logfbuffer + old_logfindex, MAX_LOGF_SIZE - old_logfindex);
236 usb_serial_send(logfbuffer, logfindex - 1);
238 else
239 usb_serial_send(logfbuffer + old_logfindex, logfindex - old_logfindex - 1);
240 usb_serial_send("\r\n", 2);
241 #endif
243 displayremote();
245 #endif
247 #endif