comparison Gui/win32/skinload.c @ 18914:d450ec82ae57

Initial win32 gui release.
author vayne
date Thu, 06 Jul 2006 02:07:03 +0000
parents
children
comparison
equal deleted inserted replaced
18913:2dc84d07332c 18914:d450ec82ae57
1 /*
2 MPlayer Gui for win32
3 Copyright (c) 2003 Sascha Sommer <saschasommer@freenet.de>
4 Copyright (c) 2006 Erik Augustson <erik_27can@yahoo.com>
5 Copyright (c) 2006 Gianluigi Tiesi <sherpya@netfarm.it>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
20 */
21
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include <windows.h>
25 #include <png.h>
26
27 #include <mp_msg.h>
28 #include <cpudetect.h>
29 #include <libswscale/rgb2rgb.h>
30 #include <libswscale/swscale.h>
31
32 #include "gui.h"
33
34 #define MAX_LINESIZE 256
35
36 typedef struct
37 {
38 int msg;
39 char *name;
40 } evName;
41
42 static const evName evNames[] =
43 {
44 { evNone, "evNone" },
45 { evPlay, "evPlay" },
46 { evDropFile, "evDropFile" },
47 { evStop, "evStop" },
48 { evPause, "evPause" },
49 { evPrev, "evPrev" },
50 { evNext, "evNext" },
51 { evLoad, "evLoad" },
52 { evEqualizer, "evEqualizer" },
53 { evEqualizer, "evEqualeaser" },
54 { evPlayList, "evPlaylist" },
55 { evExit, "evExit" },
56 { evIconify, "evIconify" },
57 { evIncBalance, "evIncBalance" },
58 { evDecBalance, "evDecBalance" },
59 { evFullScreen, "evFullScreen" },
60 { evFName, "evFName" },
61 { evMovieTime, "evMovieTime" },
62 { evAbout, "evAbout" },
63 { evLoadPlay, "evLoadPlay" },
64 { evPreferences, "evPreferences" },
65 { evSkinBrowser, "evSkinBrowser" },
66 { evBackward10sec, "evBackward10sec" },
67 { evForward10sec, "evForward10sec" },
68 { evBackward1min, "evBackward1min" },
69 { evForward1min, "evForward1min" },
70 { evBackward10min, "evBackward10min" },
71 { evForward10min, "evForward10min" },
72 { evIncVolume, "evIncVolume" },
73 { evDecVolume, "evDecVolume" },
74 { evMute, "evMute" },
75 { evIncAudioBufDelay, "evIncAudioBufDelay" },
76 { evDecAudioBufDelay, "evDecAudioBufDelay" },
77 { evPlaySwitchToPause, "evPlaySwitchToPause" },
78 { evPauseSwitchToPlay, "evPauseSwitchToPlay" },
79 { evNormalSize, "evNormalSize" },
80 { evDoubleSize, "evDoubleSize" },
81 { evSetMoviePosition, "evSetMoviePosition" },
82 { evSetVolume, "evSetVolume" },
83 { evSetBalance, "evSetBalance" },
84 { evHelp, "evHelp" },
85 { evLoadSubtitle, "evLoadSubtitle" },
86 { evPlayDVD, "evPlayDVD" },
87 { evPlayVCD, "evPlayVCD" },
88 { evSetURL, "evSetURL" },
89 { evLoadAudioFile, "evLoadAudioFile" },
90 { evDropSubtitle, "evDropSubtitle" },
91 { evSetAspect, "evSetAspect" }
92 };
93
94 static const int evBoxs = sizeof(evNames) / sizeof(evName);
95
96 static char *geteventname(int event)
97 {
98 int i;
99 for(i=0; i<evBoxs; i++)
100 if(evNames[i].msg == event)
101 return evNames[i].name;
102 return NULL;
103 }
104
105 static inline int get_sws_cpuflags(void)
106 {
107 return (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0) |
108 (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0) |
109 (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0);
110 }
111
112 /* reads a complete image as is into image buffer */
113 static image *pngRead(skin_t *skin, unsigned char *fname)
114 {
115 unsigned char header[8];
116 png_structp png;
117 png_infop info;
118 png_infop endinfo;
119 png_bytep *row_p;
120 int color, h;
121 png_uint_32 i;
122 int BPP;
123 char *img;
124 unsigned int imgsize;
125 image *bf;
126 char *filename;
127 FILE *fp;
128
129 if(!stricmp(fname, "NULL")) return 0;
130
131 /* find filename in order file file.png */
132 if(!(fp = fopen(fname, "rb")))
133 {
134 filename = calloc(1, strlen(skin->skindir) + strlen(fname) + 6);
135 sprintf(filename, "%s\\%s.png", skin->skindir, fname);
136 if(!(fp = fopen(filename, "rb")))
137 {
138 mp_msg(MSGT_GPLAYER, MSGL_ERR, "[png] cannot find image %s\n", filename);
139 free(filename);
140 return 0;
141 }
142 free(filename);
143 }
144
145 for (i=0; i < skin->imagecount; i++)
146 if(!strcmp(fname, skin->images[i]->name))
147 {
148 #ifdef DEBUG
149 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] skinfile %s already exists\n", fname);
150 #endif
151 return skin->images[i];
152 }
153 (skin->imagecount)++;
154 skin->images = realloc(skin->images, sizeof(image *) * skin->imagecount);
155 bf = skin->images[(skin->imagecount) - 1] = calloc(1, sizeof(image));
156 bf->name = strdup(fname);
157 fread(header,1,8,fp);
158 if (!png_check_sig(header, 8)) return 0;
159 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
160 info = png_create_info_struct(png);
161 endinfo = png_create_info_struct(png);
162
163 png_init_io(png, fp);
164 png_set_sig_bytes(png, 8);
165 png_read_info(png, info);
166 png_get_IHDR(png, info, (png_uint_32*) &bf->width, (png_uint_32*) &bf->height, &BPP, &color, NULL, NULL, NULL);
167
168 if(color & PNG_COLOR_MASK_ALPHA)
169 {
170 if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA ) BPP *= 2;
171 else BPP *= 4;
172 }
173 else
174 {
175 if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY ) BPP *= 1;
176 else BPP *= 3;
177 }
178 row_p = (png_bytep *) malloc (sizeof(png_bytep) * bf->height);
179 img = (png_bytep) calloc(png_get_rowbytes(png, info), bf->height);
180 for (h=0; h < bf->height; h++)
181 row_p[h] = &img[png_get_rowbytes(png, info) * h];
182 png_read_image(png, row_p);
183 free(row_p);
184
185 png_read_end(png, endinfo);
186 png_destroy_read_struct(&png, &info, &endinfo);
187 fclose(fp);
188 imgsize=bf->width * bf->height * (BPP / 8);
189
190 #ifdef DEBUG
191 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] loaded image %s\n", fname);
192 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] size: %dx%d bits: %d\n", bf->width, bf->height, BPP);
193 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] imagesize: %u\n", imgsize);
194 #endif
195
196 bf->size = bf->width * bf->height * skin->desktopbpp / 8;
197 bf->data = malloc(bf->size);
198 if(skin->desktopbpp == 16 && BPP == 24) rgb24tobgr15(img, bf->data, imgsize);
199 else if(skin->desktopbpp == 16 && BPP == 32) rgb32tobgr15(img, bf->data, imgsize);
200 else if(skin->desktopbpp == 24 && BPP == 24) rgb24tobgr24(img, bf->data, imgsize);
201 else if(skin->desktopbpp == 24 && BPP == 32) rgb32tobgr24(img, bf->data, imgsize);
202 else if(skin->desktopbpp == 32 && BPP == 24) rgb24tobgr32(img, bf->data, imgsize);
203 else if(skin->desktopbpp == 32 && BPP == 32) rgb32tobgr32(img, bf->data, imgsize);
204 free(img);
205 return bf;
206 }
207
208 /* frees all skin images */
209 static void freeimages(skin_t *skin)
210 {
211 unsigned int i;
212 for (i=0; i<skin->imagecount; i++)
213 {
214 if(skin->images && skin->images[i])
215 {
216 if(skin->images[i]->data) free(skin->images[i]->data);
217 if(skin->images[i]->name) free(skin->images[i]->name);
218 free(skin->images[i]);
219 }
220 }
221 free(skin->images);
222 }
223
224 #ifdef DEBUG
225 void dumpwidgets(skin_t *skin)
226 {
227 unsigned int i;
228 for (i=0; i<skin->widgetcount; i++)
229 mp_msg(MSGT_GPLAYER, MSGL_V, "widget %p id %i\n", skin->widgets[i], skin->widgets[i]->id);
230 }
231 #endif
232
233 static int counttonextchar(const char *s1, char c)
234 {
235 unsigned int i;
236 for (i=0; i<strlen(s1); i++)
237 if(s1[i] == c) return i;
238 return 0;
239 }
240
241 static char *findnextstring(char *temp, const char *desc, int *base)
242 {
243 int len = counttonextchar(*base + desc, ',');
244 memset(temp, 0, strlen(desc) + 1);
245 if(!len) len = strlen(desc);
246 memcpy(temp, *base + desc, len);
247 *base += (len+1);
248 return temp;
249 }
250
251 static void freeskin(skin_t *skin)
252 {
253 unsigned int i;
254 if(skin->skindir)
255 {
256 free(skin->skindir);
257 skin->skindir = NULL;
258 }
259
260 for (i=1; i<=skin->lastusedid; i++)
261 skin->removewidget(skin, i);
262
263 if(skin->widgets)
264 {
265 free(skin->widgets);
266 skin->widgets = NULL;
267 }
268
269 freeimages(skin);
270 for(i=0; i<skin->windowcount; i++)
271 {
272 if(skin->windows[i]->name)
273 {
274 free(skin->windows[i]->name);
275 skin->windows[i]->name = NULL;
276 }
277 free(skin->windows[i]);
278 }
279
280 free(skin->windows);
281 skin->windows = NULL;
282
283 for (i=0; i<skin->fontcount; i++)
284 {
285 unsigned int x;
286 if(skin->fonts[i]->name)
287 {
288 free(skin->fonts[i]->name);
289 skin->fonts[i]->name = NULL;
290 }
291
292 if(skin->fonts[i]->id)
293 {
294 free(skin->fonts[i]->id);
295 skin->fonts[i]->id = NULL;
296 }
297
298 for (x=0; x<skin->fonts[i]->charcount; x++)
299 {
300 free(skin->fonts[i]->chars[x]);
301 skin->fonts[i]->chars[x] = NULL;
302 }
303
304 if(skin->fonts[i]->chars)
305 {
306 free(skin->fonts[i]->chars);
307 skin->fonts[i]->chars = NULL;
308 }
309
310 free(skin->fonts[i]);
311 skin->fonts[i] = NULL;
312 }
313 free(skin->fonts);
314 skin->fonts = NULL;
315 #ifdef DEBUG
316 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN FREE] skin freed\n");
317 #endif
318 free(skin);
319 skin = NULL;
320 }
321
322 static void removewidget(skin_t *skin, int id)
323 {
324 unsigned int i;
325 unsigned int pos=0;
326 widget **temp = calloc(skin->widgetcount - 1, sizeof(widget *));
327
328 for (i=0; i<skin->widgetcount; i++)
329 {
330 if(skin->widgets[i]->id == id)
331 {
332 if(skin->widgets[i]->label)
333 free(skin->widgets[i]->label);
334 free(skin->widgets[i]);
335 skin->widgets[i] = NULL;
336 }
337 else
338 {
339 temp[pos] = skin->widgets[i];
340 pos++;
341 }
342 }
343 if (pos != i)
344 {
345 (skin->widgetcount)--;
346 free(skin->widgets);
347 skin->widgets = temp;
348 #ifdef DEBUG
349 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "removed widget %i\n", id);
350 #endif
351 return;
352 }
353 free(temp);
354 mp_msg(MSGT_GPLAYER, MSGL_ERR, "widget %i not found\n", id);
355 }
356
357 static void addwidget(skin_t *skin, window *win, const char *desc)
358 {
359 widget *mywidget;
360 char *temp = calloc(1, strlen(desc) + 1);
361 (skin->widgetcount)++;
362 (skin->lastusedid)++;
363 skin->widgets = realloc(skin->widgets, sizeof(widget *) * skin->widgetcount);
364 mywidget = skin->widgets[(skin->widgetcount) - 1] = calloc(1, sizeof(widget));
365 mywidget->id = skin->lastusedid;
366 mywidget->window = win->type;
367 /* parse and fill widget specific info */
368 if(!strncmp(desc, "base", 4))
369 {
370 int base = counttonextchar(desc, '=') + 1;
371 mywidget->type = tyBase;
372 mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
373 mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
374 mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
375 mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
376 mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
377 win->base = mywidget;
378 #ifdef DEBUG
379 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] %s %i %i %i %i\n",
380 (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
381 mywidget->x, mywidget->y, mywidget->width, mywidget->height);
382 #endif
383 }
384 else if(!strncmp(desc, "button", 6))
385 {
386 int base = counttonextchar(desc, '=') + 1;
387 int i;
388 mywidget->type = tyButton;
389 mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
390 mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
391 mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
392 mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
393 mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
394 findnextstring(temp, desc, &base);
395
396 /* Assign corresponding event to the widget */
397 mywidget->msg = evNone;
398 for (i=0; i<evBoxs; i++)
399 {
400 if(!strcmp(temp, evNames[i].name))
401 {
402 mywidget->msg = evNames[i].msg;
403 break;
404 }
405 }
406
407 #ifdef DEBUG
408 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BUTTON] %s %i %i %i %i msg %i\n",
409 (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
410 mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
411 #endif
412 }
413 else if(!strncmp(desc, "hpotmeter", 9) || !strncmp(desc, "vpotmeter", 9))
414 {
415 int base = counttonextchar(desc, '=') + 1;
416 int i;
417 /* hpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message */
418 if(!strncmp(desc, "hpotmeter", 9)) mywidget->type = tyHpotmeter;
419 else mywidget->type = tyVpotmeter;
420 mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
421 mywidget->width = atoi(findnextstring(temp, desc, &base));
422 mywidget->height = atoi(findnextstring(temp, desc, &base));
423 mywidget->bitmap[1] = pngRead(skin, findnextstring(temp, desc, &base));
424 mywidget->phases = atoi(findnextstring(temp, desc, &base));
425 mywidget->value = atof(findnextstring(temp, desc, &base));
426 mywidget->x = mywidget->wx = atoi(findnextstring(temp, desc, &base));
427 mywidget->y = mywidget->wy = atoi(findnextstring(temp, desc, &base));
428 mywidget->wwidth = atoi(findnextstring(temp, desc, &base));
429 mywidget->wheight = atoi(findnextstring(temp, desc, &base));
430 findnextstring(temp, desc, &base);
431 mywidget->msg = evNone;
432 for (i=0; i<evBoxs; i++)
433 {
434 if(!strcmp(temp, evNames[i].name))
435 {
436 mywidget->msg = evNames[i].msg;
437 break;
438 }
439 }
440 #ifdef DEBUG
441 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] %s %s %i %i %s %i %f %i %i %i %i msg %i\n",
442 (mywidget->type == tyHpotmeter) ? "[HPOTMETER]" : "[VPOTMETER]",
443 (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
444 mywidget->width, mywidget->height,
445 (mywidget->bitmap[1]) ? mywidget->bitmap[1]->name : NULL,
446 mywidget->phases, mywidget->value,
447 mywidget->wx, mywidget->wy, mywidget->wwidth, mywidget->wwidth,
448 mywidget->msg);
449 #endif
450 }
451 else if(!strncmp(desc, "potmeter", 8))
452 {
453 int base = counttonextchar(desc, '=') + 1;
454 int i;
455 /* potmeter = phases, numphases, default, X, Y, width, height, message */
456 mywidget->type = tyPotmeter;
457 mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
458 mywidget->phases = atoi(findnextstring(temp, desc, &base));
459 mywidget->value = atof(findnextstring(temp, desc, &base));
460 mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
461 mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
462 mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
463 mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
464 findnextstring(temp, desc, &base);
465 mywidget->msg = evNone;
466 for (i=0; i<evBoxs; i++)
467 {
468 if(!strcmp(temp, evNames[i].name))
469 {
470 mywidget->msg=evNames[i].msg;
471 break;
472 }
473 }
474 #ifdef DEBUG
475 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [POTMETER] %s %i %i %i %f %i %i msg %i\n",
476 (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
477 mywidget->width, mywidget->height,
478 mywidget->phases, mywidget->value,
479 mywidget->x, mywidget->y,
480 mywidget->msg);
481 #endif
482 }
483 else if(!strncmp(desc, "menu", 4))
484 {
485 int base = counttonextchar(desc, '=') + 1;
486 int i;
487 mywidget->type = tyMenu;
488 mywidget->wx=atoi(findnextstring(temp, desc, &base));
489 mywidget->x=0;
490 mywidget->wy=mywidget->y=atoi(findnextstring(temp, desc, &base));
491 mywidget->wwidth=mywidget->width=atoi(findnextstring(temp, desc, &base));
492 mywidget->wheight=mywidget->height=atoi(findnextstring(temp, desc, &base));
493 findnextstring(temp, desc, &base);
494 mywidget->msg = evNone;
495 for (i=0; i<evBoxs; i++)
496 {
497 if(!strcmp(temp, evNames[i].name))
498 {
499 mywidget->msg = evNames[i].msg;
500 break;
501 }
502 }
503 #ifdef DEBUG
504 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [MENU] %i %i %i %i msg %i\n",
505 mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
506 #endif
507 }
508 else if(!strncmp(desc, "selected", 8))
509 {
510 win->base->bitmap[1] = pngRead(skin, (char *) desc + 9);
511 #ifdef DEBUG
512 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] added image %s\n", win->base->bitmap[1]->name);
513 #endif
514 }
515 else if(!strncmp(desc, "slabel",6))
516 {
517 int base = counttonextchar(desc, '=') + 1;
518 unsigned int i;
519 mywidget->type = tySlabel;
520 mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
521 mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
522 findnextstring(temp, desc, &base);
523 mywidget->font = NULL;
524 for (i=0; i<skin->fontcount; i++)
525 {
526 if(!strcmp(temp, skin->fonts[i]->name))
527 {
528 mywidget->font = skin->fonts[i];
529 break;
530 }
531 }
532 mywidget->label = strdup(findnextstring(temp, desc, &base));
533 #ifdef DEBUG
534 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [SLABEL] %i %i %s %s\n",
535 mywidget->x, mywidget->y, mywidget->font->name, mywidget->label);
536 #endif
537 }
538 else if(!strncmp(desc, "dlabel", 6))
539 {
540 int base = counttonextchar(desc, '=') + 1;
541 unsigned int i;
542 mywidget->type = tyDlabel;
543 mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
544 mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
545 mywidget->length = atoi(findnextstring(temp, desc, &base));
546 mywidget->align = atoi(findnextstring(temp, desc, &base));
547 findnextstring(temp, desc, &base);
548 mywidget->font = NULL;
549 for (i=0; i<skin->fontcount; i++)
550 {
551 if(!strcmp(temp, skin->fonts[i]->name))
552 {
553 mywidget->font=skin->fonts[i];
554 break;
555 }
556 }
557 mywidget->label=strdup(findnextstring(temp, desc, &base));
558 #ifdef DEBUG
559 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [DLABEL] %i %i %i %i %s \"%s\"\n",
560 mywidget->x, mywidget->y, mywidget->length, mywidget->align, mywidget->font->name, mywidget->label);
561 #endif
562 }
563 free(temp);
564 }
565
566 static void loadfonts(skin_t* skin)
567 {
568 unsigned int x;
569 for (x=0; x<skin->fontcount; x++)
570 {
571 FILE *fp;
572 int linenumber=0;
573 char *filename;
574 char *tmp = calloc(1, MAX_LINESIZE);
575 char *desc = calloc(1, MAX_LINESIZE);
576 filename = calloc(1, strlen(skin->skindir) + strlen(skin->fonts[x]->name) + 6);
577 sprintf(filename, "%s\\%s.fnt", skin->skindir, skin->fonts[x]->name);
578 if(!(fp = fopen(filename,"rb")))
579 {
580 mp_msg(MSGT_GPLAYER, MSGL_ERR, "[FONT LOAD] Font not found \"%s\"\n", skin->fonts[x]->name);
581 return;
582 }
583 while(!feof(fp))
584 {
585 int pos = 0;
586 unsigned int i;
587 fgets(tmp, MAX_LINESIZE, fp);
588 linenumber++;
589 memset(desc, 0, MAX_LINESIZE);
590 for (i=0; i<strlen(tmp); i++)
591 {
592 /* remove spaces and linebreaks */
593 if((tmp[i] == ' ') || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
594 /* remove comments */
595 if((tmp[i] == ';') && ((i < 1) || (tmp[i-1] != '\"')))
596 {
597 #ifdef DEBUG
598 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT LOAD] Comment: %s", tmp + i + 1);
599 #endif
600 break;
601 }
602 desc[pos] = tmp[i];
603 pos++;
604 }
605 if(!strlen(desc)) continue;
606 /* now we have "readable" output -> parse it */
607 if(!strncmp(desc, "image", 5))
608 {
609 skin->fonts[x]->image = pngRead(skin, desc + 6);
610 #ifdef DEBUG
611 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [IMAGE] \"%s\"\n", desc + 6);
612 #endif
613 }
614 else
615 {
616 int base = 4;
617 if(*desc != '"') break;
618 if(*(desc + 1) == 0) break;
619 (skin->fonts[x]->charcount)++;
620 skin->fonts[x]->chars = realloc(skin->fonts[x]->chars, sizeof(char_t *) *skin->fonts[x]->charcount);
621 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]=calloc(1, sizeof(char_t));
622 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c = ((*(desc + 1) == '"') && (*(desc + 2) != '"')) ? ' ': *(desc + 1);
623 if((*(desc + 1) == '"') && (*(desc + 2) != '"')) base = 3;
624 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x = atoi(findnextstring(tmp, desc, &base));
625 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y = atoi(findnextstring(tmp, desc, &base));
626 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width = atoi(findnextstring(tmp, desc, &base));
627 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height = atoi(findnextstring(tmp, desc, &base));
628 #ifdef DEBUG
629 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [CHAR] %c %i %i %i %i\n",
630 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c,
631 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x,
632 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y,
633 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width,
634 skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height);
635 #endif
636 }
637 }
638 free(desc);
639 free(filename);
640 free(tmp);
641 fclose(fp);
642 }
643 }
644
645 skin_t* loadskin(char* skindir, int desktopbpp)
646 {
647 FILE *fp;
648 int reachedendofwindow = 0;
649 int linenumber = 0;
650 skin_t *skin = calloc(1, sizeof(skin_t));
651 char *filename;
652 char *tmp = calloc(1, MAX_LINESIZE);
653 char *desc = calloc(1, MAX_LINESIZE);
654 window* mywindow = NULL;
655
656 /* init swscaler */
657 sws_rgb2rgb_init(get_sws_cpuflags());
658 /* setup funcs */
659 skin->freeskin = freeskin;
660 skin->pngRead = pngRead;
661 skin->addwidget = addwidget;
662 skin->removewidget = removewidget;
663 skin->geteventname = geteventname;
664 skin->desktopbpp = desktopbpp;
665 skin->skindir = strdup(skindir);
666
667 filename = calloc(1, strlen(skin->skindir) + strlen("skin") + 2);
668 sprintf(filename, "%s\\skin", skin->skindir);
669 if(!(fp = fopen(filename, "rb")))
670 {
671 mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[SKIN LOAD] Skin \"%s\" not found\n", skindir);
672 skin->freeskin(skin);
673 return NULL;
674 }
675
676 while(!feof(fp))
677 {
678 int pos = 0;
679 unsigned int i;
680 int insidequote = 0;
681 fgets(tmp, MAX_LINESIZE, fp);
682 linenumber++;
683 memset(desc, 0, MAX_LINESIZE);
684 for (i=0; i<strlen(tmp); i++)
685 {
686 if((tmp[i] == '"') && !insidequote) { insidequote=1; continue; }
687 else if((tmp[i] == '"') && insidequote) { insidequote=0 ; continue; }
688 /* remove spaces and linebreaks */
689 if((!insidequote && (tmp[i] == ' ')) || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
690 /* remove comments */
691 else if(tmp[i] == ';')
692 {
693 #ifdef DEBUG
694 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN LOAD] Comment: %s", tmp + i + 1);
695 #endif
696 break;
697 }
698 desc[pos] = tmp[i];
699 pos++;
700 }
701
702 if(!strlen(desc)) continue;
703 /* now we have "readable" output -> parse it */
704 /* parse window specific info */
705 if(!strncmp(desc, "section", 7))
706 {
707 #ifdef DEBUG
708 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [SECTION] \"%s\"\n", desc + 8);
709 #endif
710 }
711 else if(!strncmp(desc, "window", 6))
712 {
713 #ifdef DEBUG
714 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [WINDOW] \"%s\"\n", desc + 7);
715 #endif
716 reachedendofwindow = 0;
717 (skin->windowcount)++;
718 skin->windows = realloc(skin->windows, sizeof(window *) * skin->windowcount);
719 mywindow = skin->windows[(skin->windowcount) - 1] = calloc(1, sizeof(window));
720 mywindow->name = strdup(desc + 7);
721 if(!strncmp(desc + 7, "main", 4)) mywindow->type = wiMain;
722 else if(!strncmp(desc+7, "sub", 3))
723 {
724 mywindow->type = wiSub;
725 mywindow->decoration = 1;
726 }
727 else if(!strncmp(desc + 7, "menu", 4)) mywindow->type = wiMenu;
728 else if(!strncmp(desc + 7, "playbar", 7)) mywindow->type = wiPlaybar;
729 else mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN] warning found unknown windowtype");
730 }
731 else if(!strncmp(desc, "decoration", 10) && !strncmp(desc + 11, "enable", 6))
732 {
733 mywindow->decoration = 1;
734 #ifdef DEBUG
735 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [DECORATION] enabled decoration for window \"%s\"\n", mywindow->name);
736 #endif
737 }
738 else if(!strncmp(desc, "background", 10))
739 {
740 int base = counttonextchar(desc, '=') + 1;
741 char temp[MAX_LINESIZE];
742 mywindow->backgroundcolor[0] = atoi(findnextstring(temp, desc, &base));
743 mywindow->backgroundcolor[1] = atoi(findnextstring(temp, desc, &base));
744 mywindow->backgroundcolor[2] = atoi(findnextstring(temp, desc, &base));
745 #ifdef DEBUG
746 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [BACKGROUND] window \"%s\" has backgroundcolor (%i,%i,%i)\n", mywindow->name,
747 mywindow->backgroundcolor[0],
748 mywindow->backgroundcolor[1],
749 mywindow->backgroundcolor[2]);
750 #endif
751 }
752 else if(!strncmp(desc, "end", 3))
753 {
754 if(reachedendofwindow)
755 {
756 #ifdef DEBUG
757 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of section\n");
758 #endif
759 }
760 else
761 {
762 reachedendofwindow = 1;
763 #ifdef DEBUG
764 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of window \"%s\"\n", mywindow->name);
765 #endif
766 }
767 }
768 else if(!strncmp(desc, "font", 4))
769 {
770 unsigned int i;
771 int id = 0;
772 char temp[MAX_LINESIZE];
773 int base = counttonextchar(desc, '=')+1;
774 findnextstring(temp, desc, &base);
775 findnextstring(temp, desc, &base);
776 for (i=0; i<skin->fontcount; i++)
777 if(!strcmp(skin->fonts[i]->id, temp))
778 {
779 id = i;
780 break;
781 }
782 if(!id)
783 {
784 int base = counttonextchar(desc, '=') + 1;
785 findnextstring(temp, desc, &base);
786 id = skin->fontcount;
787 (skin->fontcount)++;
788 skin->fonts = realloc(skin->fonts, sizeof(font_t *) * skin->fontcount);
789 skin->fonts[id]=calloc(1, sizeof(font_t));
790 skin->fonts[id]->name = strdup(temp);
791 skin->fonts[id]->id = strdup(findnextstring(temp, desc, &base));
792 }
793 #ifdef DEBUG
794 mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [FONT] id \"%s\" name \"%s\"\n", skin->fonts[id]->name, skin->fonts[id]->id);
795 #endif
796 }
797 else
798 skin->addwidget(skin, mywindow, desc);
799 }
800
801 free(desc);
802 free(filename);
803 free(tmp);
804 fclose(fp);
805 loadfonts(skin);
806 mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN LOAD] loaded skin \"%s\"\n", skin->skindir);
807 /* dumpwidgets(skin); */
808 return skin;
809 }