1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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 ****************************************************************************/
31 #define DEBUGF1 _debug
32 #define DEBUGF2 if(verbose) _debug
34 #define getFont() gdFontGetSmall()
36 static struct trackstate mp3data
=
45 (char*)"Test composer",
46 (char*)"Test comment",
47 (char*)"Test album artist",
48 (char*)"Test grouping",
59 static struct wpsstate wpsdata
= {-20, -1, -1, 70, API_STATUS_FASTFORWARD
};
60 /* volume, fontheight, fontwidth, battery_level, audio_status */
62 static struct proxy_api api
;
63 static bool verbose
= false;
64 static int (*wps_init
)(const char* buff
, struct proxy_api
*api
, bool isfile
);
65 static int (*wps_display
)();
66 static int (*wps_refresh
)();
67 static gdImagePtr framebuffer
;
68 static gdImagePtr backdrop
;
70 extern gdImagePtr
gdImageCreateFromBmp(FILE * inFile
);
71 extern char *get_current_dir_name (void) __THROW
;
73 static bool next_nl
= false;
75 int _debug(const char* fmt
,...)
82 fprintf(stdout
, "[DBG] ");
84 vfprintf(stdout
, fmt
, ap
);
86 if(fmt
[strlen(fmt
)-1] != 0xa)
96 void _putsxy(int x
, int y
, const unsigned char *str
)
98 struct viewport_api avp
;
99 int black
= gdImageColorAllocate(framebuffer
, 0, 0, 0);
101 api
.get_current_vp(&avp
);
103 gdImageString(framebuffer
, getFont(), x
+ avp
.x
, y
+ avp
.y
- avp
.fontheight
, (unsigned char*)str
, black
);
106 void _transparent_bitmap_part(const void *src
, int src_x
, int src_y
,
107 int stride
, int x
, int y
, int width
, int height
)
113 DEBUGF2("transparent_bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d, int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d\n", (char*)src
, src_x
, src_y
, stride
, x
, y
, width
, height
);
115 _image
= fopen(src
, "rb");
119 image
= gdImageCreateFromBmp(_image
);
122 pink
= gdTrueColor(255, 0, 255);
123 gdImageColorTransparent(image
, pink
);
125 gdImageCopy(framebuffer
, image
, x
, y
, src_x
, src_y
, width
, height
);
127 gdImageDestroy(image
);
130 void _bitmap_part(const void *src
, int src_x
, int src_y
,
131 int stride
, int x
, int y
, int width
, int height
)
136 DEBUGF2("bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d, int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d\n", (char*)src
, src_x
, src_y
, stride
, x
, y
, width
, height
);
138 _image
= fopen(src
, "rb");
142 image
= gdImageCreateFromBmp(_image
);
145 gdImageCopy(framebuffer
, image
, x
, y
, src_x
, src_y
, width
, height
);
147 gdImageDestroy(image
);
150 void _drawpixel(int x
, int y
)
152 int black
= gdImageColorAllocate(framebuffer
, 0, 0, 0);
153 gdImageSetPixel(framebuffer
, x
, y
, black
);
156 void _fillrect(int x
, int y
, int width
, int height
)
158 /* Don't draw this as backdrop is used */
160 int black
= gdImageColorAllocate(framebuffer
, 0, 0, 0);
161 gdImageFilledRectangle(framebuffer
, x
, y
, x
+width
, y
+height
, black
);
165 void _hline(int x1
, int x2
, int y
)
167 int black
= gdImageColorAllocate(framebuffer
, 0, 0, 0);
168 gdImageLine(framebuffer
, x1
, y
, x2
, y
, black
);
171 void _vline(int x
, int y1
, int y2
)
173 int black
= gdImageColorAllocate(framebuffer
, 0, 0, 0);
174 gdImageLine(framebuffer
, x
, y1
, x
, y2
, black
);
177 void _clear_viewport(int x
, int y
, int w
, int h
, int color
)
182 gdImageCopy(framebuffer
, backdrop
, x
, y
, x
, y
, w
, h
);
185 static bool _load_wps_backdrop(char* filename
)
189 gdImageDestroy(backdrop
);
191 DEBUGF2("load backdrop: %s", filename
);
193 image
= fopen(filename
, "rb");
197 backdrop
= gdImageCreateFromBmp(image
);
203 int _read_bmp_file(const char* filename
, int *width
, int *height
)
208 DEBUGF2("load backdrop: %s", filename
);
210 _image
= fopen(filename
, "rb");
214 image
= gdImageCreateFromBmp(_image
);
220 gdImageDestroy(image
);
225 static void _drawBackdrop()
230 gdImageCopy(framebuffer
, backdrop
, 0, 0, 0, 0, backdrop
->sx
, backdrop
->sy
);
233 static int screenshot(char *model
, char *wps
, char *png
)
240 in
= fopen(wps
, "rb");
243 fprintf(stderr
, "[ERR] Cannot open WPS: %s\n", wps
);
248 out
= fopen(png
, "wb");
251 fprintf(stderr
, "[ERR] Cannot open PNG: %s\n", png
);
255 snprintf(lib
, 255, "%s/libwps_%s.so", (char*)get_current_dir_name(), (char*)model
);
256 handle
= dlopen(lib
, RTLD_LAZY
);
259 fprintf(stderr
, "[ERR] Cannot open library: %s\n", dlerror());
264 wps_init
= dlsym(handle
, "wps_init");
265 wps_display
= dlsym(handle
, "wps_display");
266 wps_refresh
= dlsym(handle
, "wps_refresh");
268 if (!wps_init
|| !wps_display
|| !wps_refresh
)
270 fprintf(stderr
, "[ERR] Failed to resolve funcs!");
276 memset(&api
, 0, sizeof(struct proxy_api
));
283 api
.putsxy
= &_putsxy
;
284 api
.transparent_bitmap_part
= &_transparent_bitmap_part
;
285 api
.bitmap_part
= &_bitmap_part
;
286 api
.drawpixel
= &_drawpixel
;
287 api
.fillrect
= &_fillrect
;
290 api
.clear_viewport
= &_clear_viewport
;
291 api
.load_wps_backdrop
= &_load_wps_backdrop
;
292 api
.read_bmp_file
= &_read_bmp_file
;
293 api
.debugf
= &_debug
;
295 res
= wps_init(wps
, &api
, true);
298 fprintf(stderr
, "[ERR] WPS wasn't correctly inited\n");
304 framebuffer
= gdImageCreateTrueColor(api
.getwidth(), api
.getheight());
308 fprintf(stdout
, "[INFO] Model: %s\n", api
.get_model_name());
310 wpsdata
.fontheight
= getFont()->h
;
311 wpsdata
.fontwidth
= getFont()->w
;
312 api
.set_wpsstate(wpsdata
);
313 api
.set_trackstate(mp3data
);
314 api
.set_next_trackstate(mp3data
);
318 gdImagePng(framebuffer
, out
);
320 fprintf(stdout
, "[INFO] Image written\n");
324 gdImageDestroy(framebuffer
);
326 gdImageDestroy(backdrop
);
335 static void usage(void)
337 fprintf(stderr
, "Rockbox WPS screenshot utility\n");
338 fprintf(stderr
, "Made by Maurus Cuelenaere\n");
339 fprintf(stderr
, "\n");
340 fprintf(stderr
, "Usage: screenshot [-V] <MODEL> <WPS> <OUT>.png\n");
341 fprintf(stderr
, " -> creates a PNG screenshot of the WPS for the specific MODEL\n");
342 fprintf(stderr
, " -> libwps_<MODEL>.so must be present in the same directory\n");
343 fprintf(stderr
, " -> -V sets verbose mode ON\n");
344 fprintf(stderr
, "\n");
345 fprintf(stderr
, "Example: screenshot IRIVER_H10_5GB iCatcher.wps out.png\n");
348 int main(int argc
, char ** argv
)
356 if(argv
[1] == NULL
|| argv
[2] == NULL
||
358 (strcmp(argv
[1], "-V") == 0 && argv
[4] == NULL
)
365 if(strcmp(argv
[1], "-V") == 0)
368 return screenshot(argv
[2], argv
[3], argv
[4]);
373 return screenshot(argv
[1], argv
[2], argv
[3]);