summaryrefslogtreecommitdiffstats
path: root/gui/win32/skinload.c
diff options
context:
space:
mode:
Diffstat (limited to 'gui/win32/skinload.c')
-rw-r--r--gui/win32/skinload.c809
1 files changed, 809 insertions, 0 deletions
diff --git a/gui/win32/skinload.c b/gui/win32/skinload.c
new file mode 100644
index 0000000000..9c56e93348
--- /dev/null
+++ b/gui/win32/skinload.c
@@ -0,0 +1,809 @@
+/*
+ MPlayer Gui for win32
+ Copyright (c) 2003 Sascha Sommer <saschasommer@freenet.de>
+ Copyright (c) 2006 Erik Augustson <erik_27can@yahoo.com>
+ Copyright (c) 2006 Gianluigi Tiesi <sherpya@netfarm.it>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <windows.h>
+#include <png.h>
+
+#include <mp_msg.h>
+#include <cpudetect.h>
+#include <libswscale/rgb2rgb.h>
+#include <libswscale/swscale.h>
+
+#include "gui.h"
+
+#define MAX_LINESIZE 256
+
+typedef struct
+{
+ int msg;
+ char *name;
+} evName;
+
+static const evName evNames[] =
+{
+ { evNone, "evNone" },
+ { evPlay, "evPlay" },
+ { evDropFile, "evDropFile" },
+ { evStop, "evStop" },
+ { evPause, "evPause" },
+ { evPrev, "evPrev" },
+ { evNext, "evNext" },
+ { evLoad, "evLoad" },
+ { evEqualizer, "evEqualizer" },
+ { evEqualizer, "evEqualeaser" },
+ { evPlayList, "evPlaylist" },
+ { evExit, "evExit" },
+ { evIconify, "evIconify" },
+ { evIncBalance, "evIncBalance" },
+ { evDecBalance, "evDecBalance" },
+ { evFullScreen, "evFullScreen" },
+ { evFName, "evFName" },
+ { evMovieTime, "evMovieTime" },
+ { evAbout, "evAbout" },
+ { evLoadPlay, "evLoadPlay" },
+ { evPreferences, "evPreferences" },
+ { evSkinBrowser, "evSkinBrowser" },
+ { evBackward10sec, "evBackward10sec" },
+ { evForward10sec, "evForward10sec" },
+ { evBackward1min, "evBackward1min" },
+ { evForward1min, "evForward1min" },
+ { evBackward10min, "evBackward10min" },
+ { evForward10min, "evForward10min" },
+ { evIncVolume, "evIncVolume" },
+ { evDecVolume, "evDecVolume" },
+ { evMute, "evMute" },
+ { evIncAudioBufDelay, "evIncAudioBufDelay" },
+ { evDecAudioBufDelay, "evDecAudioBufDelay" },
+ { evPlaySwitchToPause, "evPlaySwitchToPause" },
+ { evPauseSwitchToPlay, "evPauseSwitchToPlay" },
+ { evNormalSize, "evNormalSize" },
+ { evDoubleSize, "evDoubleSize" },
+ { evSetMoviePosition, "evSetMoviePosition" },
+ { evSetVolume, "evSetVolume" },
+ { evSetBalance, "evSetBalance" },
+ { evHelp, "evHelp" },
+ { evLoadSubtitle, "evLoadSubtitle" },
+ { evPlayDVD, "evPlayDVD" },
+ { evPlayVCD, "evPlayVCD" },
+ { evSetURL, "evSetURL" },
+ { evLoadAudioFile, "evLoadAudioFile" },
+ { evDropSubtitle, "evDropSubtitle" },
+ { evSetAspect, "evSetAspect" }
+};
+
+static const int evBoxs = sizeof(evNames) / sizeof(evName);
+
+static char *geteventname(int event)
+{
+ int i;
+ for(i=0; i<evBoxs; i++)
+ if(evNames[i].msg == event)
+ return evNames[i].name;
+ return NULL;
+}
+
+static inline int get_sws_cpuflags(void)
+{
+ return (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0) |
+ (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0) |
+ (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0);
+}
+
+/* reads a complete image as is into image buffer */
+static image *pngRead(skin_t *skin, unsigned char *fname)
+{
+ unsigned char header[8];
+ png_structp png;
+ png_infop info;
+ png_infop endinfo;
+ png_bytep *row_p;
+ int color, h;
+ png_uint_32 i;
+ int BPP;
+ char *img;
+ unsigned int imgsize;
+ image *bf;
+ char *filename;
+ FILE *fp;
+
+ if(!stricmp(fname, "NULL")) return 0;
+
+ /* find filename in order file file.png */
+ if(!(fp = fopen(fname, "rb")))
+ {
+ filename = calloc(1, strlen(skin->skindir) + strlen(fname) + 6);
+ sprintf(filename, "%s\\%s.png", skin->skindir, fname);
+ if(!(fp = fopen(filename, "rb")))
+ {
+ mp_msg(MSGT_GPLAYER, MSGL_ERR, "[png] cannot find image %s\n", filename);
+ free(filename);
+ return 0;
+ }
+ free(filename);
+ }
+
+ for (i=0; i < skin->imagecount; i++)
+ if(!strcmp(fname, skin->images[i]->name))
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] skinfile %s already exists\n", fname);
+#endif
+ return skin->images[i];
+ }
+ (skin->imagecount)++;
+ skin->images = realloc(skin->images, sizeof(image *) * skin->imagecount);
+ bf = skin->images[(skin->imagecount) - 1] = calloc(1, sizeof(image));
+ bf->name = strdup(fname);
+ fread(header,1,8,fp);
+ if (!png_check_sig(header, 8)) return 0;
+ png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info = png_create_info_struct(png);
+ endinfo = png_create_info_struct(png);
+
+ png_init_io(png, fp);
+ png_set_sig_bytes(png, 8);
+ png_read_info(png, info);
+ png_get_IHDR(png, info, (png_uint_32*) &bf->width, (png_uint_32*) &bf->height, &BPP, &color, NULL, NULL, NULL);
+
+ if(color & PNG_COLOR_MASK_ALPHA)
+ {
+ if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA ) BPP *= 2;
+ else BPP *= 4;
+ }
+ else
+ {
+ if(color & PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY ) BPP *= 1;
+ else BPP *= 3;
+ }
+ row_p = (png_bytep *) malloc (sizeof(png_bytep) * bf->height);
+ img = (png_bytep) calloc(png_get_rowbytes(png, info), bf->height);
+ for (h=0; h < bf->height; h++)
+ row_p[h] = &img[png_get_rowbytes(png, info) * h];
+ png_read_image(png, row_p);
+ free(row_p);
+
+ png_read_end(png, endinfo);
+ png_destroy_read_struct(&png, &info, &endinfo);
+ fclose(fp);
+ imgsize=bf->width * bf->height * (BPP / 8);
+
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] loaded image %s\n", fname);
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] size: %dx%d bits: %d\n", bf->width, bf->height, BPP);
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[png] imagesize: %u\n", imgsize);
+#endif
+
+ bf->size = bf->width * bf->height * skin->desktopbpp / 8;
+ bf->data = malloc(bf->size);
+ if(skin->desktopbpp == 16 && BPP == 24) rgb24tobgr15(img, bf->data, imgsize);
+ else if(skin->desktopbpp == 16 && BPP == 32) rgb32tobgr15(img, bf->data, imgsize);
+ else if(skin->desktopbpp == 24 && BPP == 24) rgb24tobgr24(img, bf->data, imgsize);
+ else if(skin->desktopbpp == 24 && BPP == 32) rgb32tobgr24(img, bf->data, imgsize);
+ else if(skin->desktopbpp == 32 && BPP == 24) rgb24tobgr32(img, bf->data, imgsize);
+ else if(skin->desktopbpp == 32 && BPP == 32) rgb32tobgr32(img, bf->data, imgsize);
+ free(img);
+ return bf;
+}
+
+/* frees all skin images */
+static void freeimages(skin_t *skin)
+{
+ unsigned int i;
+ for (i=0; i<skin->imagecount; i++)
+ {
+ if(skin->images && skin->images[i])
+ {
+ if(skin->images[i]->data) free(skin->images[i]->data);
+ if(skin->images[i]->name) free(skin->images[i]->name);
+ free(skin->images[i]);
+ }
+ }
+ free(skin->images);
+}
+
+#ifdef DEBUG
+void dumpwidgets(skin_t *skin)
+{
+ unsigned int i;
+ for (i=0; i<skin->widgetcount; i++)
+ mp_msg(MSGT_GPLAYER, MSGL_V, "widget %p id %i\n", skin->widgets[i], skin->widgets[i]->id);
+}
+#endif
+
+static int counttonextchar(const char *s1, char c)
+{
+ unsigned int i;
+ for (i=0; i<strlen(s1); i++)
+ if(s1[i] == c) return i;
+ return 0;
+}
+
+static char *findnextstring(char *temp, const char *desc, int *base)
+{
+ int len = counttonextchar(*base + desc, ',');
+ memset(temp, 0, strlen(desc) + 1);
+ if(!len) len = strlen(desc);
+ memcpy(temp, *base + desc, len);
+ *base += (len+1);
+ return temp;
+}
+
+static void freeskin(skin_t *skin)
+{
+ unsigned int i;
+ if(skin->skindir)
+ {
+ free(skin->skindir);
+ skin->skindir = NULL;
+ }
+
+ for (i=1; i<=skin->lastusedid; i++)
+ skin->removewidget(skin, i);
+
+ if(skin->widgets)
+ {
+ free(skin->widgets);
+ skin->widgets = NULL;
+ }
+
+ freeimages(skin);
+ for(i=0; i<skin->windowcount; i++)
+ {
+ if(skin->windows[i]->name)
+ {
+ free(skin->windows[i]->name);
+ skin->windows[i]->name = NULL;
+ }
+ free(skin->windows[i]);
+ }
+
+ free(skin->windows);
+ skin->windows = NULL;
+
+ for (i=0; i<skin->fontcount; i++)
+ {
+ unsigned int x;
+ if(skin->fonts[i]->name)
+ {
+ free(skin->fonts[i]->name);
+ skin->fonts[i]->name = NULL;
+ }
+
+ if(skin->fonts[i]->id)
+ {
+ free(skin->fonts[i]->id);
+ skin->fonts[i]->id = NULL;
+ }
+
+ for (x=0; x<skin->fonts[i]->charcount; x++)
+ {
+ free(skin->fonts[i]->chars[x]);
+ skin->fonts[i]->chars[x] = NULL;
+ }
+
+ if(skin->fonts[i]->chars)
+ {
+ free(skin->fonts[i]->chars);
+ skin->fonts[i]->chars = NULL;
+ }
+
+ free(skin->fonts[i]);
+ skin->fonts[i] = NULL;
+ }
+ free(skin->fonts);
+ skin->fonts = NULL;
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN FREE] skin freed\n");
+#endif
+ free(skin);
+ skin = NULL;
+}
+
+static void removewidget(skin_t *skin, int id)
+{
+ unsigned int i;
+ unsigned int pos=0;
+ widget **temp = calloc(skin->widgetcount - 1, sizeof(widget *));
+
+ for (i=0; i<skin->widgetcount; i++)
+ {
+ if(skin->widgets[i]->id == id)
+ {
+ if(skin->widgets[i]->label)
+ free(skin->widgets[i]->label);
+ free(skin->widgets[i]);
+ skin->widgets[i] = NULL;
+ }
+ else
+ {
+ temp[pos] = skin->widgets[i];
+ pos++;
+ }
+ }
+ if (pos != i)
+ {
+ (skin->widgetcount)--;
+ free(skin->widgets);
+ skin->widgets = temp;
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "removed widget %i\n", id);
+#endif
+ return;
+ }
+ free(temp);
+ mp_msg(MSGT_GPLAYER, MSGL_ERR, "widget %i not found\n", id);
+}
+
+static void addwidget(skin_t *skin, window *win, const char *desc)
+{
+ widget *mywidget;
+ char *temp = calloc(1, strlen(desc) + 1);
+ (skin->widgetcount)++;
+ (skin->lastusedid)++;
+ skin->widgets = realloc(skin->widgets, sizeof(widget *) * skin->widgetcount);
+ mywidget = skin->widgets[(skin->widgetcount) - 1] = calloc(1, sizeof(widget));
+ mywidget->id = skin->lastusedid;
+ mywidget->window = win->type;
+ /* parse and fill widget specific info */
+ if(!strncmp(desc, "base", 4))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ mywidget->type = tyBase;
+ mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+ mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+ mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+ mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+ mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+ win->base = mywidget;
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] %s %i %i %i %i\n",
+ (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+ mywidget->x, mywidget->y, mywidget->width, mywidget->height);
+#endif
+ }
+ else if(!strncmp(desc, "button", 6))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ int i;
+ mywidget->type = tyButton;
+ mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+ mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+ mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+ mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+ mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+
+ /* Assign corresponding event to the widget */
+ mywidget->msg = evNone;
+ for (i=0; i<evBoxs; i++)
+ {
+ if(!strcmp(temp, evNames[i].name))
+ {
+ mywidget->msg = evNames[i].msg;
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BUTTON] %s %i %i %i %i msg %i\n",
+ (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+ mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
+#endif
+ }
+ else if(!strncmp(desc, "hpotmeter", 9) || !strncmp(desc, "vpotmeter", 9))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ int i;
+ /* hpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message */
+ if(!strncmp(desc, "hpotmeter", 9)) mywidget->type = tyHpotmeter;
+ else mywidget->type = tyVpotmeter;
+ mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+ mywidget->width = atoi(findnextstring(temp, desc, &base));
+ mywidget->height = atoi(findnextstring(temp, desc, &base));
+ mywidget->bitmap[1] = pngRead(skin, findnextstring(temp, desc, &base));
+ mywidget->phases = atoi(findnextstring(temp, desc, &base));
+ mywidget->value = atof(findnextstring(temp, desc, &base));
+ mywidget->x = mywidget->wx = atoi(findnextstring(temp, desc, &base));
+ mywidget->y = mywidget->wy = atoi(findnextstring(temp, desc, &base));
+ mywidget->wwidth = atoi(findnextstring(temp, desc, &base));
+ mywidget->wheight = atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+ mywidget->msg = evNone;
+ for (i=0; i<evBoxs; i++)
+ {
+ if(!strcmp(temp, evNames[i].name))
+ {
+ mywidget->msg = evNames[i].msg;
+ break;
+ }
+ }
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] %s %s %i %i %s %i %f %i %i %i %i msg %i\n",
+ (mywidget->type == tyHpotmeter) ? "[HPOTMETER]" : "[VPOTMETER]",
+ (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+ mywidget->width, mywidget->height,
+ (mywidget->bitmap[1]) ? mywidget->bitmap[1]->name : NULL,
+ mywidget->phases, mywidget->value,
+ mywidget->wx, mywidget->wy, mywidget->wwidth, mywidget->wwidth,
+ mywidget->msg);
+#endif
+ }
+ else if(!strncmp(desc, "potmeter", 8))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ int i;
+ /* potmeter = phases, numphases, default, X, Y, width, height, message */
+ mywidget->type = tyPotmeter;
+ mywidget->bitmap[0] = pngRead(skin, findnextstring(temp, desc, &base));
+ mywidget->phases = atoi(findnextstring(temp, desc, &base));
+ mywidget->value = atof(findnextstring(temp, desc, &base));
+ mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+ mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+ mywidget->wwidth = mywidget->width = atoi(findnextstring(temp, desc, &base));
+ mywidget->wheight = mywidget->height = atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+ mywidget->msg = evNone;
+ for (i=0; i<evBoxs; i++)
+ {
+ if(!strcmp(temp, evNames[i].name))
+ {
+ mywidget->msg=evNames[i].msg;
+ break;
+ }
+ }
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [POTMETER] %s %i %i %i %f %i %i msg %i\n",
+ (mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
+ mywidget->width, mywidget->height,
+ mywidget->phases, mywidget->value,
+ mywidget->x, mywidget->y,
+ mywidget->msg);
+#endif
+ }
+ else if(!strncmp(desc, "menu", 4))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ int i;
+ mywidget->type = tyMenu;
+ mywidget->wx=atoi(findnextstring(temp, desc, &base));
+ mywidget->x=0;
+ mywidget->wy=mywidget->y=atoi(findnextstring(temp, desc, &base));
+ mywidget->wwidth=mywidget->width=atoi(findnextstring(temp, desc, &base));
+ mywidget->wheight=mywidget->height=atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+ mywidget->msg = evNone;
+ for (i=0; i<evBoxs; i++)
+ {
+ if(!strcmp(temp, evNames[i].name))
+ {
+ mywidget->msg = evNames[i].msg;
+ break;
+ }
+ }
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [MENU] %i %i %i %i msg %i\n",
+ mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
+#endif
+ }
+ else if(!strncmp(desc, "selected", 8))
+ {
+ win->base->bitmap[1] = pngRead(skin, (char *) desc + 9);
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [BASE] added image %s\n", win->base->bitmap[1]->name);
+#endif
+ }
+ else if(!strncmp(desc, "slabel",6))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ unsigned int i;
+ mywidget->type = tySlabel;
+ mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+ mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+ mywidget->font = NULL;
+ for (i=0; i<skin->fontcount; i++)
+ {
+ if(!strcmp(temp, skin->fonts[i]->name))
+ {
+ mywidget->font = skin->fonts[i];
+ break;
+ }
+ }
+ mywidget->label = strdup(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [SLABEL] %i %i %s %s\n",
+ mywidget->x, mywidget->y, mywidget->font->name, mywidget->label);
+#endif
+ }
+ else if(!strncmp(desc, "dlabel", 6))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ unsigned int i;
+ mywidget->type = tyDlabel;
+ mywidget->wx = mywidget->x = atoi(findnextstring(temp, desc, &base));
+ mywidget->wy = mywidget->y = atoi(findnextstring(temp, desc, &base));
+ mywidget->length = atoi(findnextstring(temp, desc, &base));
+ mywidget->align = atoi(findnextstring(temp, desc, &base));
+ findnextstring(temp, desc, &base);
+ mywidget->font = NULL;
+ for (i=0; i<skin->fontcount; i++)
+ {
+ if(!strcmp(temp, skin->fonts[i]->name))
+ {
+ mywidget->font=skin->fonts[i];
+ break;
+ }
+ }
+ mywidget->label=strdup(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [ITEM] [DLABEL] %i %i %i %i %s \"%s\"\n",
+ mywidget->x, mywidget->y, mywidget->length, mywidget->align, mywidget->font->name, mywidget->label);
+#endif
+ }
+ free(temp);
+}
+
+static void loadfonts(skin_t* skin)
+{
+ unsigned int x;
+ for (x=0; x<skin->fontcount; x++)
+ {
+ FILE *fp;
+ int linenumber=0;
+ char *filename;
+ char *tmp = calloc(1, MAX_LINESIZE);
+ char *desc = calloc(1, MAX_LINESIZE);
+ filename = calloc(1, strlen(skin->skindir) + strlen(skin->fonts[x]->name) + 6);
+ sprintf(filename, "%s\\%s.fnt", skin->skindir, skin->fonts[x]->name);
+ if(!(fp = fopen(filename,"rb")))
+ {
+ mp_msg(MSGT_GPLAYER, MSGL_ERR, "[FONT LOAD] Font not found \"%s\"\n", skin->fonts[x]->name);
+ return;
+ }
+ while(!feof(fp))
+ {
+ int pos = 0;
+ unsigned int i;
+ fgets(tmp, MAX_LINESIZE, fp);
+ linenumber++;
+ memset(desc, 0, MAX_LINESIZE);
+ for (i=0; i<strlen(tmp); i++)
+ {
+ /* remove spaces and linebreaks */
+ if((tmp[i] == ' ') || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
+ /* remove comments */
+ if((tmp[i] == ';') && ((i < 1) || (tmp[i-1] != '\"')))
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT LOAD] Comment: %s", tmp + i + 1);
+#endif
+ break;
+ }
+ desc[pos] = tmp[i];
+ pos++;
+ }
+ if(!strlen(desc)) continue;
+ /* now we have "readable" output -> parse it */
+ if(!strncmp(desc, "image", 5))
+ {
+ skin->fonts[x]->image = pngRead(skin, desc + 6);
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [IMAGE] \"%s\"\n", desc + 6);
+#endif
+ }
+ else
+ {
+ int base = 4;
+ if(*desc != '"') break;
+ if(*(desc + 1) == 0) break;
+ (skin->fonts[x]->charcount)++;
+ skin->fonts[x]->chars = realloc(skin->fonts[x]->chars, sizeof(char_t *) *skin->fonts[x]->charcount);
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]=calloc(1, sizeof(char_t));
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c = ((*(desc + 1) == '"') && (*(desc + 2) != '"')) ? ' ': *(desc + 1);
+ if((*(desc + 1) == '"') && (*(desc + 2) != '"')) base = 3;
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x = atoi(findnextstring(tmp, desc, &base));
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y = atoi(findnextstring(tmp, desc, &base));
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width = atoi(findnextstring(tmp, desc, &base));
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height = atoi(findnextstring(tmp, desc, &base));
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[FONT] [CHAR] %c %i %i %i %i\n",
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->c,
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->x,
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->y,
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->width,
+ skin->fonts[x]->chars[skin->fonts[x]->charcount - 1]->height);
+#endif
+ }
+ }
+ free(desc);
+ free(filename);
+ free(tmp);
+ fclose(fp);
+ }
+}
+
+skin_t* loadskin(char* skindir, int desktopbpp)
+{
+ FILE *fp;
+ int reachedendofwindow = 0;
+ int linenumber = 0;
+ skin_t *skin = calloc(1, sizeof(skin_t));
+ char *filename;
+ char *tmp = calloc(1, MAX_LINESIZE);
+ char *desc = calloc(1, MAX_LINESIZE);
+ window* mywindow = NULL;
+
+ /* init swscaler */
+ sws_rgb2rgb_init(get_sws_cpuflags());
+ /* setup funcs */
+ skin->freeskin = freeskin;
+ skin->pngRead = pngRead;
+ skin->addwidget = addwidget;
+ skin->removewidget = removewidget;
+ skin->geteventname = geteventname;
+ skin->desktopbpp = desktopbpp;
+ skin->skindir = strdup(skindir);
+
+ filename = calloc(1, strlen(skin->skindir) + strlen("skin") + 2);
+ sprintf(filename, "%s\\skin", skin->skindir);
+ if(!(fp = fopen(filename, "rb")))
+ {
+ mp_msg(MSGT_GPLAYER, MSGL_FATAL, "[SKIN LOAD] Skin \"%s\" not found\n", skindir);
+ skin->freeskin(skin);
+ return NULL;
+ }
+
+ while(!feof(fp))
+ {
+ int pos = 0;
+ unsigned int i;
+ int insidequote = 0;
+ fgets(tmp, MAX_LINESIZE, fp);
+ linenumber++;
+ memset(desc, 0, MAX_LINESIZE);
+ for (i=0; i<strlen(tmp); i++)
+ {
+ if((tmp[i] == '"') && !insidequote) { insidequote=1; continue; }
+ else if((tmp[i] == '"') && insidequote) { insidequote=0 ; continue; }
+ /* remove spaces and linebreaks */
+ if((!insidequote && (tmp[i] == ' ')) || (tmp[i] == '\n') || (tmp[i] == '\r')) continue;
+ /* remove comments */
+ else if(tmp[i] == ';')
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN LOAD] Comment: %s", tmp + i + 1);
+#endif
+ break;
+ }
+ desc[pos] = tmp[i];
+ pos++;
+ }
+
+ if(!strlen(desc)) continue;
+ /* now we have "readable" output -> parse it */
+ /* parse window specific info */
+ if(!strncmp(desc, "section", 7))
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [SECTION] \"%s\"\n", desc + 8);
+#endif
+ }
+ else if(!strncmp(desc, "window", 6))
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [WINDOW] \"%s\"\n", desc + 7);
+#endif
+ reachedendofwindow = 0;
+ (skin->windowcount)++;
+ skin->windows = realloc(skin->windows, sizeof(window *) * skin->windowcount);
+ mywindow = skin->windows[(skin->windowcount) - 1] = calloc(1, sizeof(window));
+ mywindow->name = strdup(desc + 7);
+ if(!strncmp(desc + 7, "main", 4)) mywindow->type = wiMain;
+ else if(!strncmp(desc+7, "sub", 3))
+ {
+ mywindow->type = wiSub;
+ mywindow->decoration = 1;
+ }
+ else if(!strncmp(desc + 7, "menu", 4)) mywindow->type = wiMenu;
+ else if(!strncmp(desc + 7, "playbar", 7)) mywindow->type = wiPlaybar;
+ else mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN] warning found unknown windowtype");
+ }
+ else if(!strncmp(desc, "decoration", 10) && !strncmp(desc + 11, "enable", 6))
+ {
+ mywindow->decoration = 1;
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [DECORATION] enabled decoration for window \"%s\"\n", mywindow->name);
+#endif
+ }
+ else if(!strncmp(desc, "background", 10))
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ char temp[MAX_LINESIZE];
+ mywindow->backgroundcolor[0] = atoi(findnextstring(temp, desc, &base));
+ mywindow->backgroundcolor[1] = atoi(findnextstring(temp, desc, &base));
+ mywindow->backgroundcolor[2] = atoi(findnextstring(temp, desc, &base));
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [BACKGROUND] window \"%s\" has backgroundcolor (%i,%i,%i)\n", mywindow->name,
+ mywindow->backgroundcolor[0],
+ mywindow->backgroundcolor[1],
+ mywindow->backgroundcolor[2]);
+#endif
+ }
+ else if(!strncmp(desc, "end", 3))
+ {
+ if(reachedendofwindow)
+ {
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of section\n");
+#endif
+ }
+ else
+ {
+ reachedendofwindow = 1;
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [END] of window \"%s\"\n", mywindow->name);
+#endif
+ }
+ }
+ else if(!strncmp(desc, "font", 4))
+ {
+ unsigned int i;
+ int id = 0;
+ char temp[MAX_LINESIZE];
+ int base = counttonextchar(desc, '=')+1;
+ findnextstring(temp, desc, &base);
+ findnextstring(temp, desc, &base);
+ for (i=0; i<skin->fontcount; i++)
+ if(!strcmp(skin->fonts[i]->id, temp))
+ {
+ id = i;
+ break;
+ }
+ if(!id)
+ {
+ int base = counttonextchar(desc, '=') + 1;
+ findnextstring(temp, desc, &base);
+ id = skin->fontcount;
+ (skin->fontcount)++;
+ skin->fonts = realloc(skin->fonts, sizeof(font_t *) * skin->fontcount);
+ skin->fonts[id]=calloc(1, sizeof(font_t));
+ skin->fonts[id]->name = strdup(temp);
+ skin->fonts[id]->id = strdup(findnextstring(temp, desc, &base));
+ }
+#ifdef DEBUG
+ mp_msg(MSGT_GPLAYER, MSGL_DBG4, "[SKIN] [FONT] id \"%s\" name \"%s\"\n", skin->fonts[id]->name, skin->fonts[id]->id);
+#endif
+ }
+ else
+ skin->addwidget(skin, mywindow, desc);
+ }
+
+ free(desc);
+ free(filename);
+ free(tmp);
+ fclose(fp);
+ loadfonts(skin);
+ mp_msg(MSGT_GPLAYER, MSGL_V, "[SKIN LOAD] loaded skin \"%s\"\n", skin->skindir);
+ /* dumpwidgets(skin); */
+ return skin;
+}