Mercurial > mplayer.hg
comparison gui/win32/skinload.c @ 23077:17bf4f4b0715
Gui --> gui
author | diego |
---|---|
date | Mon, 23 Apr 2007 07:42:42 +0000 |
parents | |
children | f81cd5be161b |
comparison
equal
deleted
inserted
replaced
23076:39dd908375b2 | 23077:17bf4f4b0715 |
---|---|
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 } |