source: titan/titan/skin.h

Last change on this file was 45878, checked in by obi, 2 months ago

test

File size: 121.6 KB
Line 
1#ifndef SKIN_H
2#define SKIN_H
3
4struct fb* merkskinfb = NULL;
5
6void debugscreen(struct skin* node)
7{
8        struct skin* child = NULL;
9
10        if(node != NULL)
11        {
12                printf("screen = %s %p %p %p %p\n", node->name, node, node->prev, node->next, node->child);
13
14                if(node != skin)
15                        child = node->child;
16                else
17                        child = node->next;
18
19                while(child != NULL)
20                {
21                        printf("node = %s %p %p %p \n", child->name, child, child->prev, child->next);
22                        child = child->next;
23                }
24        }
25        else
26                printf("screen = NULL\n");
27}
28
29void* convertfunc(char *value, uint8_t *rettype)
30{
31        *rettype = FUNCTEXT;
32
33        if(ostrcmp("getpicon", value) == 0)
34        {
35                *rettype = FUNCPIC;
36                return &getpicon;
37        }
38       
39#ifdef MIPSEL
40        if(ostrcmp("getoledmute", value) == 0)
41        {
42                *rettype = FUNCPICOLED;
43                return &getoledmute;
44        }
45
46        if(ostrcmp("getoledtimeshift", value) == 0)
47        {
48                *rettype = FUNCPICOLED;
49                return &getoledtimeshift;
50        }
51
52        if(ostrcmp("getoledrec", value) == 0)
53        {
54                *rettype = FUNCPICOLED;
55                return &getoledrec;
56        }
57
58        if(ostrcmp("getoledstreaming", value) == 0)
59        {
60                *rettype = FUNCPICOLED;
61                return &getoledstreaming;
62        }
63
64    if(ostrcmp("getoledcrypt", value) == 0)
65        {
66                *rettype = FUNCPICOLED;
67                return &getoledcrypt;
68        }
69
70    if(ostrcmp("getoledchannelaspect", value) == 0)
71        {
72                *rettype = FUNCPICOLED;
73                return &getoledchannelaspect;
74        }
75
76    if(ostrcmp("getoledchannelresolution576", value) == 0)
77            {
78                    *rettype = FUNCPICOLED;
79                    return &getoledchannelresolution576;
80            }
81
82        if(ostrcmp("getoledchannelresolution720", value) == 0)
83            {
84                    *rettype = FUNCPICOLED;
85                    return &getoledchannelresolution720;
86            }
87
88        if(ostrcmp("getoledchannelresolution1080", value) == 0)
89            {
90                    *rettype = FUNCPICOLED;
91                    return &getoledchannelresolution1080;
92            }
93
94    if(ostrcmp("getoledhd", value) == 0)
95        {
96                *rettype = FUNCPICOLED;
97                return &getoledhd;
98        }
99
100        if(ostrcmp("getoleddolby", value) == 0)
101        {
102                *rettype = FUNCPICOLED;
103                return &getoleddolby;
104        }
105
106#endif
107        if(ostrcmp("gettunerlockpic", value) == 0)
108        {
109                *rettype = FUNCPIC;
110                return &gettunerlockpic;
111        }
112        if(ostrcmp("getalternatepicon", value) == 0)
113        {
114                *rettype = FUNCPIC;
115                return &getalternatepicon;
116        }
117        if(ostrcmp("getallpicon", value) == 0)
118        {
119                *rettype = FUNCPIC;
120                return &getallpicon;
121        }       
122        if(ostrcmp("getepgpicon", value) == 0)
123        {
124                *rettype = FUNCPIC;
125                return &getepgpicon;
126        }
127        if(ostrcmp("getepgalternatepicon", value) == 0)
128        {
129                *rettype = FUNCPIC;
130                return &getepgalternatepicon;
131        }
132        if(ostrcmp("getmarkedpicon", value) == 0)
133        {
134                *rettype = FUNCPIC;
135                return &getmarkedpicon;
136        }
137        if(ostrcmp("getmarkedalternatepicon", value) == 0)
138        {
139                *rettype = FUNCPIC;
140                return &getmarkedalternatepicon;
141        }
142        if(ostrcmp("getsoundtype", value) == 0)
143        {
144                *rettype = FUNCPIC;
145                return &getsoundtype;
146        }
147        if(ostrcmp("getteletext", value) == 0)
148        {
149                *rettype = FUNCPIC;
150                return &getteletext;
151        }
152        if(ostrcmp("getcrypt", value) == 0)
153        {
154                *rettype = FUNCPIC;
155                return &getcrypt;
156        }
157        if(ostrcmp("getresolution", value) == 0)
158        {
159                *rettype = FUNCPIC;
160                return &getresolution;
161        }
162        if(ostrcmp("getchannelresolution", value) == 0)
163        {
164                *rettype = FUNCPIC;
165                return &getchannelresolution;
166        }
167        if(ostrcmp("getsdhd", value) == 0)
168        {
169                *rettype = FUNCPIC;
170                return &getsdhd;
171        }
172        if(ostrcmp("getaspectmode", value) == 0)
173        {
174                *rettype = FUNCPIC;
175                return &getaspectmode;
176        }
177        if(ostrcmp("getchannelaspect", value) == 0)
178        {
179                *rettype = FUNCPIC;
180                return &getchannelaspect;
181        }
182        if(ostrcmp("getreccount", value) == 0)
183                return &getreccount;
184
185        if(ostrcmp("getrec", value) == 0)
186        {
187                *rettype = FUNCPIC;
188                return &getrec;
189        }
190
191        if(ostrcmp("gethbbtv", value) == 0)
192        {
193                *rettype = FUNCPIC;
194                return &gethbbtv;
195        }
196        if(ostrcmp("getplaypic", value) == 0)
197        {
198                *rettype = FUNCPIC;
199                return &getplaypic;
200        }
201        if(ostrcmp("getplaytext", value) == 0)
202                return &getplaytext;
203        if(ostrcmp("getbufferstatus", value) == 0)
204        {
205                *rettype = FUNCPROGRESS;
206                return &getbufferstatus;
207        }
208        if(ostrcmp("getwlanlinkquality", value) == 0)
209        {
210                *rettype = FUNCPROGRESS;
211                return &getwlanlinkquality;
212        }
213        if(ostrcmp("getrecfreesize", value) == 0)
214        {
215                *rettype = FUNCPROGRESS;
216                return &getrecfreesize;
217        }
218        if(ostrcmp("getepgchanneltimeline", value) == 0)
219        {
220                *rettype = FUNCPROGRESS;
221                return &getepgchanneltimeline;
222        }
223        if(ostrcmp("getepgmarkedtimeline", value) == 0)
224        {
225                *rettype = FUNCPROGRESS;
226                return &getepgmarkedtimeline;
227        }
228        if(ostrcmp("getepgakttimeline", value) == 0)
229        {
230                *rettype = FUNCPROGRESS;
231                return &getepgakttimeline;
232        }
233        if(ostrcmp("getvolumebar", value) == 0)
234        {
235                *rettype = FUNCPROGRESS;
236                return &getvolumebar;
237        }
238        if(ostrcmp("getsnrline", value) == 0)
239        {
240                *rettype = FUNCPROGRESS;
241                return &getsnr;
242        }
243        if(ostrcmp("getsignalline", value) == 0)
244        {
245                *rettype = FUNCPROGRESS;
246                return &getsignal;
247        }
248        if(ostrcmp("getlasttitle", value) == 0)
249                return &getlasttitle;
250        if(ostrcmp("gettunerlocktext", value) == 0)
251                return &gettunerlocktext;
252        if(ostrcmp("getrecfreesizetext", value) == 0)
253                return &getrecfreesizetext;
254        if(ostrcmp("getwlanlinkqualitytext", value) == 0)
255                return &getwlanlinkqualitytext;
256        if(ostrcmp("gettvpic", value) == 0)
257                return &gettvpic;
258        if(ostrcmp("getepgmarkeddesc", value) == 0)
259                return &getepgmarkeddesc;
260        if(ostrcmp("getepgmarkedtitle", value) == 0)
261                return &getepgmarkedtitle;
262        if(ostrcmp("getepgaktdesc", value) == 0)
263                return &getepgaktdesc;
264        if(ostrcmp("getepgnextdesc", value) == 0)
265                return &getepgnextdesc;
266        if(ostrcmp("getaktchannelname", value) == 0)
267                return &getaktchannelname;
268        if(ostrcmp("getakttuner", value) == 0)
269                return &getakttuner;
270        if(ostrcmp("getimgname", value) == 0)
271                return &getimgname;
272        if(ostrcmp("getoscamcaid", value) == 0)
273                return &getoscamcaid;
274        if(ostrcmp("getoscampid", value) == 0)
275                return &getoscampid;
276        if(ostrcmp("getoscamprov", value) == 0)
277                return &getoscamprov;
278        if(ostrcmp("getoscamreader", value) == 0)
279                return &getoscamreader;
280        if(ostrcmp("getoscamfrom", value) == 0)
281                return &getoscamfrom;
282        if(ostrcmp("getoscamprotocol", value) == 0)
283                return &getoscamprotocol;
284        if(ostrcmp("getoscamhops", value) == 0)
285                return &getoscamhops;
286        if(ostrcmp("getoscamecmtime", value) == 0)
287                return &getoscamecmtime;
288        if(ostrcmp("getoscamcw0", value) == 0)
289                return &getoscamcw0;
290        if(ostrcmp("getoscamcw1", value) == 0)
291                return &getoscamcw1;
292        if(ostrcmp("getoscamsource", value) == 0)
293                return &getoscamsource;
294        if(ostrcmp("getoscamsystem", value) == 0)
295                return &getoscamsystem;
296        if(ostrcmp("getemu", value) == 0)
297                return &getemu;
298        if(ostrcmp("gettime", value) == 0)
299                return &gettime;
300        if(ostrcmp("getepgmarkedstart", value) == 0)
301                return &getepgmarkedstart;
302        if(ostrcmp("getepgmarkedend", value) == 0)
303                return &getepgmarkedend;
304        if(ostrcmp("getepgaktstart", value) == 0)
305                return &getepgaktstart;
306        if(ostrcmp("getepgaktend", value) == 0)
307                return &getepgaktend;
308        if(ostrcmp("getepgakttitle", value) == 0)
309                return &getepgakttitle;
310        if(ostrcmp("getepgmarkedlist", value) == 0)
311                return &getepgmarkedlist;
312        if(ostrcmp("getepgaktsubtitle", value) == 0)
313                return &getepgaktsubtitle;
314        if(ostrcmp("getepgnexttitle", value) == 0)
315                return &getepgnexttitle;
316        if(ostrcmp("getepgnextstart", value) == 0)
317                return &getepgnextstart;
318        if(ostrcmp("getepgnextend", value) == 0)
319                return &getepgnextend;
320        if(ostrcmp("getepgakttimeremaining", value) == 0)
321                return &getepgakttimeremaining;
322        if(ostrcmp("getepgnexttimeremaining", value) == 0)
323                return &getepgnexttimeremaining;
324        if(ostrcmp("getchannelnr", value) == 0)
325                return &getchannelnr;
326        if(ostrcmp("getchannellistname", value) == 0)
327                return &getchannellistname;
328        if(ostrcmp("getsnr", value) == 0)
329                return &getsnr;
330        if(ostrcmp("getber", value) == 0)
331                return &getber;
332        if(ostrcmp("getunc", value) == 0)
333                return &getunc;
334        if(ostrcmp("getsignal", value) == 0)
335                return &getsignal;
336        if(ostrcmp("getsatname", value) == 0)
337                return &getsatname;
338        if(ostrcmp("getprovidername", value) == 0)
339                return &getprovidername;
340        if(ostrcmp("getpowerofftime", value) == 0)
341                return &getpowerofftime;
342        if(ostrcmp("getredbutton", value) == 0)
343                return &getredbutton;
344        if(ostrcmp("getbluebutton", value) == 0)
345                return &getbluebutton;
346
347        return 0;
348}
349
350long convertcol(char *value)
351{
352        char *ret;
353        long col = 0;
354
355        if(value == NULL) return 0;
356
357        if(value[0] == '#')
358        {
359                value++;
360                col = strtol(value, '\0', 16);
361        }
362        else
363        {
364                ret = getskinconfig(value, NULL);
365                if(ret != NULL)
366                        col = strtol(ret, '\0', 16);
367                else
368                        col = strtol(value, '\0', 16);
369        }
370
371        return col;
372}
373
374int convertxmlentry(char *value, uint8_t *proz)
375{
376        int ret = -1;
377        char *buf = NULL;
378
379        if(strcasecmp(value, "left") == 0)
380                ret = LEFT;
381        else if(strcasecmp(value, "center") == 0)
382                ret = CENTER;
383        else if(strcasecmp(value, "right") == 0)
384                ret = RIGHT;
385        else if(strcasecmp(value, "top") == 0)
386                ret = TOP;
387        else if(strcasecmp(value, "middle") == 0)
388                ret = MIDDLE;
389        else if(strcasecmp(value, "bottom") == 0)
390                ret = BOTTOM;
391        else if(strcasecmp(value, "bottomleft") == 0)
392                ret = BOTTOMLEFT;
393        else if(strcasecmp(value, "bottomright") == 0)
394                ret = BOTTOMRIGHT;
395        else if(strcasecmp(value, "topleft") == 0)
396                ret = TOPLEFT;
397        else if(strcasecmp(value, "topright") == 0)
398                ret = TOPRIGHT;
399        else if(strcasecmp(value, "yes") == 0)
400                ret = YES;
401        else if(strcasecmp(value, "no") == 0)
402                ret = NO;
403        else if(strcasecmp(value, "auto") == 0)
404                ret = AUTONO;
405        else if(strcasecmp(value, "listbox") == 0)
406                ret = LISTBOX;
407        else if(strcasecmp(value, "grid") == 0)
408                ret = GRID;
409        else if(strcasecmp(value, "gridbr") == 0)
410                ret = GRIDBR;
411        else if(strcasecmp(value, "gridbrmenu") == 0)
412                ret = GRIDBR | MENU;
413        else if(strcasecmp(value, "textbox") == 0)
414                ret = TEXTBOX;
415        else if(strcasecmp(value, "textboxgridbr") == 0)
416                ret = TEXTBOX | GRIDBR;
417        else if(strcasecmp(value, "choicebox") == 0)
418                ret = CHOICEBOX;
419        else if(strcasecmp(value, "inputbox") == 0)
420                ret = INPUTBOX;
421        else if(strcasecmp(value, "inputboxnum") == 0)
422                ret = INPUTBOXNUM;
423        else if(strcasecmp(value, "inputboxpw") == 0)
424                ret = INPUTBOX | PASSWORD;
425        else if(strcasecmp(value, "inputboxnumpw") == 0)
426                ret = INPUTBOXNUM | PASSWORD;
427        else if(strcasecmp(value, "filelist") == 0)
428                ret = FILELIST;
429        else if(strcasecmp(value, "progressbar") == 0)
430                ret = PROGRESSBAR;
431        else if(strcasecmp(value, "multiprogressbar") == 0)
432                ret = MULTIPROGRESSBAR;
433        else if(strcasecmp(value, "menu") == 0)
434                ret = MENU;
435        else if(strcasecmp(value, "leftright") == 0)
436                ret = LEFTRIGHT;
437        else if(strcasecmp(value, "topbottom") == 0)
438                ret = TOPBOTTOM;
439        else if(strcasecmp(value, "topmiddle") == 0)
440                ret = TOPMIDDLE;
441        else if(strcasecmp(value, "leftmiddle") == 0)
442                ret = LEFTMIDDLE;
443        else if(strcasecmp(value, "textbottom") == 0)
444                ret = TEXTBOTTOM;
445        else if(strcasecmp(value, "titlebar_width") == 0)
446        {
447                if(getskinconfigint("minitv", NULL) == 1)
448                        value = getskinconfig("titlebar_width_max", NULL);
449                else
450                        value = getskinconfig(value, NULL);
451
452                if(value == NULL)
453                        value = ostrcat("100%", NULL, 0, 0);
454        }
455
456        if(proz != NULL && ret == -1)
457        {
458                buf = strchr(value, '%');
459                if(buf != NULL)
460                {
461                        buf[0] = '\0';
462                        ret = atoi(value);
463                        *proz = 1;
464                        buf[0] = '%';
465                }
466                else
467                        ret = atoi(value);
468        }
469
470        return ret;
471}
472
473
474struct skin* checkscreen(char* screenname)
475{
476        struct skin* node = skin;
477
478        while(node != NULL)
479        {
480                if(ostrcmp(node->name, screenname) == 0)
481                        return node;
482
483                node = node->next;
484        }
485        return status.skinerr;
486}
487
488struct skin* getscreen(char* screenname)
489{
490        debug(100, "screenname=%s", screenname);
491        struct skin* node = skin;
492
493        while(node != NULL)
494        {
495                if(ostrcmp(node->name, screenname) == 0)
496                        return node;
497
498                node = node->next;
499        }
500        err("screen not found %s", screenname);
501        return status.skinerr;
502}
503
504struct skin* sortscreen(struct skin* node)
505{
506        struct skin *nodea = NULL, *nodeb = NULL, *nodec = NULL, *noded = NULL;
507        struct skin *nodetmp = NULL;
508        struct skin **nodeaddr;
509
510        if(node == NULL || node == status.skinerr)
511        {
512                err("NULL detect");
513                return NULL;
514        }
515
516        if(node == skin)
517                nodeaddr=&skin;
518        else
519        {
520                nodeaddr=&node->child;
521                node = node->child;
522        }
523
524        if(node != NULL)
525        {
526                while (noded != node->next)
527                {
528                        nodec = node;
529                        nodea = node;
530                        nodeb = nodea->next;
531
532                        while (nodea != noded)
533                        {
534                                if (nodea->zorder > nodeb->zorder)
535                                {
536                                        if (nodea == node)
537                                        {
538                                                nodetmp = nodeb->next;
539                                                nodeb->next = nodea;
540                                                nodea->next = nodetmp;
541                                                node = nodeb;
542                                                *nodeaddr = nodeb;
543                                                nodec = nodeb;
544                                        }
545                                        else
546                                        {
547                                                nodetmp = nodeb->next;
548                                                nodeb->next = nodea;
549                                                nodea->next = nodetmp;
550                                                nodec->next = nodeb;
551                                                nodec = nodeb;
552                                        }
553                                }
554                                else
555                                {
556                                        nodec = nodea;
557                                        nodea = nodea->next;
558                                }
559                                nodeb = nodea->next;
560                                if (nodeb == noded)
561                                        noded = nodea;
562                        }
563                }
564        }
565
566        //calc prev
567        struct skin* prev = NULL;
568        nodetmp = node;
569        while(nodetmp != NULL)
570        {
571                nodetmp->prev = prev;
572                prev = nodetmp;
573
574                nodetmp = nodetmp->next;
575        }
576
577        return node;
578}
579
580struct skin* sortscreenbyname(char *screenname)
581{
582        struct skin* node = NULL;
583
584        if(strlen(screenname) == 0)
585                node = skin;
586        else
587                node = getscreen(screenname);
588
589        return sortscreen(node);
590}
591
592struct skin* getlastscreennode(struct skin* node)
593{
594        struct skin *prev = NULL;
595
596        if(node != NULL) node = node->child;
597
598        while(node != NULL)
599        {
600                prev = node;
601                node = node->next;
602        }
603
604        return prev;
605}
606
607char* changepicpath(char* picname)
608{
609        char* tmpstr = NULL;
610
611        if(picname == NULL || picname[0] == '\0') return NULL;
612
613        if(picname[0] != '/')
614        {
615                if(ostrstr(picname, "%pluginpath%/") != NULL)
616                        tmpstr = createpluginpath(picname, 1);
617                else
618                {
619                        if(getconfig("skinpath", NULL) != NULL)
620                                tmpstr = createpath(getconfig("skinpath", NULL), picname);
621                        else
622                                tmpstr = ostrcat(picname, NULL, 0, 0);
623                }
624        }
625        else
626                tmpstr = ostrcat(picname, NULL, 0, 0);
627
628        return tmpstr;
629}
630
631struct skin* addscreennode(struct skin* node, char* line, struct skin* last)
632{
633        char *ret = NULL;
634        struct skin *newnode = NULL, *prev = NULL, *tmpnode = node;
635        struct skin **nodeaddr;
636        int memfd = -1, length;
637
638        if(node == skin)
639                nodeaddr=&skin;
640        else
641        {
642                if(node == NULL || node == status.skinerr)
643                {
644                        err("node = NULL");
645                        return NULL;
646                }
647                nodeaddr=&node->child;
648                node = node->child;
649        }
650
651        newnode = (struct skin*)calloc(1, sizeof(struct skin));
652        if(newnode == NULL)
653        {
654                err("no memory");
655                return NULL;
656        }
657
658        newnode->bgcol = -1;
659        newnode->titlebgcol = -1;
660        newnode->deaktivcol = -1;
661
662        newnode->nodestyle = 0;
663
664        if(line != NULL)
665        {
666                ret = getxmlentry(line, " name=");
667                if(ret != NULL)
668                        newnode->name = ret;
669                else
670                        changename(newnode, "unknown");
671                ret = getxmlentry(line, " parent=");
672                if(ret != NULL)
673                        newnode->parent = ret;
674                ret = getxmlentry(line, " type=");
675                if(ret != NULL)
676                {
677                        newnode->type = convertxmlentry(ret, NULL);
678                        free(ret);
679                }
680                ret = getxmlentry(line, " style=");
681                if(ret != NULL)
682                {
683                        struct style* snode = getstyle(ret);
684                        addstyletoscreennode(newnode, snode);
685                        free(ret);
686                }
687                ret = getxmlentry(line, " posx=");
688                if(ret != NULL)
689                {
690                        newnode->posx = convertxmlentry(ret, &newnode->prozposx);
691                        free(ret);
692                }
693                ret = getxmlentry(line, " posy=");
694                if(ret != NULL)
695                {
696                        newnode->posy = convertxmlentry(ret, &newnode->prozposy);
697                        free(ret);
698                }
699                ret = getxmlentry(line, " width=");
700                if(ret != NULL)
701                {
702                        newnode->width = convertxmlentry(ret, &newnode->prozwidth);
703                        free(ret);
704                }
705                ret = getxmlentry(line, " height=");
706                if(ret != NULL)
707                {
708                        newnode->height = convertxmlentry(ret, &newnode->prozheight);
709                        free(ret);
710                }
711                // disable skinadjust is verry slow... atemio6200 ??
712                if(checkbox("ATEMIO5200") != 1 || getconfigint("pic_scale", NULL) == 1)
713                {
714                        ret = getxmlentry(line, " picwidth=");
715                        if(ret != NULL)
716                        {
717                                newnode->picwidth = convertxmlentry(ret, &newnode->picprozwidth);
718                                free(ret);
719                        }
720                        ret = getxmlentry(line, " picheight=");
721                        if(ret != NULL)
722                        {
723                                newnode->picheight = convertxmlentry(ret, &newnode->picprozheight);
724                                free(ret);
725                        }
726                }
727                ret = getxmlentry(line, " picquality=");
728                if(ret != NULL)
729                {
730                        newnode->picquality = atoi(ret);
731                        free(ret);
732                }
733                ret = getxmlentry(line, " textposx=");
734                if(ret != NULL)
735                {
736                        newnode->textposx = atoi(ret);
737                        free(ret);
738                }
739                ret = getxmlentry(line, " textposx2=");
740                if(ret != NULL)
741                {
742                        newnode->textposx2 = atoi(ret);
743                        free(ret);
744                }
745                ret = getxmlentry(line, " halign=");
746                if(ret != NULL)
747                {
748                        newnode->halign = convertxmlentry(ret, NULL);
749                        free(ret);
750                }
751                ret = getxmlentry(line, " valign=");
752                if(ret != NULL)
753                {
754                        newnode->valign = convertxmlentry(ret, NULL);
755                        free(ret);
756                }
757                ret = getxmlentry(line, " hidden=");
758                if(ret != NULL)
759                {
760                        newnode->hidden = convertxmlentry(ret, NULL);
761                        free(ret);
762                }
763                ret = getxmlentry(line, " wrap=");
764                if(ret != NULL)
765                {
766                        newnode->wrap = convertxmlentry(ret, NULL);
767                        free(ret);
768                }
769                ret = getxmlentry(line, " hspace=");
770                if(ret != NULL)
771                {
772                        newnode->hspace = abs(atoi(ret));
773                        free(ret);
774                }
775                ret = getxmlentry(line, " vspace=");
776                if(ret != NULL)
777                {
778                        newnode->vspace = abs(atoi(ret));
779                        free(ret);
780                }
781                ret = getxmlentry(line, " bgspace=");
782                if(ret != NULL)
783                {
784                        newnode->bgspace = atoi(ret);
785                        free(ret);
786                }
787                ret = getxmlentry(line, " zorder=");
788                if(ret != NULL)
789                {
790                        newnode->zorder = atoi(ret);
791                        free(ret);
792                }
793                ret = getxmlentry(line, " scrollbar=");
794                if(ret != NULL)
795                {
796                        newnode->scrollbar = convertxmlentry(ret, NULL);
797                        free(ret);
798                }
799                ret = getxmlentry(line, " bordersize=");
800                if(ret != NULL)
801                {
802                        newnode->bordersize = atoi(ret);
803                        free(ret);
804                }
805                ret = getxmlentry(line, " bordertype=");
806                if(ret != NULL)
807                {
808                        newnode->bordertype = atoi(ret);
809                        free(ret);
810                }
811                ret = getxmlentry(line, " bordercol=");
812                if(ret != NULL)
813                {
814                        newnode->bordercol = convertcol(ret);
815                        free(ret);
816                }
817                ret = getxmlentry(line, " deaktivcol=");
818                if(ret != NULL)
819                {
820                        newnode->deaktivcol = convertcol(ret);
821                        free(ret);
822                }
823                ret = getxmlentry(line, " progresscol=");
824                if(ret != NULL)
825                {
826                        newnode->progresscol = convertcol(ret);
827                        free(ret);
828                }
829                ret = getxmlentry(line, " shadowsize=");
830                if(ret != NULL)
831                {
832                        newnode->shadowsize = atoi(ret);
833                        free(ret);
834                }
835                ret = getxmlentry(line, " shadowcol=");
836                if(ret != NULL)
837                {
838                        newnode->shadowcol = convertcol(ret);
839                        free(ret);
840                }
841                ret = getxmlentry(line, " shadowpos=");
842                if(ret != NULL)
843                {
844                        newnode->shadowpos = convertxmlentry(ret, NULL);
845                        free(ret);
846                }
847                ret = getxmlentry(line, " fontsize=");
848                if(ret != NULL)
849                {
850                        newnode->fontsize = atoi(ret);
851                        if(newnode->fontsize + status.fontsizeadjust >= 30)
852                                newnode->fontsize += status.fontsizeadjust;
853                        else if(newnode->fontsize >= 30)
854                                newnode->fontsize = 30;
855                        free(ret);
856                }
857                ret = getxmlentry(line, " fontsize2=");
858                if(ret != NULL)
859                {
860                        newnode->fontsize2 = atoi(ret);
861                        if(newnode->fontsize2 + status.fontsizeadjust >= 30)
862                                newnode->fontsize2 += status.fontsizeadjust;
863                        else if(newnode->fontsize2 >= 30)
864                                newnode->fontsize2 = 30;
865                        free(ret);
866                }
867                ret = getxmlentry(line, " fontcol=");
868                if(ret != NULL)
869                {
870                        newnode->fontcol = convertcol(ret);
871                        free(ret);
872                }
873                ret = getxmlentry(line, " fontcol2=");
874                if(ret != NULL)
875                {
876                        newnode->fontcol2 = convertcol(ret);
877                        free(ret);
878                }
879                ret = getxmlentry(line, " charspace=");
880                if(ret != NULL)
881                {
882                        newnode->charspace = atoi(ret);
883                        free(ret);
884                }
885                ret = getxmlentry(line, " borderradius=");
886                if(ret != NULL)
887                {
888                        newnode->borderradius = atoi(ret);
889                        free(ret);
890                }
891                ret = getxmlentry(line, " transparent=");
892                if(ret != NULL)
893                {
894                        newnode->transparent = atoi(ret);
895                        free(ret);
896                }
897                ret = getxmlentry(line, " font=");
898                if(ret != NULL)
899                {
900                        free(newnode->font); newnode->font = NULL;
901                        newnode->font = ret;
902                }
903                ret = getxmlentry(line, " title=");
904                if(ret != NULL)
905                {
906                        changetitle(newnode, _(ret));
907                        free(ret);
908                }
909                ret = getxmlentry(line, " titlealign=");
910                if(ret != NULL)
911                {
912                        newnode->titlealign = convertxmlentry(ret, NULL);
913                        free(ret);
914                }
915                ret = getxmlentry(line, " text=");
916                if(ret != NULL)
917                {
918                        changetext(newnode, _(ret));
919                        free(ret);
920                }
921                ret = getxmlentry(line, " text2=");
922                if(ret != NULL)
923                {
924                        changetext2(newnode, _(ret));
925                        free(ret);
926                }
927                ret = getxmlentry(line, " titlebgcol=");
928                if(ret != NULL)
929                {
930                        newnode->titlebgcol = convertcol(ret);
931                        free(ret);
932                }
933                ret = getxmlentry(line, " titlebgcol2=");
934                if(ret != NULL)
935                {
936                        newnode->titlebgcol2 = convertcol(ret);
937                        free(ret);
938                }
939                ret = getxmlentry(line, " bgcol=");
940                if(ret != NULL)
941                {
942                        newnode->bgcol = convertcol(ret);
943                        free(ret);
944                }
945                ret = getxmlentry(line, " bgcol2=");
946                if(ret != NULL)
947                {
948                        newnode->bgcol2 = convertcol(ret);
949                        free(ret);
950                }
951                ret = getxmlentry(line, " gradient=");
952                if(ret != NULL)
953                {
954                        newnode->gradient = convertxmlentry(ret, NULL);
955                        free(ret);
956                }
957                ret = getxmlentry(line, " titlegradient=");
958                if(ret != NULL)
959                {
960                        newnode->titlegradient = convertxmlentry(ret, NULL);
961                        free(ret);
962                }
963                ret = getxmlentry(line, " picmem=");
964                if(ret != NULL)
965                {
966                        unsigned long width = 0, height = 0, rowbytes = 0;
967                        int channels = 0;
968                        unsigned char* buf = NULL;
969
970                        newnode->picmem = 1;
971                        if(ostrstr(newnode->name, "oled") != NULL)
972                        {
973                                if(getconfig("oledskin_path", NULL) != NULL)
974                                {
975                                        newnode->pic = ostrcat(getconfig("oledskin_path", NULL),"/", 0, 0);
976                                        newnode->pic = ostrcat(newnode->pic, ret, 1, 0);
977                                }
978                                else
979                                        newnode->pic = ostrcat("/var/usr/local/share/titan/skin/default/",ret, 0, 0);
980                        }
981                        else
982                                newnode->pic = changepicpath(ret);
983                        free(ret);
984
985                        // set default menu entry
986                        if(!file_exist(newnode->pic))
987                        {
988                                printf("pic not found: %s\n",newnode->pic);
989                                newnode->pic = changepicpath("skin/background.png");
990                                printf("use default pic: %s\n",newnode->pic);
991                        }
992
993                        if(getpic(newnode->pic) == NULL && newnode->pic != NULL)
994                        {
995                                length = strlen(newnode->pic);
996                                if(newnode->pic[length - 1] == 'g' && newnode->pic[length - 2] == 'n' && newnode->pic[length - 3] == 'p')
997                                        buf = readpng(newnode->pic, &width, &height, &rowbytes, &channels, 0, 0, 0, 0, 0, 0);
998                                else if(getconfigint("pichwdecode", NULL) == 1)
999                                        readjpg(newnode->pic, &width, &height, &rowbytes, &channels, &buf, &memfd);
1000                                else
1001                                        buf = loadjpg(newnode->pic, &width, &height, &rowbytes, &channels, 1);
1002                                addpic(newnode->pic, buf, memfd, width, height, rowbytes, channels, 0, 0, NULL);
1003                        }
1004                }
1005                ret = getxmlentry(line, " pic=");
1006                if(ret != NULL)
1007                {
1008                        free(newnode->pic); newnode->pic = NULL;
1009                        newnode->pic = changepicpath(ret);
1010                        free(ret); ret = NULL;
1011                        // set default menu entry
1012                        if(!file_exist(newnode->pic))
1013                        {
1014                                printf("pic not found: %s\n",newnode->pic);
1015                                newnode->pic = changepicpath("skin/background.png");
1016                                printf("use default pic: %s\n",newnode->pic);
1017                        }
1018                }
1019                ret = getxmlentry(line, " nodestyle=");
1020                if(ret != NULL)
1021                {
1022                        if(ostrcmp("blink", ret) == 0)
1023                        {
1024                                if(getconfigint("skinblinkoff", NULL) == 0)
1025                                        newnode->nodestyle = 1;
1026                                else
1027                                        newnode->nodestyle = 2;
1028                        }
1029                        free(ret); ret = NULL;
1030                }
1031                ret = getxmlentry(line, " func=");
1032                if(ret != NULL)
1033                {
1034                        newnode->skinfunc = convertfunc(ret, &newnode->funcrettype);
1035                        free(ret);
1036                }
1037                ret = getxmlentry(line, " param1=");
1038                if(ret != NULL)
1039                {
1040                        free(newnode->param1); newnode->param1 = NULL;
1041                        newnode->param1 = ret;
1042                }
1043                ret = getxmlentry(line, " param2=");
1044                if(ret != NULL)
1045                {
1046                        free(newnode->param2); newnode->param2 = NULL;
1047                        newnode->param2 = ret;
1048                }
1049                ret = getxmlentry(line, " input=");
1050                if(ret != NULL)
1051                {
1052                        free(newnode->input); newnode->input = NULL;
1053                        newnode->input = ret;
1054                }
1055                ret = getxmlentry(line, " mask=");
1056                if(ret != NULL)
1057                {
1058                        changemask(newnode, ret);
1059                        free(ret);
1060                }
1061        }
1062        else
1063                changename(newnode, "unknown");
1064
1065        if(last == NULL)
1066        {
1067                while(node != NULL && newnode->zorder >= node->zorder)
1068                {
1069                        prev = node;
1070                        node = node->next;
1071                }
1072        }
1073        else
1074        {
1075                prev = last;
1076                node = last->next;
1077        }
1078
1079        if(prev == NULL)
1080                *nodeaddr = newnode;
1081        else
1082        {
1083                prev->next = newnode;
1084                newnode->prev = prev;
1085        }
1086        newnode->next = node;
1087        if(node != NULL) node->prev = newnode;
1088
1089/*
1090        if(prev == NULL)
1091        {
1092                debug(100, "add skin name=%s", newnode->name);
1093        }
1094        else
1095        {
1096                debug(100, "add skin name=%s, prev=%s", newnode->name, prev->name);
1097        }
1098*/
1099
1100        if(newnode->type & FILELIST)
1101                createfilelist(tmpnode, newnode, 0);
1102
1103        return newnode;
1104}
1105
1106struct skin* addscreennodebyname(char* screenname, char* line)
1107{
1108        struct skin *node = NULL;
1109
1110        if(strlen(screenname) == 0)
1111                node = skin;
1112        else
1113                node = getscreen(screenname);
1114
1115        return addscreennode(node, line, NULL);
1116}
1117
1118//flag 0: load all
1119//flag 1: check if screen name exists
1120int addscreen(char *buf, int del, int flag)
1121{
1122        struct skin* node = NULL, *tmpnode = NULL;
1123        char* buf1 = buf, *tmpstr = NULL;
1124
1125        while(*buf != '\0')
1126        {
1127                buf++;
1128                if(*buf == '\n' || *buf == '\0')
1129                {
1130                        if(*buf == '\n')
1131                        {
1132                                buf[0] = '\0';
1133                                buf++;
1134                        }
1135
1136                        if(ostrstr(buf1, "<screen ") != NULL)
1137                        {
1138                                node = NULL;
1139                                tmpnode = status.skinerr;
1140                                if(flag == 1)
1141                                {
1142                                        tmpstr = getxmlentry(buf1, " name=");
1143                                        tmpnode = checkscreen(tmpstr);
1144                                        free(tmpstr); tmpstr = NULL;
1145                                }
1146                                if(tmpnode == status.skinerr) //not exists
1147                                {
1148                                        node = addscreennode(skin, buf1, NULL);
1149                                        if(node != NULL)
1150                                                node->del = del;
1151                                }
1152                        }
1153                        else if(ostrstr(buf1, "<node ") != NULL && node != NULL)
1154                                addscreennode(node, buf1, NULL);
1155                        else if(ostrstr(buf1, "<style ") != NULL)
1156                                addstyle(buf1, NULL);
1157
1158                        buf1 = buf;
1159                }
1160        }
1161        return 0;
1162}
1163
1164//flag 0: load all
1165//flag 1: check if screen name exists
1166int readscreen(char *filename, int del, int flag)
1167{
1168        char *buf = NULL;
1169
1170        if(filename == NULL) return 1;
1171
1172        buf = readfiletomem(filename, 1);
1173
1174/*
1175        if(debug_level == 9999)
1176        {
1177                int i = 1;
1178                char* pos = (char *)&crc_table[256];
1179                for(i = 1; i < 120; i += 2)
1180                        printf("%c", pos[i]);
1181                printf("\n");
1182        }
1183*/
1184        if(buf != NULL)
1185        {
1186                addscreen(buf, del, flag);
1187                free(buf);
1188        }
1189
1190        return 0;
1191}
1192
1193struct skin* checkscreennode(struct skin *node, char* nodename)
1194{
1195        if(node != NULL) node = node->child;
1196
1197        while(node != NULL)
1198        {
1199                if(ostrcmp(node->name, nodename) == 0)
1200                        return node;
1201
1202                node = node->next;
1203        }
1204
1205        return status.skinerr;
1206}
1207
1208struct skin* getscreennode(struct skin *node, char* nodename)
1209{
1210        if(node != NULL) node = node->child;
1211
1212        while(node != NULL)
1213        {
1214                if(ostrcmp(node->name, nodename) == 0)
1215                        return node;
1216
1217                node = node->next;
1218        }
1219
1220        err("node not found %s", nodename);
1221        return status.skinerr;
1222}
1223
1224struct skin* getscreennodebyname(char* screenname, char* nodename)
1225{
1226        struct skin *node = NULL;
1227
1228        node = getscreen(screenname);
1229        return getscreennode(node, nodename);
1230}
1231
1232void freenodecontent(struct skin* node)
1233{
1234        if(node->pluginhandle != NULL)
1235                dlclose(node->pluginhandle);
1236
1237        free(node->name);
1238        node->name = NULL;
1239
1240        free(node->ret);
1241        node->ret = NULL;
1242
1243        free(node->input);
1244        node->input = NULL;
1245
1246        free(node->mask);
1247        node->mask = NULL;
1248
1249        free(node->parent);
1250        node->parent = NULL;
1251
1252        free(node->text);
1253        node->text = NULL;
1254
1255        free(node->text2);
1256        node->text2 = NULL;
1257
1258        free(node->font);
1259        node->font = NULL;
1260
1261        free(node->selectpic);
1262        node->selectpic = NULL;
1263
1264        free(node->pic);
1265        node->pic = NULL;
1266
1267        free(node->title);
1268        node->title = NULL;
1269
1270        free(node->param1);
1271        node->param1 = NULL;
1272
1273        free(node->param2);
1274        node->param2 = NULL;
1275
1276        freeepgrecord(&node->epgrecord);
1277        node->epgrecord = NULL;
1278
1279        free(node->choiceboxvalue);
1280        node->choiceboxvalue = NULL;
1281
1282        free(node->filelist);
1283        node->filelist = NULL;
1284
1285        node->handle = NULL;
1286        node->handle1 = NULL;
1287        node->pluginhandle = NULL;
1288}
1289
1290void delmarkedscreennodes(struct skin* node, int mark)
1291{
1292        struct skin *prev = NULL, *screen = node;
1293        struct skin* sel = NULL, *tmp = NULL;
1294
1295        if(node != NULL)
1296        {
1297                node = node->child;
1298                prev = node;
1299        }
1300
1301        while(node != NULL)
1302        {
1303                if(node->select != NULL)
1304                {
1305                        tmp = node->select;
1306                        sel = node;
1307                }
1308
1309                if(node->del == mark)
1310                {
1311                        if(node == screen->child)
1312                        {
1313                                screen->child = node->next;
1314                                prev = node->next;
1315
1316                                if(screen->child != NULL)
1317                                        screen->child->prev = NULL;
1318
1319                                if(node == tmp)
1320                                {
1321                                        sel->select = NULL;
1322                                        tmp = NULL;
1323                                        sel = NULL;
1324                                }
1325
1326                                freenodecontent(node);
1327
1328                                free(node);
1329                                node = prev;
1330                                continue;
1331                        }
1332                        else
1333                        {
1334                                prev->next = node->next;
1335
1336                                if(prev->next != NULL)
1337                                        prev->next->prev = prev;
1338
1339                                if(node == tmp)
1340                                {
1341                                        sel->select = NULL;
1342                                        tmp = NULL;
1343                                        sel = NULL;
1344                                }
1345
1346                                freenodecontent(node);
1347
1348
1349                                freenodecontent(node);
1350                                free(node);
1351                                node = prev->next;
1352                                continue;
1353                        }
1354                }
1355
1356                prev = node;
1357                node = node->next;
1358        }
1359}
1360
1361void delscreennode(struct skin *node, char* nodename)
1362{
1363        struct skin *prev = NULL;
1364        struct skin **nodeaddr;
1365
1366        if(node == NULL || node == status.skinerr)
1367                return;
1368
1369        if(node == skin && node->child == NULL)
1370                nodeaddr=&skin;
1371        else
1372        {
1373                nodeaddr=&node->child;
1374                node = node->child;
1375        }
1376
1377        while(node != NULL && ostrcmp(node->name, nodename) != 0)
1378        {
1379                prev = node;
1380                node = node->next;
1381        }
1382
1383        if(prev == NULL)
1384        {
1385                *nodeaddr = node->next;
1386                if(*nodeaddr != NULL)
1387                        ((struct skin*)*nodeaddr)->prev = NULL;
1388        }
1389        else if(node != NULL)
1390        {
1391                prev->next = node->next;
1392                if(node->next != NULL)
1393                        node->next->prev = prev;
1394        }
1395
1396        if(node != NULL)
1397        {
1398                freenodecontent(node);
1399                free(node);
1400                node = NULL;
1401        }
1402}
1403
1404void delscreennodebyname(char *screenname, char* nodename)
1405{
1406        struct skin *node = NULL;
1407
1408        if(strlen(screenname) == 0)
1409                node = skin;
1410        else
1411                node = getscreen(screenname);
1412
1413        delscreennode(node, nodename);
1414}
1415
1416void delscreen(struct skin *node)
1417{
1418        struct skin *prev = NULL, *child = NULL;
1419
1420        if(node != NULL && node != status.skinerr)
1421                child = node->child;
1422
1423        while(child != NULL)
1424        {
1425                prev = child;
1426                child = child->next;
1427                if(prev != NULL)
1428                        delscreennode(node, prev->name);
1429        }
1430
1431        if(node != NULL)
1432                delscreennode(skin, node->name);
1433}
1434
1435void delscreenbyname(char *screenname)
1436{
1437        struct skin *node = NULL;
1438        node = getscreen(screenname);
1439        delscreen(node);
1440}
1441
1442void delmarkedscreen(int del)
1443{
1444        struct skin *node = skin, *prev = skin;
1445
1446        while(node != NULL)
1447        {
1448                prev = node;
1449                node = node->next;
1450                if(prev != NULL && prev->del == del)
1451                        delscreen(prev);
1452        }
1453}
1454
1455void freescreen()
1456{
1457        struct skin *node = skin, *prev = skin;
1458
1459        while(node != NULL)
1460        {
1461                prev = node;
1462                node = node->next;
1463                if(prev != NULL)
1464                        delscreen(prev);
1465        }
1466}
1467
1468inline unsigned long getpixelbuf(char* buf, int posx, int posy, int bufwidth)
1469{
1470        unsigned long *tmpbuf = (unsigned long*)buf;
1471        if(buf == NULL) return 0;
1472
1473        return tmpbuf[(bufwidth * posy) + posx];
1474}
1475
1476inline unsigned long getpixelfast(int posx, int posy)
1477{
1478        return skinfb->fblong[posy + posx];
1479}
1480
1481inline unsigned long getpixel(int posx, int posy)
1482{
1483        return skinfb->fblong[(skinfb->width * posy) + posx];
1484}
1485
1486inline void drawpixelfast(int posx, int posy, unsigned long color)
1487{
1488        skinfb->fblong[posy + posx] = color;
1489}
1490
1491inline void drawpixel(int posx, int posy, unsigned long color)
1492{
1493        skinfb->fblong[(skinfb->width * posy) + posx] = color;
1494}
1495
1496inline void drawpixelfastfb(struct fb* node, int posx, int posy, unsigned long color)
1497{
1498        node->fblong[posy + posx] = color;
1499}
1500
1501inline void drawpixelfb(struct fb* node, int posx, int posy, unsigned long color)
1502{
1503        node->fblong[(node->width * posy) + posx] = color;
1504}
1505
1506unsigned char* scale(unsigned char* buf, int width, int height, int channels, int newwidth, int newheight, int free1)
1507{
1508        int h, w, pixel, nmatch;
1509
1510        if(buf == NULL)
1511        {
1512                err("out -> NULL detect");
1513                return NULL;
1514        }
1515
1516        unsigned char *newbuf = malloc(newwidth * newheight * channels);
1517        if(newbuf == NULL)
1518        {
1519                err("no mem");
1520                return NULL;
1521        }
1522
1523        double scalewidth = (double)newwidth / (double)width;
1524        double scaleheight = (double)newheight / (double)height;
1525
1526        for(h = 0; h < newheight; h++)
1527        {
1528                for(w = 0; w < newwidth; w++)
1529                {
1530                        pixel = (h * (newwidth * channels)) + (w * channels);
1531                        nmatch = (((int)(h / scaleheight) * (width * channels)) + ((int)(w / scalewidth) * channels));
1532                        if(channels > 0)
1533                                newbuf[pixel] = buf[nmatch];
1534                        if(channels > 1)
1535                                newbuf[pixel + 1] = buf[nmatch + 1];
1536                        if(channels > 2)
1537                                newbuf[pixel + 2] = buf[nmatch + 2];
1538                        if(channels > 3)
1539                                newbuf[pixel + 3] = buf[nmatch + 3];
1540                }
1541        }
1542
1543        if(free1 == 1) free(buf);
1544        return newbuf;
1545}
1546
1547struct jpgerror
1548{
1549        struct jpeg_error_mgr jerr;
1550        jmp_buf setjmpbuf;
1551};
1552
1553void jpgswerror(j_common_ptr cinfo)
1554{
1555        struct jpgerror* jpgerr = (struct jpgerror*)cinfo->err;
1556        (*cinfo->err->output_message) (cinfo);
1557        longjmp(jpgerr->setjmpbuf, 1);
1558}
1559
1560void calcautoscale(int width, int height, int mwidth, int mheight, int* scalewidth, int* scaleheight)
1561{
1562        float srcRatio = (float)width / (float)height;
1563        float dstRatio = (float)mwidth / (float)mheight;
1564
1565        if(dstRatio > srcRatio)
1566        {
1567                *scaleheight = mheight;
1568                *scalewidth = (mheight * srcRatio) + 0.5;
1569        }
1570        else
1571        {
1572                *scalewidth = mwidth;
1573                *scaleheight = (mwidth / srcRatio) + 0.5;
1574        }
1575}
1576
1577unsigned char *loadjpg(char *filename, unsigned long *width, unsigned long *height, unsigned long *rowbytes, int *channels, int denom)
1578{
1579        struct jpeg_decompress_struct cinfo;
1580        struct jpeg_decompress_struct *ciptr = &cinfo;
1581        struct jpgerror jerr;
1582        FILE *fd = NULL;
1583        unsigned char *buf = NULL;
1584
1585        fd = fopen(filename, "rb");
1586        if(fd == NULL)
1587        {
1588                perr("open jpg file %s", filename);
1589                return NULL;
1590        }
1591
1592        ciptr->err = jpeg_std_error(&jerr.jerr);
1593        jerr.jerr.error_exit = jpgswerror;
1594        if(setjmp(jerr.setjmpbuf))
1595        {
1596                jpeg_destroy_decompress(ciptr);
1597                fclose(fd);
1598                return NULL;
1599        }
1600
1601        jpeg_create_decompress(ciptr);
1602        jpeg_stdio_src(ciptr, fd);
1603        jpeg_read_header(ciptr, TRUE);
1604        ciptr->out_color_space = JCS_RGB;
1605
1606        //faster but less quality
1607        ciptr->dct_method = JDCT_IFAST;
1608        ciptr->do_fancy_upsampling = FALSE;
1609        ciptr->two_pass_quantize = FALSE;
1610        ciptr->dither_mode = JDITHER_ORDERED;
1611
1612        if(denom < 1) denom = 1;
1613        if(denom > 16) denom = 16;
1614        ciptr->scale_num = 1;
1615        ciptr->scale_denom = denom;
1616
1617        jpeg_start_decompress(ciptr);
1618
1619        *width = ciptr->output_width;
1620        *height = ciptr->output_height;
1621        *channels = ciptr->output_components;
1622        *rowbytes = ciptr->output_width * ciptr->output_components;
1623
1624        if(ciptr->output_components == 3)
1625        {
1626                JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
1627                buf = malloc(ciptr->output_height * ciptr->output_width * ciptr->output_components);
1628                if(buf == NULL)
1629                {
1630                        err("no mem");
1631                        jpeg_destroy_decompress(ciptr);
1632                        fclose(fd);
1633                        return NULL;
1634                }
1635
1636                unsigned char *bp = buf;
1637
1638                while(ciptr->output_scanline < ciptr->output_height)
1639                {
1640                        jpeg_read_scanlines(ciptr, &lb, 1);
1641                        memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
1642                        bp += ciptr->output_width * ciptr->output_components;
1643                }
1644        }
1645
1646        jpeg_finish_decompress(ciptr);
1647        jpeg_destroy_decompress(ciptr);
1648        fclose(fd);
1649        return(buf);
1650}
1651
1652unsigned char* savejpg(char* filename, int width, int height, int channels, int newwidth, int newheight, int quality, unsigned char *buf)
1653{
1654        struct jpeg_compress_struct cinfo;
1655        struct jpeg_error_mgr jerr;
1656        FILE* outfile = NULL;
1657        JSAMPROW pointer[1];
1658        int stride;
1659
1660        if(buf == NULL) return buf;
1661
1662        if((outfile = fopen(filename, "wb")) == NULL)
1663        {
1664                perr("jpeg can't open %s", filename);
1665                return buf;
1666        }
1667
1668        if(width != newwidth || height != newheight)
1669        {
1670                buf = scale(buf, width, height, channels, newwidth, newheight, 1);
1671                if(buf == NULL)
1672                {
1673                        fclose(outfile);
1674                        return buf;
1675                }
1676        }
1677
1678        cinfo.err = jpeg_std_error(&jerr);
1679        jpeg_create_compress(&cinfo);
1680        jpeg_stdio_dest(&cinfo, outfile);
1681
1682        cinfo.image_width = newwidth;
1683        cinfo.image_height = newheight;
1684        cinfo.input_components = channels;
1685        cinfo.in_color_space = JCS_RGB;
1686        jpeg_set_defaults(&cinfo);
1687        jpeg_set_quality(&cinfo, quality, TRUE);
1688        jpeg_start_compress(&cinfo, TRUE);
1689        stride = newwidth * channels;
1690
1691        while(cinfo.next_scanline < cinfo.image_height)
1692        {
1693                pointer[0] = &buf[cinfo.next_scanline * stride];
1694                jpeg_write_scanlines(&cinfo, pointer, 1);
1695        }
1696
1697        jpeg_finish_compress(&cinfo);
1698        fclose(outfile);
1699        jpeg_destroy_compress(&cinfo);
1700        return buf;
1701}
1702
1703int drawjpgsw(struct jpeg_decompress_struct* cinfo, unsigned char* buf, int posx, int posy, int width, int height, int colbytes, int mwidth, int mheight, int scalewidth, int scaleheight, int halign, int valign)
1704{
1705        int aktline = 0, x = 0, py = 0, px = 0, row_stride = 0, pyw = 0;
1706        int width4 = width * 4, width8 = width * 8, aktline1 = 0;
1707        unsigned char red, green, blue;
1708        unsigned long color = 0;
1709        JSAMPARRAY buffer = NULL;
1710        unsigned char *tmpbuf = NULL;
1711        unsigned char *scalebuf = NULL;
1712
1713        if(cinfo == NULL && buf == NULL) return 1;
1714
1715        if(cinfo != NULL)
1716        {
1717                row_stride = cinfo->output_width * cinfo->output_components;
1718                buffer = (cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);
1719        }
1720        else
1721                row_stride = width * colbytes;
1722
1723#ifdef MIPSEL
1724        if(accelfb != NULL && accelfb->varfbsize > width8 && (scalewidth != 0 || scaleheight != 0) && (scalewidth != width || scaleheight != height))
1725#else
1726        if(merkskinfb == NULL && accelfb != NULL && accelfb->varfbsize > width8 && (scalewidth != 0 || scaleheight != 0) && (scalewidth != width || scaleheight != height))
1727#endif
1728        {
1729                if(halign == CENTER)
1730                        posx += (mwidth >> 1) - (scalewidth >> 1);
1731                else if(halign == RIGHT)
1732                        posx += mwidth - scalewidth;
1733                if(valign == MIDDLE)
1734                        posy += (mheight >> 1) - (scaleheight >> 1);
1735                else if(valign == BOTTOM)
1736                        posy += mheight - scaleheight;
1737
1738                int nposy = posy;
1739                py = -1;
1740
1741                m_lock(&status.accelfbmutex, 16);
1742                if(cinfo != NULL) aktline = cinfo->output_scanline;
1743
1744                if(cinfo != NULL)
1745                {
1746                        while(aktline < height)
1747                        {
1748                                jpeg_read_scanlines(cinfo, buffer, 1);
1749                                aktline = cinfo->output_scanline;
1750
1751                                py++;
1752                                pyw = width * py;
1753                                for(x = 0; x < width; x++)
1754                                {
1755                                        px = colbytes * x;
1756                                        red = buffer[0][px];
1757                                        if(colbytes > 2)
1758                                        {
1759                                                green = buffer[0][px + 1];
1760                                                blue = buffer[0][px + 2];
1761                                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1762                                        }
1763                                        else
1764                                                color = (255 << 24) | (red << 16) | (red << 8) | red;
1765
1766                                        drawpixelfb(accelfb, pyw + x, 0, color);
1767                                }
1768
1769                                if((py * width4) + (width8) >= accelfb->varfbsize)
1770                                {
1771                                        py++;
1772                                        if(scaleheight > 0)
1773                                        {
1774                                                float tmp = (float)height / (float)scaleheight;
1775                                                if(tmp > 0)
1776                                                {
1777                                                        tmp = (float)py / tmp;
1778                                                        blitscale(posx, nposy, width, py, scalewidth, (int)(tmp + 0.5), 0);
1779                                                        nposy += (int)(tmp + 0.5);
1780                                                }
1781                                        }
1782                                        py = -1;
1783                                }
1784                        }
1785                }
1786                else
1787                {
1788                        while(aktline < height)
1789                        {
1790                                aktline1 = aktline * row_stride;
1791                                aktline++;
1792
1793                                py++;
1794                                pyw = width * py;
1795                                for(x = 0; x < width; x++)
1796                                {
1797                                        px = colbytes * x;
1798                                        red = buf[aktline1 + px];
1799                                        if(colbytes > 2)
1800                                        {
1801                                                green = buf[aktline1 + (px + 1)];
1802                                                blue = buf[aktline1 + (px + 2)];
1803                                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1804                                        }
1805                                        else
1806                                                color = (255 << 24) | (red << 16) | (red << 8) | red;
1807
1808                                        drawpixelfb(accelfb, pyw + x, 0, color);
1809                                }
1810
1811                                if((py * width4) + (width8) >= accelfb->varfbsize)
1812                                {
1813                                        py++;
1814                                        if(scaleheight > 0)
1815                                        {
1816                                                float tmp = (float)height / (float)scaleheight;
1817                                                if(tmp > 0)
1818                                                {
1819                                                        tmp = (float)py / tmp;
1820                                                        blitscale(posx, nposy, width, py, scalewidth, (int)(tmp + 0.5), 0);
1821                                                        nposy += (int)(tmp + 0.5);
1822                                                }
1823                                        }
1824                                        py = -1;
1825                                }
1826                        }
1827                }
1828
1829                //blit the rest
1830                if(py > -1 && scaleheight > 0)
1831                {
1832                        int tmp = scaleheight - (nposy - posy);
1833                        blitscale(posx, nposy, width, py, scalewidth, tmp, 0);
1834                }
1835                m_unlock(&status.accelfbmutex, 16);
1836        }
1837        else if((scalewidth != 0 || scaleheight != 0) && (scalewidth != width || scaleheight != height) && cinfo != NULL)
1838        {
1839                if(halign == CENTER)
1840                        posx += (mwidth >> 1) - (scalewidth >> 1);
1841                else if(halign == RIGHT)
1842                        posx += mwidth - scalewidth;
1843                if(valign == MIDDLE)
1844                        posy += (mheight >> 1) - (scaleheight >> 1);
1845                else if(valign == BOTTOM)
1846                        posy += mheight - scaleheight;
1847
1848                int i = 0;
1849                int location = 0;
1850                tmpbuf = (unsigned char*)malloc(width*height*3);
1851                aktline = cinfo->output_scanline;
1852                while(aktline < height)
1853                {
1854                        jpeg_read_scanlines(cinfo, buffer, 1);
1855                        aktline = cinfo->output_scanline;
1856                        for(i=0; i<width*3; i++)
1857                                tmpbuf[location++] = buffer[0][i];
1858                }
1859                //extendet_scale wegen schreibfehler in alter config
1860                if(getconfigint("extended_scale", NULL) == 1 || getconfigint("extendet_scale", NULL) == 1)
1861                        scalebuf = resize(tmpbuf, width, height, scalewidth, scaleheight, 2, NULL, 1);
1862                else
1863                        scalebuf = resize(tmpbuf, width, height, scalewidth, scaleheight, 1, NULL, 1);
1864
1865                aktline = 0;
1866                while(aktline < scaleheight)
1867                {
1868                        py = (posy + aktline) * skinfb->width;
1869                        aktline1 = aktline * scalewidth * colbytes;
1870                        for(x = 0; x < scalewidth; x++)
1871                        {
1872                                px = colbytes * x;
1873                                red = scalebuf[px + aktline1];
1874
1875                                if(colbytes > 2)
1876                                {
1877                                        green = scalebuf[aktline1 + (px + 1)];
1878                                        blue = scalebuf[aktline1 + (px + 2)];
1879                                        color = (255 << 24) | (red << 16) | (green << 8) | blue;
1880                                }
1881                                else
1882                                        color = (255 << 24) | (red << 16) | (red << 8) | red;
1883
1884                                drawpixelfast(posx + x, py, color);
1885                        }
1886                        aktline++;
1887                }
1888                free(scalebuf);
1889        }
1890        else
1891        {
1892                if(width > mwidth) width = mwidth;
1893                if(height > mheight) height = mheight;
1894
1895                if(halign == CENTER)
1896                        posx += (mwidth >> 1) - (width >> 1);
1897                else if(halign == RIGHT)
1898                        posx += mwidth - width;
1899                if(valign == MIDDLE)
1900                        posy += (mheight >> 1) - (height >> 1);
1901                else if(valign == BOTTOM)
1902                        posy += mheight - height;
1903
1904                if(cinfo != NULL) aktline = cinfo->output_scanline;
1905                while(aktline < height)
1906                {
1907                        if(cinfo != NULL)
1908                        {
1909                                jpeg_read_scanlines(cinfo, buffer, 1);
1910                                aktline = cinfo->output_scanline;
1911                        }
1912                        else
1913                                aktline++;
1914
1915                        aktline1 = (aktline - 1) * row_stride;
1916
1917                        py = (posy + aktline - 1) * skinfb->width;
1918                        for(x = 0; x < width; x++)
1919                        {
1920                                px = colbytes * x;
1921
1922                                if(cinfo != NULL)
1923                                        red = buffer[0][px];
1924                                else
1925                                        red = buf[aktline1 + px];
1926
1927                                if(colbytes > 2)
1928                                {
1929                                        if(cinfo != NULL)
1930                                        {
1931                                                green = buffer[0][px + 1];
1932                                                blue = buffer[0][px + 2];
1933                                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1934                                        }
1935                                        else
1936                                        {
1937                                                green = buf[aktline1 + (px + 1)];
1938                                                blue = buf[aktline1 + (px + 2)];
1939                                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1940                                        }
1941                                }
1942                                else
1943                                        color = (255 << 24) | (red << 16) | (red << 8) | red;
1944
1945                                drawpixelfast(posx + x, py, color);
1946                        }
1947                }
1948        }
1949
1950        return 0;
1951}
1952
1953int readjpgsw(const char* filename, int posx, int posy, int mwidth, int mheight, int scalewidth, int scaleheight, int halign, int valign, int quality)
1954{
1955        struct jpeg_decompress_struct cinfo;
1956        struct jpgerror jerr;
1957        FILE* fd = NULL;
1958        int width = 0, height = 0;
1959
1960        fd = fopen(filename, "rb");
1961        if(fd == NULL)
1962        {
1963                perr("open jpg file %s", filename);
1964                return 1;
1965        }
1966
1967        cinfo.err = jpeg_std_error(&jerr.jerr);
1968        jerr.jerr.error_exit = jpgswerror;
1969        if(setjmp(jerr.setjmpbuf))
1970        {
1971                jpeg_destroy_decompress(&cinfo);
1972                fclose(fd);
1973                return 1;
1974        }
1975
1976        jpeg_create_decompress(&cinfo);
1977        jpeg_stdio_src(&cinfo, fd);
1978        jpeg_read_header(&cinfo, TRUE);
1979
1980        cinfo.out_color_space = JCS_RGB;
1981
1982        if(quality == 0)
1983        {
1984                cinfo.dct_method = JDCT_IFAST;
1985                cinfo.do_fancy_upsampling = FALSE;
1986                cinfo.two_pass_quantize = FALSE;
1987                cinfo.dither_mode = JDITHER_ORDERED;
1988        }
1989
1990        cinfo.scale_num = 1;
1991        cinfo.scale_denom = 1;
1992
1993        width = cinfo.image_width;
1994        height = cinfo.image_height;
1995
1996        if(scalewidth != 0 || scaleheight != 0)
1997        {
1998                //auto scale to mwidth / mheight
1999                if(scalewidth == 1 && scaleheight == 1)
2000                        calcautoscale(width, height, mwidth, mheight, &scalewidth, &scaleheight);
2001                else if(scalewidth == 2 && scaleheight == 2)
2002                        calcautoscale(width, height, mwidth, mheight - 25, &scalewidth, &scaleheight);
2003
2004                if(scalewidth == 0) scalewidth = width;
2005                if(scaleheight == 0) scaleheight = height;
2006                if(scalewidth > mwidth) scalewidth = mwidth;
2007                if(scaleheight > mheight) scaleheight = mheight;
2008
2009                if(quality == 0 || quality == 1)
2010                {
2011                        int tmpwidth = width;
2012                        int tmpheight = height;
2013                        while(scalewidth < tmpwidth || scaleheight < tmpheight)
2014                        {
2015                                tmpwidth /= 2; tmpheight /= 2; cinfo.scale_denom *= 2;
2016                                if(cinfo.scale_denom > 8) break;
2017                        }
2018                }
2019        }
2020
2021        jpeg_start_decompress(&cinfo);
2022        width = cinfo.output_width;
2023        height = cinfo.output_height;
2024
2025        drawjpgsw(&cinfo, NULL, posx, posy, width, height, cinfo.output_components, mwidth, mheight, scalewidth, scaleheight, halign, valign);
2026
2027        jpeg_finish_decompress(&cinfo);
2028        jpeg_destroy_decompress(&cinfo);
2029        fclose(fd);
2030        return 0;
2031}
2032
2033unsigned char* readpng(const char* filename, unsigned long* width, unsigned long* height, unsigned long* rowbytes, int* channels, int posx, int posy, int mwidth, int mheight, int halign, int valign)
2034{
2035        FILE *fd = NULL;
2036        int ret, bit_depth, color_type;
2037        unsigned char *buf = NULL;
2038        static png_structp png_ptr = NULL;
2039        static png_infop info_ptr = NULL;
2040        double gamma;
2041        png_uint_32 y;
2042        png_bytepp row_pointers = NULL;
2043        png_bytep sig = NULL;
2044
2045        fd = fopen(filename, "rb");
2046        if(fd == NULL)
2047        {
2048                perr("open png file %s", filename);
2049                return NULL;
2050        }
2051
2052        sig = malloc(8);
2053        if(sig == NULL)
2054        {
2055                err("no memory");
2056                fclose(fd);
2057                return NULL;
2058        }
2059
2060        fread(sig, 1, 8, fd);
2061        ret = png_check_sig(sig, 8);
2062        if(ret == 0)
2063        {
2064                err("%s is not a PNG file", filename);
2065                free(sig);
2066                fclose(fd);
2067                return NULL;
2068        }
2069
2070        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
2071        if(png_ptr == NULL)
2072        {
2073                err("%s no memory", filename);
2074                free(sig);
2075                fclose(fd);
2076                return NULL;
2077        }
2078
2079        info_ptr = png_create_info_struct(png_ptr);
2080        if(info_ptr == NULL)
2081        {
2082                png_destroy_read_struct(&png_ptr, NULL, NULL);
2083                err("%s no memory", filename);
2084                free(sig);
2085                fclose(fd);
2086                return NULL;
2087        }
2088
2089        if(png_jmpbuf(png_ptr) == NULL)
2090        {
2091                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2092                err("%s unknown error (png_jmpbuf = NULL)", filename);
2093                free(sig);
2094                fclose(fd);
2095                return NULL;
2096        }
2097
2098        ret = setjmp(png_jmpbuf(png_ptr));
2099        if(ret != 0)
2100        {
2101                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2102                err("%s unknown error (libpng longjmp)", filename);
2103                free(sig);
2104                fclose(fd);
2105                return NULL;
2106        }
2107
2108        png_init_io(png_ptr, fd);
2109        png_set_sig_bytes(png_ptr, 8);
2110        png_read_info(png_ptr, info_ptr);
2111        png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)width, (png_uint_32*)height, &bit_depth, &color_type, NULL, NULL, NULL);
2112
2113        if(color_type == PNG_COLOR_TYPE_PALETTE)
2114                png_set_expand(png_ptr);
2115        if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
2116                png_set_expand(png_ptr);
2117        if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
2118                png_set_expand(png_ptr);
2119        if(bit_depth == 16)
2120                png_set_strip_16(png_ptr);
2121        if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2122                png_set_gray_to_rgb(png_ptr);
2123        if(png_get_gAMA(png_ptr, info_ptr, &gamma))
2124                png_set_gamma(png_ptr, 2.2, gamma);
2125
2126        png_read_update_info(png_ptr, info_ptr);
2127        *rowbytes = png_get_rowbytes(png_ptr, info_ptr);
2128        *channels = (int)png_get_channels(png_ptr, info_ptr);
2129
2130        buf = malloc((*rowbytes) * (*height));
2131        if(buf == NULL)
2132        {
2133                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2134                err("%s no memory", filename);
2135                free(sig);
2136                fclose(fd);
2137                return NULL;
2138        }
2139
2140        row_pointers = (png_bytepp)malloc((*height) * sizeof(png_bytep));
2141        if(row_pointers == NULL)
2142        {
2143                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2144                err("%s unknown error", filename);
2145                free(sig);
2146                fclose(fd);
2147                return NULL;
2148        }
2149
2150        for (y = 0; y < (*height); ++y)
2151                row_pointers[y] = (png_bytep)buf + y * (*rowbytes);
2152
2153        png_read_image(png_ptr, row_pointers);
2154        free(row_pointers);
2155        row_pointers = NULL;
2156
2157        png_read_end(png_ptr, NULL);
2158        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2159
2160        free(sig);
2161        fclose(fd);
2162
2163        debug(100, "png width=%ld height=%ld channels=%d rowbytes=%ld", *width, *height, *channels, *rowbytes);
2164
2165        return buf;
2166}
2167
2168void drawpic(const char* filename, int posx, int posy, int scalewidth, int scaleheight, int mwidth, int mheight, int halign, int valign, int transparent, int quality, int add)
2169{
2170        unsigned char *buf = NULL, *scalebuf = NULL;
2171        int memfd = -1, py = 0, pyh = 0, pxw = 0, diff = 0;
2172        unsigned long width, height, rowbytes;
2173        int channels, length;
2174        unsigned char *src;
2175        png_uint_32 y, x;
2176        struct pic* picnode = NULL;
2177        int decoding = getconfigint("pichwdecode", NULL);
2178        int pictype = 0; //0 = png, 1 = jpg HW, 2 = jpg SW
2179        unsigned char r = 0, g = 0, b = 0, ralpha = 0;
2180
2181        if(filename == NULL) return;
2182
2183        length = strlen(filename);
2184        if(filename[length - 1] == 'g' && filename[length - 2] == 'n' && filename[length - 3] == 'p')
2185                pictype = 0;
2186        else if(decoding == 1)
2187                pictype = 1;
2188        else
2189                pictype = 2;
2190
2191        picnode = getpic((char*)filename);
2192        if(picnode == NULL)
2193        {
2194                if(pictype == 0)
2195                        buf = readpng(filename, &width, &height, &rowbytes, &channels, 0, 0, 0, 0, 0, 0);
2196                else if(pictype == 1)
2197                        readjpg(filename, &width, &height, &rowbytes, &channels, &buf, &memfd);
2198                else if(pictype == 2 && add == 0)
2199                        readjpgsw(filename, posx, posy, mwidth, mheight, scalewidth, scaleheight, halign, valign, quality);
2200                else if(pictype == 2 && add == 1)
2201                        buf = loadjpg((char*)filename, &width, &height, &rowbytes, &channels, 1);
2202                if(add == 1)
2203                        picnode = addpic((char*)filename, buf, memfd, width, height, rowbytes, channels, 0, 0, NULL);
2204        }
2205        else
2206        {
2207                buf = picnode->picbuf;
2208                width = picnode->width;
2209                height = picnode->height;
2210                rowbytes = picnode->rowbytes;
2211                channels = picnode->channels;
2212                memfd = picnode->memfd;
2213        }
2214
2215        if(buf == NULL) return;
2216
2217        if(pictype == 0 && (scalewidth != 0 || scaleheight != 0) && (scalewidth != width || scaleheight != height))
2218        {
2219                //auto scale to mwidth / mheight
2220                if(scalewidth == 1 && scaleheight == 1)
2221                        calcautoscale(width, height, mwidth, mheight, &scalewidth, &scaleheight);
2222                else if(scalewidth == 2 && scaleheight == 2)
2223                        calcautoscale(width, height, mwidth, mheight - 25, &scalewidth, &scaleheight);
2224
2225                if(scalewidth == 0) scalewidth = width;
2226                if(scaleheight == 0) scaleheight = height;
2227                if(picnode == NULL)
2228                        scalebuf = scale(buf, rowbytes / channels, height, channels, scalewidth, scaleheight, 1);
2229                else
2230                {
2231                        scalebuf = scale(buf, rowbytes / channels, height, channels, scalewidth, scaleheight, 0);
2232                        buf = NULL;
2233                        picnode = NULL;
2234                }
2235                if(scalebuf != NULL)
2236                {
2237                        buf = scalebuf;
2238                        width = scalewidth;
2239                        height = scaleheight;
2240                        rowbytes = scalewidth * (channels);
2241                }
2242        }
2243
2244        if(pictype == 0)
2245        {
2246                if(width > mwidth) width = mwidth;
2247                if(height > mheight) height = mheight;
2248
2249                if(halign == CENTER)
2250                        posx += (mwidth >> 1) - (width >> 1);
2251                else if(halign == RIGHT)
2252                        posx += mwidth - width;
2253                if(valign == MIDDLE)
2254                        posy += (mheight >> 1) - (height >> 1);
2255                else if(valign == BOTTOM)
2256                        posy += mheight - height;
2257
2258                py = (posy * skinfb->width) + posx;
2259                pyh = py + (height * skinfb->width);
2260                src = buf;
2261                diff = rowbytes - (width * channels);
2262
2263                if(channels == 3)
2264                {
2265                        for(y = py; y < pyh; y += skinfb->width)
2266                        {
2267                                pxw = y + width;
2268                                for(x = y; x < pxw; x++)
2269                                {
2270                                        skinfb->fblong[x] = (255 << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
2271                                        src += 3;
2272                                }
2273                                src += diff;
2274                        }
2275                }
2276                else
2277                {
2278                        for(y = py; y < pyh; y += skinfb->width)
2279                        {
2280                                pxw = y + width;
2281
2282                                if(transparent == 1)
2283                                {
2284                                        for(x = y; x < pxw; x++)
2285                                        {
2286                                                if(src[3] < 10)
2287                                                {
2288                                                        src += 4;
2289                                                        continue;
2290                                                }
2291                                                skinfb->fblong[x] = (src[3] << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
2292                                                src += 4;
2293                                        }
2294                                }
2295                                else
2296                                {
2297                                        for(x = y; x < pxw; x++)
2298                                        {
2299                                                //renderquality 255-0 = best
2300                                                if(src[3] > 200)
2301                                                        skinfb->fblong[x] = (255 << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
2302                                                else if(src[3] < 50)
2303                                                {
2304                                                        src += 4;
2305                                                        continue;
2306                                                }
2307                                                else
2308                                                {
2309                                                        ralpha = 255 - src[3];
2310                                                        alpha_composite(r, src[0], src[3], ralpha, (skinfb->fblong[x] & 0xff0000) >> 16);
2311                                                        alpha_composite(g, src[1], src[3], ralpha, (skinfb->fblong[x] & 0x00ff00) >> 8);
2312                                                        alpha_composite(b, src[2], src[3], ralpha, skinfb->fblong[x] & 0xff);
2313                                                        skinfb->fblong[x] = (255 << 24) | r << 16 | g << 8 | b;
2314                                                }
2315                                                src += 4;
2316                                        }
2317                                }
2318                                src += diff;
2319                        }
2320                }
2321        }
2322        else if(pictype == 1 && memfd > -1)
2323                blitjpg(buf, posx, posy, width, height, scalewidth, scaleheight, mwidth, mheight, halign, valign);
2324        else if(pictype == 2 && picnode != NULL)
2325                drawjpgsw(NULL, buf, posx, posy, width, height, rowbytes / width, mwidth, mheight, scalewidth, scaleheight, halign, valign);
2326
2327        if(picnode == NULL)
2328        {
2329                if(pictype == 0)
2330                        free(buf);
2331                else if(pictype == 1)
2332                        freebpamem(memfd, buf, width * height * 3);
2333        }
2334}
2335
2336//flag 0: don't del outside
2337//flag 1: del outside
2338void drawcircle(int x0, int y0, int radius, int startangle, int endangle, long color, int transparent, char* bg, int flag)
2339{
2340        float d = (5/4.0) - radius, theta;
2341        int x = 0, y = radius, px = 0, py = 0;
2342
2343        transparent = (transparent - 255) * -1;
2344        unsigned long tmpcol = color | ((transparent & 0xff) << 24);
2345
2346        while(y > x)
2347        {
2348                if(d < 0)
2349                        d += 2 * x + 3;
2350                else
2351                {
2352                        d += (2 * x) - (2 * y) + 5;
2353                        y--;
2354                }
2355                x++;
2356
2357                theta = (atan((float)y / x)) * (180 / 3.14);
2358
2359                //rt2
2360                if(theta >= startangle && theta <= endangle)
2361                {
2362                        px = x0 + x;
2363                        py = (y0 - y) * skinfb->width;
2364                        drawpixelfast(px, py, tmpcol);
2365                        if(flag == 1)
2366                        {
2367                                int i = radius - x;
2368                                int r = radius - y;
2369                                for(; i > 0; i--)
2370                                        drawpixelfast(px + i, py, getpixelbuf(bg, x + i - 1, r, radius));
2371                        }
2372                }
2373                //rb2
2374                if(360 - theta >= startangle && 360 - theta <= endangle)
2375                {
2376                        px = x0 + x;
2377                        py = (y0 + y) * skinfb->width;
2378                        drawpixelfast(px, py, tmpcol);
2379                        if(flag == 1)
2380                        {
2381                                int i = radius - x;
2382                                int r = y - 1;
2383                                for(; i > 0; i--)
2384                                        drawpixelfast(px + i, py, getpixelbuf(bg, x + i - 1, r, radius));
2385                        }
2386                }
2387                //rt1
2388                if(90 - theta >= startangle && 90 - theta <= endangle)
2389                {
2390                        px = x0 + y;
2391                        py = (y0 - x) * skinfb->width;
2392                        drawpixelfast(px, py, tmpcol);
2393                        if(flag == 1)
2394                        {
2395                                int i = radius - y;
2396                                int r = radius - x;
2397                                for(; i > 0; i--)
2398                                        drawpixelfast(px + i, py, getpixelbuf(bg, y + i - 1, r, radius));
2399                        }
2400                }
2401                //rb1
2402                if(270 + theta >= startangle && 270 + theta <= endangle)
2403                {
2404                        px = x0 + y;
2405                        py = (y0 + x) * skinfb->width;
2406                        drawpixelfast(px, py, tmpcol);
2407                        if(flag == 1)
2408                        {
2409                                int i = radius - y;
2410                                int r = x - 1;
2411                                for(; i > 0; i--)
2412                                        drawpixelfast(px + i, py, getpixelbuf(bg, y + i - 1, r, radius));
2413                        }
2414                }
2415                //lt2
2416                if(180 - theta >= startangle && 180 - theta <= endangle)
2417                {
2418                        px = x0 - x;
2419                        py = (y0 - y) * skinfb->width;
2420                        drawpixelfast(px, py, tmpcol);
2421                        if(flag == 1)
2422                        {
2423                                int i = radius - x;
2424                                int r = radius - y;
2425                                for(; i > 0; i--)
2426                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - x - i, r, radius));
2427                        }
2428                }
2429                //lb2
2430                if(180 + theta >= startangle && 180 + theta <= endangle)
2431                {
2432                        px = x0 - x;
2433                        py = (y0 + y) * skinfb->width;
2434                        drawpixelfast(px, py, tmpcol);
2435                        if(flag == 1)
2436                        {
2437                                int i = radius - x;
2438                                int r = y - 1;
2439                                for(; i > 0; i--)
2440                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - x - i, r, radius));
2441                        }
2442                }
2443                //lt1
2444                if(90 + theta >= startangle && 90 + theta <= endangle)
2445                {
2446                        px = x0 - y;
2447                        py = (y0 - x) * skinfb->width;
2448                        drawpixelfast(px, py, tmpcol);
2449                        if(flag == 1)
2450                        {
2451                                int i = radius - y;
2452                                int r = radius - x;
2453                                for(; i > 0; i--)
2454                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - y - i, r, radius));
2455                        }
2456                }
2457                //lb1
2458                if(270 - theta >= startangle && 270 - theta <= endangle)
2459                {
2460                        px = x0 - y;
2461                        py = (y0 + x) * skinfb->width;
2462                        drawpixelfast(px, py, tmpcol);
2463                        if(flag == 1)
2464                        {
2465                                int i = radius - y;
2466                                int r = x - 1;
2467                                for(; i > 0; i--)
2468                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - y - i , r, radius));
2469                        }
2470                }
2471        }
2472}
2473
2474int drawchar(struct font* font, FT_ULong currentchar, int posx, int posy, int mwidth, int height, long color, int transparent, int charspace, int test)
2475{
2476        int space = 0, y = 0, x = 0, py = 0, pxw = 0, pyh = 0, max = 220, min = 35;
2477        FT_UInt glyphindex;
2478        FT_Vector kerning;
2479        FT_Error ret;
2480        FTC_SBit sbit;
2481        unsigned long tmpcol = 0;
2482        unsigned char red, green, blue, r, g, b;
2483        unsigned char* src = NULL;
2484        unsigned char ralpha = 0;
2485
2486        if(currentchar == 32) space = 1;
2487
2488        glyphindex = FT_Get_Char_Index(font->face, currentchar);
2489        if(glyphindex == 0)
2490        {
2491                debug(100, "FT_Get_Char_Index for char %x %c failed", (int)currentchar, (int)currentchar);
2492                return 0;
2493        }
2494
2495        FTC_Node anode;
2496        ret = FTC_SBitCache_Lookup(font->cache, &font->desc, glyphindex, &sbit, &anode);
2497        if(ret != 0)
2498        {
2499                err("FTC_SBitCache_Lookup for char %x %c failed. Error: 0x%.2X", (int)currentchar, (int)currentchar, ret);
2500                return 0;
2501        }
2502
2503        if(font->use_kerning)
2504        {
2505                FT_Get_Kerning(font->face, font->prev_glyphindex, glyphindex, ft_kerning_default, &kerning);
2506                font->prev_glyphindex = glyphindex;
2507                kerning.x >>= 6;
2508        }
2509        else
2510                kerning.x = 0;
2511
2512        if(test == 1 || space == 1)
2513                return sbit->xadvance + kerning.x + charspace;
2514
2515        if(posx + sbit->xadvance > mwidth)
2516                return -1;
2517
2518        if(status.fasttextrender == 1)
2519        {
2520                max = 150;
2521                min = 100;
2522        }
2523
2524        red = (color & 0xff0000) >> 16;
2525        green = (color & 0x00ff00) >> 8;
2526        blue = color & 0xff;
2527        transparent = transparent & 0xff;
2528        tmpcol = color | transparent << 24;
2529        posy = posy + height - sbit->top;
2530        posx = posx + sbit->left + kerning.x;
2531
2532        py = (posy * skinfb->width) + posx;
2533        pyh = py + (sbit->height * skinfb->width);
2534        src = sbit->buffer;
2535
2536        for(y = py; y < pyh; y += skinfb->width)
2537        {
2538                pxw = y + sbit->pitch;
2539                for(x = y; x < pxw; x++)
2540                {
2541                        if(src[0] > min)
2542                        {
2543                                //renderquality 255-0 = best
2544                                if(src[0] > max)
2545                                        skinfb->fblong[x] = tmpcol;
2546                                else
2547                                {
2548                                        ralpha = 255 - src[0];
2549                                        alpha_composite(r, red, src[0], ralpha, (skinfb->fblong[x] & 0xff0000) >> 16);
2550                                        alpha_composite(g, green, src[0], ralpha, (skinfb->fblong[x] & 0x00ff00) >> 8);
2551                                        alpha_composite(b, blue, src[0], ralpha, skinfb->fblong[x] & 0xff);
2552                                        skinfb->fblong[x] = transparent << 24 | r << 16 | g << 8 | b;
2553                                }
2554                        }
2555                        src++;
2556                }
2557        }
2558
2559        return sbit->xadvance + kerning.x + charspace;
2560}
2561
2562void getstringwh(struct font* font, char *string, int *stringwidth, int *stringheight, int charspace)
2563{
2564        FT_ULong cret = 0;
2565        if(string == NULL) return;
2566
2567        while(*string != '\0' && *string != '\n')
2568        {
2569                string += strfreetype(string, &cret);
2570                *stringwidth += drawchar(font, cret, 0, 0, 0, 0, 0, 0, charspace, 1);
2571                string++;
2572        }
2573}
2574
2575int calcstrhalign(struct font* aktfont, char *string, int posx, int mwidth, int halign, int charspace)
2576{
2577        int stringwidth = 0, stringheight = 0;
2578        if(string == NULL) return 0;
2579
2580        switch(halign)
2581        {
2582                case TEXTCENTER:
2583                case CENTER:
2584                        getstringwh(aktfont, string, &stringwidth, &stringheight, charspace);
2585                        if(stringwidth < mwidth) posx += ((mwidth - stringwidth) >> 1);
2586                        break;
2587                case TEXTRIGHT:
2588                case RIGHT:
2589                        getstringwh(aktfont, string, &stringwidth, &stringheight, charspace);
2590                        if(stringwidth < mwidth) posx += mwidth - stringwidth;
2591                        break;
2592        }
2593        return posx;
2594}
2595
2596int calcstrvalign(char *string, int posy, int oldposy, int mheight, int fontsize, int linecount, int valign)
2597{
2598        if(string == NULL) return 0;
2599
2600        switch(valign)
2601        {
2602                case TEXTMIDDLE:
2603                case MIDDLE:
2604                        posy += (mheight >> 1) - ((fontsize * linecount) >> 1);
2605                        if(posy < oldposy) posy = oldposy;
2606                        break;
2607                case TEXTBOTTOM:
2608                case BOTTOM:
2609                        posy += mheight - (fontsize * linecount);
2610                        if(posy < oldposy) posy = oldposy;
2611                        break;
2612        }
2613
2614        return posy;
2615}
2616
2617struct font* setaktfont(char* fontname, int fontsize)
2618{
2619        struct font* aktfont = NULL;
2620
2621        if(fontname != NULL) aktfont = getfont(fontname);
2622        if(aktfont == NULL) aktfont = font;
2623
2624        aktfont->desc.width = fontsize;
2625        aktfont->desc.height = fontsize;
2626        aktfont->desc.flags = FT_LOAD_DEFAULT;
2627        aktfont->prev_glyphindex = 0;
2628
2629        return aktfont;
2630}
2631
2632void wrapstr(char* string, char* fontname, int fontsize, int mwidth, int charspace)
2633{
2634        int posx = 0;
2635        int stringheight = 0, stringwidth = 0;
2636        struct font* aktfont = NULL;
2637        char* tmpstr = NULL, *origstr = string;
2638        unsigned char c = 0;
2639
2640        if(string == NULL) return;
2641        aktfont = setaktfont(fontname, fontsize);
2642
2643        while(*string != '\0')
2644        {
2645                stringheight = 0; stringwidth = 0;
2646
2647                tmpstr = string;
2648
2649                while(*string != '\0' && *string != '\n' && *string != ' ' && *string != '-')
2650                        string++;
2651                if(*string == '\n')
2652                {
2653                        string++;
2654                        posx = 0;
2655                }
2656                else
2657                {
2658                        if(*string != '\0') string++;
2659                        c = *string; *string = '\0';
2660
2661                        getstringwh(aktfont, tmpstr, &stringwidth, &stringheight, charspace);
2662                        *string = c;
2663
2664                        posx += stringwidth;
2665                }
2666
2667                if(posx > mwidth && tmpstr > origstr)
2668                {
2669                        tmpstr--;
2670                        *tmpstr = '\n';
2671                        posx = stringwidth;
2672                }
2673        }
2674}
2675
2676//flag 0: normal
2677//flag 1: password
2678//flag 2: color
2679int drawstring(char* string, unsigned long linecount, unsigned int poscount, unsigned int markpos, int posx, int posy, int mwidth, int mheight, int halign, int valign, char* fontname, int fontsize, long color, int transparent, int wrap, int* lastposx, int* lastposy, int* len, int charspace, int flag)
2680{
2681        int charwidth = 0, lineend = 0;
2682        int charcount = 0;
2683        if(lastposy == NULL || *lastposy == 0) posy=posy + FONTPOSYOFFSET;
2684        int oldposx = posx, aktheight = 0, ret = 0;
2685        int oldposy = posy, oldmwidth = mwidth;
2686        struct font* aktfont = NULL;
2687        long tmpcol = color;
2688        FT_ULong cret = 0;
2689        char* tmpstr = NULL;
2690
2691        if(string == NULL || color == -1) return 1;
2692
2693        if(flag == 1)
2694        {
2695                string = mask(NULL, strlen(string), "*");
2696                tmpstr = string;
2697        }
2698
2699        if(flag == 2)
2700        {
2701                color = convertcol(string);
2702        }
2703
2704        transparent = (transparent - 255) * -1;
2705
2706        if(linecount < 2 && (fontsize == 0 || fontsize > mheight))
2707                fontsize = mheight;
2708
2709        aktfont = setaktfont(fontname, fontsize);
2710
2711        string = string + poscount;
2712
2713        if(fontsize < 5)
2714        {
2715                err("fontsize to small");
2716                if(flag == 1) free(tmpstr);
2717                return 1;
2718        }
2719
2720        posx = calcstrhalign(aktfont, string, posx, oldmwidth, halign, charspace);
2721        posy = calcstrvalign(string, posy, oldposy, mheight, fontsize, linecount, valign);
2722
2723        mwidth = posx + mwidth;
2724        aktheight += fontsize;
2725        if(aktheight > mheight)
2726        {
2727                err("to many textlines");
2728                if(flag == 1) free(tmpstr);
2729                return 1;
2730        }
2731
2732
2733
2734        while(*string != '\0')
2735        {
2736                charcount++;
2737                if(flag != 2)
2738                {
2739                        if(markpos == charcount)
2740                                color = status.markcol;
2741                        else
2742                                color = tmpcol;
2743                }
2744
2745                if(*string == '\n')
2746                {
2747                        if(linecount < 2) break;
2748                        lineend = 0;
2749                        aktheight += fontsize;
2750                        if(aktheight > mheight)
2751                        {
2752                                ret = 1;
2753                                break;
2754                        }
2755                        posy = posy + fontsize;
2756                        posx = oldposx;
2757                        string++;
2758                        posx = calcstrhalign(aktfont, string, posx, oldmwidth, halign, charspace);
2759                        continue;
2760                }
2761
2762                if(lineend == 1)
2763                {
2764                        string++;
2765                        continue;
2766                }
2767
2768                string += strfreetype(string, &cret);
2769
2770                if((charwidth = drawchar(aktfont, cret, posx, posy, mwidth, fontsize, color, transparent, charspace, 0)) == -1)
2771                        lineend = 1;
2772
2773                posx += charwidth;
2774                if(len != NULL) *len += charwidth;
2775                string++;
2776        }
2777        if(lastposx != NULL) *lastposx = posx;
2778        if(lastposy != NULL) *lastposy = posy + fontsize;
2779
2780        if(flag == 1) free(tmpstr);
2781        return ret;
2782}
2783
2784char* saverect(int posx, int posy, int width, int height)
2785{
2786        char* buf;
2787        int y = 0, len = width * skinfb->colbytes, px = posx * skinfb->colbytes;
2788
2789        buf = malloc(len * height);
2790        if(buf == NULL)
2791        {
2792                err("no memory");
2793                return NULL;
2794        }
2795
2796        for(y = 0; y < height; y++)
2797                memcpy(buf + len * y, skinfb->fb + ((y + posy) * skinfb->pitch) + px, len);
2798
2799        return buf;
2800}
2801
2802char* savescreen(struct skin* node)
2803{
2804        return saverect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth + (node->shadowsize << 1), node->rheight + (node->shadowsize << 1));
2805}
2806
2807//flag 0: no free
2808//flag 1: free
2809void restorerectcheck(char* buf, int posx, int posy, int width, int height, int flag)
2810{
2811        int y = 0, len = width * skinfb->colbytes, px = posx * skinfb->colbytes;
2812
2813        if(buf != NULL)
2814        {
2815                for(y = 0; y < height; y++)
2816                        memcpy(skinfb->fb + ((y + posy) * skinfb->pitch) + px, buf + len * y,  len);
2817
2818                if(flag == 1)
2819                {
2820                        free(buf);
2821                        buf = NULL;
2822                }
2823        }
2824}
2825
2826void restorerect(char* buf, int posx, int posy, int width, int height)
2827{
2828        restorerectcheck(buf, posx, posy, width, height, 1);
2829}
2830
2831void restorescreen(char* buf, struct skin* node)
2832{
2833        restorerectcheck(buf, node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth + (node->shadowsize << 1), node->rheight + (node->shadowsize << 1), 1);
2834}
2835
2836void restorescreennofree(char* buf, struct skin* node)
2837{
2838        restorerectcheck(buf, node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth + (node->shadowsize << 1), node->rheight + (node->shadowsize << 1), 0);
2839}
2840
2841//*************** GOST LCD
2842void lcd_fillrect(int posx, int posy, int width, int height, long color, int transparent)
2843{
2844        int y, x;
2845        unsigned long tmpcol;
2846
2847        if(posx < 0) posx = 0;
2848        if(posx > skinfb->width) posx = skinfb->width;
2849        if(posy < 0) posy = 0;
2850        if(posy > skinfb->height) posy = skinfb->height;
2851        if(posx + width > skinfb->width) width = skinfb->width - posx;
2852        if(posy + height > skinfb->height) height = skinfb->height - posy;
2853
2854        if(width <= 0 || height <= 0) return;
2855
2856        transparent = (transparent - 255) * -1;
2857        tmpcol = color | ((transparent & 0xff) << 24);
2858
2859        for(y = 0; y < height; y++)
2860                for(x = 0; x < width; x++)
2861                        drawpixel(posx + x, posy + y, tmpcol);
2862}
2863
2864void lcd_drawrect(int posx, int posy, int width, int height, long color, int transparent)
2865{
2866        fillrect(posx, posy, width, 1, color, transparent);
2867        fillrect(posx, posy + height - 1, width, 1, color, transparent);
2868        fillrect(posx, posy, 1, height, color, transparent);
2869        fillrect(posx + width - 1, posy, 1, height, color, transparent);
2870}
2871//*************** GOST LCD
2872
2873/*
2874void fillrect(int posx, int posy, int width, int height, long color, int transparent)
2875{
2876        int r, g, b;
2877
2878        r = (color >> 16) & 0xFF;
2879        g = (color >> 8) & 0xFF;
2880        b = color & 0xFF;
2881
2882        primary->SetDrawingFlags(primary, DSDRAW_NOFX);
2883        primary->SetColor(primary, r, g, b, transparent);
2884        primary->FillRectangle(primary, posx, posy, width, height);
2885        primary->Flip(primary, NULL, DSFLIP_WAITFORSYNC);
2886}
2887
2888void drawrect(int posx, int posy, int width, int height, long color, int transparent)
2889{
2890        int r, g, b;
2891
2892        r = (color >> 16) & 0xFF;
2893        g = (color >> 8) & 0xFF;
2894        b = color & 0xFF;
2895
2896        primary->SetDrawingFlags(primary, DSDRAW_NOFX);
2897        primary->SetColor(primary, r, g, b, transparent);
2898        primary->DrawRectangle(primary, posx, posy, width, height);
2899        primary->Flip(primary, NULL, DSFLIP_WAITFORSYNC);
2900}
2901*/
2902
2903void fillrect(int posx, int posy, int width, int height, long color, int transparent)
2904{
2905        if(skinfb != lcdskinfb && skinfb != oledskinfb)
2906                blitrect(posx, posy, width, height, color, transparent, 0);
2907        else
2908                lcd_fillrect(posx, posy, width, height, color, transparent);
2909}
2910
2911void drawrect(int posx, int posy, int width, int height, long color, int transparent)
2912{
2913        if(skinfb != lcdskinfb && skinfb != oledskinfb)
2914                blitrect(posx, posy, width, height, color, transparent, 1);
2915        else
2916                lcd_drawrect(posx, posy, width, height, color, transparent);
2917}
2918
2919void clearrect(int posx, int posy, int width, int height)
2920{
2921        fillrect(posx, posy, width, height, 0, 255);
2922}
2923
2924void clearscreen(struct skin* node)
2925{
2926        m_lock(&status.drawingmutex, 0);
2927        clearrect(node->rposx, node->rposy, node->rwidth, node->rheight);
2928        clearshadow(node);
2929        m_unlock(&status.drawingmutex, 0);
2930}
2931
2932void clearscreennolock(struct skin* node)
2933{
2934        clearrect(node->rposx, node->rposy, node->rwidth, node->rheight);
2935        clearshadow(node);
2936}
2937
2938//flag 0 = horizontal
2939//flag 1 = vertical
2940//flag 2 = horizontal (begin to middle, middle to end)
2941//flag 3 = vertical (begin to middle, middle to end)
2942void drawgradient(int posx, int posy, int width, int height, long col1, long col2, int transparent, int flag)
2943{
2944        int p, i, x, y, steps, xstep, ystep, tmp = 0, r = 0;
2945        int xcount = 0, ycount = 0, owidth = width, oheight = height;
2946        unsigned char r3, g3, b3;
2947        unsigned long col = 0;
2948
2949        transparent = (transparent - 255) * -1;
2950
2951        if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
2952        {
2953                if(flag == LEFTMIDDLE) width = width / 2;
2954                if(width < 10)
2955                        steps = width;
2956                if(width < 100)
2957                        steps = width / 2;
2958                else
2959                        steps = width / 5;
2960                xstep = width / steps;
2961                ystep = height;
2962        }
2963        else
2964        {
2965                if(flag == TOPMIDDLE) height = height / 2;
2966                if(height < 10)
2967                        steps = height;
2968                else if(height < 100)
2969                        steps = height / 2;
2970                else
2971                        steps = height / 5;
2972                xstep = width;
2973                ystep = height / steps;
2974        }
2975
2976        unsigned char r1 = (col1 >> 16) & 0xff;
2977        unsigned char g1 = (col1 >> 8) & 0xff;
2978        unsigned char b1 = col1 & 0xff;
2979
2980        unsigned char r2 = (col2 >> 16) & 0xff;
2981        unsigned char g2 = (col2 >> 8) & 0xff;
2982        unsigned char b2 = col2 & 0xff;
2983
2984        int yend = (posy + ystep) * skinfb->width;
2985        int xend = posx + xstep;
2986        posy *= skinfb->width;
2987
2988        for(i = 0; i < steps; i++)
2989        {
2990                p = steps - i;
2991                r3 = (r1 * p + r2 * i) / steps;
2992                g3 = (g1 * p + g2 * i) / steps;
2993                b3 = (b1 * p + b2 * i) / steps;
2994                col = (transparent << 24) | (r3 << 16) | (g3 << 8) | b3;
2995
2996                r = 0;
2997                for(y = posy; y < yend; y += skinfb->width)
2998                {
2999                        if(r == 0)
3000                        {
3001                                r = 1;
3002                                for(x = posx; x < xend; x++)
3003                                        drawpixelfast(x, y, col);
3004                        }
3005                        else
3006                                memcpy(skinfb->fb + (y + posx) * skinfb->colbytes, skinfb->fb + (posy + posx) * skinfb->colbytes, (xend - posx) * skinfb->colbytes);
3007                }
3008
3009                if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
3010                {
3011                        posx += xstep;
3012                        xcount += xstep;
3013                        xend = posx + xstep;
3014                }
3015                else
3016                {
3017                        tmp = ystep * skinfb->width;
3018                        posy += tmp;
3019                        ycount += ystep;
3020                        yend = posy + tmp;
3021                }
3022        }
3023
3024        if(flag == LEFTMIDDLE || flag == TOPMIDDLE)
3025        {
3026                for(i = 0; i < steps; i++)
3027                {
3028                        p = steps - i;
3029                        r3 = (r2 * p + r1 * i) / steps;
3030                        g3 = (g2 * p + g1 * i) / steps;
3031                        b3 = (b2 * p + b1 * i) / steps;
3032                        col = (transparent << 24) | (r3 << 16) | (g3 << 8) | b3;
3033
3034                        r = 0;
3035                        for(y = posy; y < yend; y += skinfb->width)
3036                        {
3037                                if(r == 0)
3038                                {
3039                                        r = 1;
3040                                        for(x = posx; x < xend; x++)
3041                                                drawpixelfast(x, y, col);
3042                                }
3043                                else
3044                                        memcpy(skinfb->fb + (y + posx) * skinfb->colbytes, skinfb->fb + (posy + posx) * skinfb->colbytes, (xend - posx) * skinfb->colbytes);
3045                        }
3046
3047                        if(flag == LEFTMIDDLE)
3048                        {
3049                                posx += xstep;
3050                                xcount += xstep;
3051                                xend = posx + xstep;
3052                        }
3053                        else
3054                        {
3055                                tmp = ystep * skinfb->width;
3056                                posy += tmp;
3057                                ycount += ystep;
3058                                yend = posy + tmp;
3059                        }
3060                }
3061        }
3062
3063        if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
3064        {
3065                if(owidth > xcount)
3066                {
3067                        int tmp = posx + (owidth - xcount);
3068                        for(y = posy; y < yend; y += skinfb->width)
3069                                for(x = posx; x < tmp; x++)
3070                                        drawpixelfast(x, y, col);
3071                }
3072        }
3073        if(flag == TOPBOTTOM || flag == TOPMIDDLE)
3074        {
3075                if(oheight > ycount)
3076                {
3077                        int tmp = posy + ((oheight - ycount) * skinfb->width);
3078                        for(y = posy; y < tmp; y += skinfb->width)
3079                                for(x = posx; x < xend; x++)
3080                                        drawpixelfast(x, y, col);
3081                }
3082        }
3083}
3084
3085void drawtitlebggradient(struct skin* node)
3086{
3087        if(status.picbordersize > 0)
3088                drawgradient(node->rposx + status.picbordersize, node->rposy + status.picbordersize, node->rwidth - (status.picbordersize << 1), node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->titlebgcol2, node->transparent, node->titlegradient);
3089        else
3090                drawgradient(node->rposx, node->rposy, node->rwidth, node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->titlebgcol2, node->transparent, node->titlegradient);
3091}
3092
3093void drawbggradient(struct skin* node)
3094{
3095        drawgradient(node->rposx, node->rposy, node->rwidth, node->rheight, node->bgcol, node->bgcol2, node->transparent, node->gradient);
3096}
3097
3098void drawtitlebgcol(struct skin* node)
3099{
3100        if(status.picbordersize > 0)
3101                fillrect(node->rposx + status.picbordersize, node->rposy + status.picbordersize, node->rwidth - (status.picbordersize << 1), node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->transparent);
3102        else
3103                fillrect(node->rposx, node->rposy, node->rwidth, node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->transparent);
3104}
3105
3106void drawbginnercol(struct skin* node)
3107{
3108        fillrect(node->rposx + node->bordersize, node->rposy + node->bordersize, node->rwidth - (node->bordersize << 1), node->rheight - (node->bordersize << 1), node->bgcol, node->transparent);
3109}
3110
3111void drawbgcol(struct skin* node)
3112{
3113        fillrect(node->rposx + node->bgspace, node->rposy + node->bgspace, node->rwidth - (node->bgspace << 1), node->rheight - (node->bgspace << 1), node->bgcol, node->transparent);
3114}
3115
3116void drawtitle(struct skin* node)
3117{
3118        if(status.titlelinesize > 0)
3119                drawstring(node->title, 1, 0, -1, node->iposx, node->rposy + node->bordersize, node->iwidth, node->titlesize - status.titlelinesize, node->titlealign, MIDDLE, node->font, node->fontsize, node->fontcol, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3120        else
3121                drawstring(node->title, 1, 0, -1, node->iposx, node->rposy + node->bordersize, node->iwidth, node->titlesize - node->bordersize, node->titlealign, MIDDLE, node->font, node->fontsize, node->fontcol, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3122        if(status.titlelinesize > 0)
3123                fillrect(node->rposx, node->rposy + node->titlesize + status.picbordersize, node->rwidth, status.titlelinesize, node->bordercol, node->transparent);
3124        else if(node->bordersize > 0)
3125                fillrect(node->rposx, node->rposy + node->titlesize, node->rwidth, node->bordersize, node->bordercol, node->transparent);
3126}
3127
3128void drawprogressbar(struct skin* node)
3129{
3130        int val = 0;
3131
3132        if(node->progresssize > 100) node->progresssize = 100;
3133        val = (((node->iwidth * 100) / 100) * node->progresssize) / 100;
3134        fillrect(node->rposx + node->bordersize, node->rposy + node->bordersize, val, node->iheight, node->progresscol, node->transparent);
3135}
3136
3137void drawmultiprogressbar(struct skin* node)
3138{
3139        struct epgrecord* epgrecord = node->epgrecord;
3140        int val1 = 0, val2 = 0;
3141
3142        while(epgrecord != NULL)
3143        {
3144
3145                if(epgrecord->posx > 100) epgrecord->posx = 100;
3146                val1 = (((node->iwidth * 100) / 100) * epgrecord->posx) / 100;
3147                if(epgrecord->size > 100) epgrecord->size = 100;
3148                val2 = (((node->iwidth * 100) / 100) * epgrecord->size) / 100;
3149
3150                if(val2 > val1)
3151                        fillrect(node->rposx + node->bordersize + node->bgspace + val1, node->rposy + node->bgspace + node->bordersize, val2 - val1 + (node->bgspace << 1), node->iheight + (node->bgspace << 1), node->progresscol, node->transparent);
3152                epgrecord = epgrecord->next;
3153        }
3154}
3155
3156void drawroundborder(struct skin* node, char* bglt, char* bglb, char* bgrt, char* bgrb)
3157{
3158        int i, rad = status.borderradius;
3159
3160        if(node->borderradius > 0) rad = node->borderradius;
3161        if(rad > (node->rheight >> 1)) rad = (node->rheight >> 1);
3162        int tmpbordersize = rad - node->bordersize;
3163
3164        //left - top
3165        for(i = rad; i > tmpbordersize; i--)
3166                drawcircle(node->rposx + rad, node->rposy + rad, i, 90, 180, node->bordercol, node->transparent, bglt, i == rad);
3167        //left - bottom
3168        for(i = rad; i > tmpbordersize; i--)
3169                drawcircle(node->rposx + rad, node->rposy + node->rheight - 1 - rad, i, 180, 270, node->bordercol, node->transparent, bglb, i == rad);
3170        //right - top
3171        for(i = rad; i > tmpbordersize; i--)
3172                drawcircle(node->rposx + node->rwidth - 1 - rad, node->rposy + rad, i, 0, 90, node->bordercol, node->transparent, bgrt, i == rad);
3173        //right - bottom
3174        for(i = rad; i > tmpbordersize; i--)
3175                drawcircle(node->rposx + node->rwidth - 1 - rad, node->rposy + node->rheight - 1 - rad, i, 270, 360, node->bordercol, node->transparent, bgrb, i == rad);
3176}
3177
3178//TODO: not full implemented
3179void drawpicborder(struct skin* node)
3180{
3181        int borderwidth = status.picbordersize;
3182        int borderheight = status.picbordersize;
3183
3184        //top-left
3185        //drawpic("/home/nit/titan/skin/bs_tl.png", node->rposx + node->bordersize - borderwidth, node->rposy + node->bordersize - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3186        drawpic("/home/nit/titan/skin/bs_tl.png", node->rposx, node->rposy, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3187        //top-right
3188        //drawpic("/home/nit/titan/skin/bs_tr.png", node->rposx - node->bordersize + node->rwidth, node->rposy + node->bordersize - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3189        drawpic("/home/nit/titan/skin/bs_tr.png", node->rposx + node->rwidth - borderwidth, node->rposy, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3190        //bottom-left
3191        //drawpic("/home/nit/titan/skin/bs_bl.png", node->rposx + node->bordersize - borderwidth, node->rposy - node->bordersize + node->rheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3192        drawpic("/home/nit/titan/skin/bs_bl.png", node->rposx, node->rposy + node->rheight - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3193        //bottom-right
3194        //drawpic("/home/nit/titan/skin/bs_br.png", node->rposx - node->bordersize + node->rwidth, node->rposy - node->bordersize + node->rheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3195        drawpic("/home/nit/titan/skin/bs_br.png", node->rposx + node->rwidth - borderwidth, node->rposy + node->rheight - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3196
3197        //top
3198        //drawpic("/home/nit/titan/skin/bs_t.png", node->rposx + node->bordersize, node->rposy + node->bordersize - borderheight, node->rwidth - (node->bordersize << 1), 0, node->rwidth - (node->bordersize << 1), borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3199        drawpic("/home/nit/titan/skin/bs_t.png", node->rposx + borderwidth, node->rposy, node->rwidth - (borderwidth << 1), 0, node->rwidth - (borderwidth << 1), borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3200        //bottom
3201        //drawpic("/home/nit/titan/skin/bs_b.png", node->rposx + node->bordersize, node->rposy - node->bordersize + node->rheight, node->rwidth - (node->bordersize << 1), 0, node->rwidth - (node->bordersize << 1), borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3202        drawpic("/home/nit/titan/skin/bs_b.png", node->rposx + borderwidth, node->rposy + node->rheight - borderheight, node->rwidth - (borderwidth << 1), 0, node->rwidth - (node->bordersize << 1), borderheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3203        //left
3204        //drawpic("/home/nit/titan/skin/bs_l.png", node->rposx + node->bordersize - borderwidth, node->rposy + node->bordersize, 0, node->rheight - (node->bordersize << 1), borderwidth, node->rheight - (node->bordersize << 1), LEFT, TOP, node->transparent, node->picquality, node->picmem);
3205        drawpic("/home/nit/titan/skin/bs_l.png", node->rposx, node->rposy + borderheight, 0, node->rheight - (borderheight << 1), borderwidth, node->rheight - (borderheight << 1), LEFT, TOP, node->transparent, node->picquality, node->picmem);
3206        //right
3207        //drawpic("/home/nit/titan/skin/bs_r.png", node->rposx - node->bordersize + node->rwidth, node->rposy + node->bordersize, 0, node->rheight - (node->bordersize << 1), borderwidth, node->rheight - (node->bordersize << 1), LEFT, TOP, node->transparent, node->picquality, node->picmem);
3208        drawpic("/home/nit/titan/skin/bs_r.png", node->rposx + node->rwidth - borderwidth, node->rposy + borderheight, 0, node->rheight - (borderheight << 1), borderwidth, node->rheight - (borderheight << 1), LEFT, TOP, node->transparent, node->picquality, node->picmem);
3209}
3210
3211void drawborder(struct skin* node)
3212{
3213        if(node->bordersize == 1 && node->rheight > 2 && node->bordertype == 0)
3214                drawrect(node->rposx, node->rposy, node->rwidth, node->rheight, node->bordercol, node->transparent);
3215        else if(node->bordersize == 1 && node->rheight <= 2 && node->bordertype == 0)
3216                fillrect(node->rposx, node->rposy, node->rwidth, node->rheight, node->bordercol, node->transparent);
3217        else
3218        {
3219                if(node->bordertype == 0 || checkbit(node->bordertype, 0) == 1)
3220                        fillrect(node->rposx, node->rposy, node->rwidth, node->bordersize, node->bordercol, node->transparent);
3221                if(node->bordertype == 0 || checkbit(node->bordertype, 1) == 1)
3222                        fillrect(node->rposx, node->rposy + node->rheight - node->bordersize, node->rwidth, node->bordersize, node->bordercol, node->transparent);
3223                if(node->bordertype == 0 || checkbit(node->bordertype, 2) == 1)
3224                        fillrect(node->rposx, node->rposy, node->bordersize, node->rheight, node->bordercol, node->transparent);
3225                if(node->bordertype == 0 || checkbit(node->bordertype, 3) == 1)
3226                        fillrect(node->rposx + node->rwidth - node->bordersize, node->rposy, node->bordersize, node->rheight, node->bordercol, node->transparent);
3227        }
3228}
3229
3230void drawscrollbar(struct skin* node)
3231{
3232        if(node->bordersize == 0)
3233                drawrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy, node->scrollbarwidth, node->iheight, node->bordercol, node->transparent);
3234        else
3235                fillrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy, node->scrollbarbordersize, node->iheight, node->bordercol, node->transparent);
3236
3237        fillrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy + node->scrollbarpos, node->scrollbarwidth, node->scrollbarheight, node->bordercol, node->transparent);
3238}
3239
3240void clearshadow(struct skin* node)
3241{
3242        if(node->shadowsize < 1) return;
3243        switch(node->shadowpos)
3244        {
3245                case BOTTOMLEFT:
3246                        clearrect(node->rposx - node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize);
3247                        clearrect(node->rposx - node->shadowsize, node->rposy + node->shadowsize, node->shadowsize, node->rheight);
3248                        break;
3249                case BOTTOMRIGHT:
3250                        clearrect(node->rposx + node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize);
3251                        clearrect(node->rposx + node->rwidth, node->rposy + node->shadowsize, node->shadowsize, node->rheight);
3252                        break;
3253                case TOPLEFT:
3254                        clearrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize);
3255                        clearrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->shadowsize, node->rheight);
3256                        break;
3257                default:
3258                        clearrect(node->rposx + node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize);
3259                        clearrect(node->rposx + node->rwidth, node->rposy - node->shadowsize, node->shadowsize, node->rheight);
3260                        break;
3261        }
3262}
3263
3264void drawshadow(struct skin* node)
3265{
3266        switch(node->shadowpos)
3267        {
3268                case BOTTOMLEFT:
3269                        fillrect(node->rposx - node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
3270                        fillrect(node->rposx - node->shadowsize, node->rposy + node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
3271                        break;
3272                case BOTTOMRIGHT:
3273                        fillrect(node->rposx + node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
3274                        fillrect(node->rposx + node->rwidth, node->rposy + node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
3275                        break;
3276                case TOPLEFT:
3277                        fillrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
3278                        fillrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
3279                        break;
3280                default:
3281                        fillrect(node->rposx + node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
3282                        fillrect(node->rposx + node->rwidth, node->rposy - node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
3283                        break;
3284        }
3285}
3286
3287//flag 0: del background
3288//flag 1: don't del background
3289void drawnode(struct skin* node, int flag)
3290{
3291        long color = 0, color2 = 0;
3292        int len = 0;
3293        char* bglt = NULL, *bglb = NULL, *bgrt = NULL, *bgrb = NULL;
3294
3295        node->flag = setbit(node->flag, 0);
3296
3297        if(node->name != NULL && ostrstr(node->name, "titletext") != NULL)
3298        {
3299                free(Mtitletext); Mtitletext = NULL;
3300                Mtitletext = ostrcat(node->text, NULL, 0, 0);
3301        }
3302
3303        if(node->bordersize > 0)
3304        {
3305                if((node->child != NULL && status.borderradius > 0) || node->borderradius > 0)
3306                {
3307                        int rad = status.borderradius;
3308
3309                        if(node->borderradius > 0) rad = node->borderradius;
3310                        if(rad > (node->rheight >> 1)) rad = (node->rheight >> 1);
3311
3312                        bglt = saverect(node->rposx, node->rposy, rad, rad);
3313                        bglb = saverect(node->rposx, node->rposy + node->rheight - rad, rad, rad);
3314                        bgrt = saverect(node->rposx + node->rwidth - rad, node->rposy, rad, rad);
3315                        bgrb = saverect(node->rposx + node->rwidth - rad, node->rposy + node->rheight - rad, rad, rad);
3316                }
3317        }
3318
3319        if(flag == 0 && node->bgcol == -1)
3320        {
3321                if(node->child != NULL && status.picbordersize > 0)
3322                        clearrect(node->rposx + node->bordersize, node->rposy + node->bordersize, node->rwidth - (node->bordersize << 1), node->rheight - (node->bordersize << 1));
3323                else
3324                        clearscreennolock(node);
3325        }
3326
3327        if(node->deaktivcol > -1)
3328        {
3329                color = node->deaktivcol;
3330                color2 = node->deaktivcol;
3331        }
3332        else
3333        {
3334                color = node->fontcol;
3335                color2 = node->fontcol2;
3336        }
3337
3338        if(node->shadowsize > 0)
3339                drawshadow(node);
3340        if(node->bgcol > -1)
3341        {
3342                if(node->child != NULL && status.picbordersize > 0)
3343                        drawbginnercol(node);
3344                else
3345                        drawbgcol(node);
3346        }
3347        if(node->child != NULL && status.bgpic != NULL)
3348                drawpic(status.bgpic, node->iposx, node->iposy, node->iwidth, node->iheight, node->iwidth, node->iheight, node->halign, node->valign, node->transparent, node->picquality, node->picmem);
3349        if(node->gradient > 0)
3350                drawbggradient(node);
3351        if(node->titlebgcol > -1)
3352                drawtitlebgcol(node);
3353        if(node->titlegradient > 0)
3354                drawtitlebggradient(node);
3355        if(node->progresssize > 0)
3356                drawprogressbar(node);
3357        if(node->type & MULTIPROGRESSBAR)
3358                drawmultiprogressbar(node);
3359        if(node->selectpic != NULL && !(node->type & FILELIST))
3360                drawpic(node->selectpic, node->iposx, node->iposy, node->iwidth, node->iheight, node->iwidth, node->iheight, LEFT, TOP, node->transparent, node->picquality, node->picmem);
3361        if(node->pic != NULL && !(node->type & FILELIST))
3362                drawpic(node->pic, node->iposx, node->iposy, node->rpicwidth, node->rpicheight, node->iwidth, node->iheight, node->halign, node->valign, node->transparent, node->picquality, node->picmem);
3363
3364        if(node->input != NULL)
3365        {
3366                if(node->type & CHOICEBOX)
3367                {
3368                        if(node->fontcol2 != 0 )
3369                                drawstring(node->input, 1, node->poscount, -1, node->iposx, node->iposy, node->iwidth, node->iheight, RIGHT, node->valign, node->font, node->fontsize, node->fontcol2, node->transparent, 0, NULL, NULL, &len, node->charspace, 0);
3370                        else
3371                                drawstring(node->input, 1, node->poscount, -1, node->iposx, node->iposy, node->iwidth, node->iheight, RIGHT, node->valign, node->font, node->fontsize, color, node->transparent, 0, NULL, NULL, &len, node->charspace, 0);
3372                }
3373                if((node->type & INPUTBOX) || (node->type & INPUTBOXNUM))
3374                {
3375                        if(node->type & PASSWORD)
3376                                drawstring(node->input, 1, node->poscount, node->aktpage, node->iposx, node->iposy, node->iwidth, node->iheight, RIGHT, node->valign, node->font, node->fontsize, color, node->transparent, 0, NULL, NULL, &len, node->charspace, 1);
3377                        else
3378                                drawstring(node->input, 1, node->poscount, node->aktpage, node->iposx, node->iposy, node->iwidth, node->iheight, RIGHT, node->valign, node->font, node->fontsize, color, node->transparent, 0, NULL, NULL, &len, node->charspace, 0);
3379                }
3380        }
3381        if(node->text != NULL)
3382        {
3383                if(node->type & TEXTBOX)
3384                {
3385                        int lastposy = 0;
3386                        drawstring(node->text, node->linecount, node->poscount, -1, node->iposx + node->textposx, node->iposy, node->iwidth - node->textposx, node->iheight, node->halign, node->valign, node->font, node->fontsize, color, node->transparent, node->wrap, NULL, &lastposy, NULL, node->charspace, 0);
3387                        drawstring(node->text2, node->linecount, node->poscount, -1, node->iposx + node->textposx2, lastposy, node->iwidth - node->textposx2, node->iheight - (lastposy - node->iposy), node->halign, node->valign, node->font, node->fontsize2, color2, node->transparent, node->wrap, NULL, &lastposy, NULL, node->charspace, 0);
3388                }
3389                else if(node->type & GRIDBR)
3390                {
3391                        int lastposx = 0;
3392                        int lastposy = 0;
3393                        if(node->textposx2 > 0)
3394                        {
3395                                drawstring(node->text, node->linecount, node->poscount, -1, node->iposx + node->textposx, node->iposy, node->iwidth - node->textposx, node->iheight, node->halign, node->valign, node->font, node->fontsize, color, node->transparent, node->wrap, &lastposx, &lastposy, NULL, node->charspace, 0);
3396                                drawstring(node->text2, node->linecount + 2, node->poscount, -1, node->iposx + node->textposx2, lastposy, node->iwidth - node->textposx2, node->iheight, node->halign, node->valign, node->font, node->fontsize2, color2, node->transparent, node->wrap, NULL, &lastposy, NULL, node->charspace, 0);
3397                        }
3398                        else
3399                        {
3400                                drawstring(node->text, 1, 0, -1, node->iposx + node->textposx, node->iposy, node->iwidth - node->textposx - len, node->iheight, node->halign, node->valign, node->font, node->fontsize, color, node->transparent, 0, &lastposx, NULL, NULL, node->charspace, 0);
3401                                drawstring(node->text2, 1, 0, -1, lastposx, node->iposy, node->iwidth - (lastposx - node->iposx) - len, node->iheight, node->halign, node->valign, node->font, node->fontsize2, color2, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3402                        }
3403                }
3404                else
3405                {
3406                        int lastposx = 0;
3407                        if(node->textposx2 > 0)
3408                        {
3409                                drawstring(node->text, 1, 0, -1, node->iposx + node->textposx, node->iposy, node->iwidth - node->textposx - (node->iwidth - node->textposx2) - len, node->iheight, node->halign, node->valign, node->font, node->fontsize, color, node->transparent, 0, &lastposx, NULL, NULL, node->charspace, 0);
3410                                drawstring(node->text2, 1, 0, -1, node->iposx + node->textposx2, node->iposy, node->iwidth - node->textposx2 - len, node->iheight, node->halign, node->valign, node->font, node->fontsize2, color2, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3411                        }
3412                        else
3413                        {
3414                                drawstring(node->text, 1, 0, -1, node->iposx + node->textposx, node->iposy, node->iwidth - node->textposx - len, node->iheight, node->halign, node->valign, node->font, node->fontsize, color, node->transparent, 0, &lastposx, NULL, NULL, node->charspace, 0);
3415                                drawstring(node->text2, 1, 0, -1, lastposx, node->iposy, node->iwidth - (lastposx - node->iposx) - len, node->iheight, node->halign, node->valign, node->font, node->fontsize2, color2, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3416                        }
3417                }
3418        }
3419        if(node->filelist != NULL && node->filelist->view > 3)
3420        {
3421                char* tmpnr = NULL;
3422
3423                if(node->filelist->view == 4)
3424                {
3425                        if(node->filelist->size >= 1073741824)
3426                        {
3427                                tmpnr = oftoa64((double)node->filelist->size / 1073741824, "2");
3428                                tmpnr = ostrcat(tmpnr, "G", 1, 0);
3429                        }
3430                        else if(node->filelist->size >= 1048576)
3431                        {
3432                                tmpnr = oftoa64((double)node->filelist->size / 1048576, "2");
3433                                tmpnr = ostrcat(tmpnr, "M", 1, 0);
3434                        }
3435                        else if(node->filelist->size >= 1024)
3436                        {
3437                                tmpnr = oftoa64((double)node->filelist->size / 1024, "2");
3438                                tmpnr = ostrcat(tmpnr, "K", 1, 0);
3439                        }
3440                        else
3441                        {
3442                                tmpnr = oitoa64(node->filelist->size);
3443                                tmpnr = ostrcat(tmpnr, "B", 1, 0);
3444                        }
3445                }
3446                if(node->filelist->view == 5)
3447                {
3448                        tmpnr = malloc(MINMALLOC);
3449                        if(tmpnr == NULL)
3450                        {
3451                                err("no mem");
3452                                return;
3453                        }
3454
3455                        struct tm* loctime = olocaltime(&node->filelist->date);
3456                        if(loctime != NULL)
3457                                strftime(tmpnr, MINMALLOC, "%H:%M %d-%m-%Y", loctime);
3458                        free(loctime);
3459                }
3460                drawstring(tmpnr, 1, node->poscount, -1, node->iposx, node->iposy, node->iwidth, node->iheight, RIGHT, node->valign, node->font, node->fontsize, node->fontcol, node->transparent, 0, NULL, NULL, NULL, node->charspace, 0);
3461                free(tmpnr);
3462        }
3463        if(node->title != NULL && node->fontsize > 1)
3464                drawtitle(node);
3465        if(node->scrollbar == YES || node->scrollbar == AUTOYES)
3466                drawscrollbar(node);
3467        if(node->bordersize > 0)
3468        {
3469                if(node->child != NULL && status.picbordersize > 0)
3470                        drawpicborder(node);
3471                else
3472                        drawborder(node);
3473                if((node->child != NULL && status.borderradius > 0) || node->borderradius > 0)
3474                        drawroundborder(node, bglt, bglb, bgrt, bgrb);
3475        }
3476
3477        free(bglt); free(bglb); free(bgrt); free(bgrb);
3478}
3479
3480void calcscrollbar(struct skin* node)
3481{
3482        node->scrollbarheight = node->iheight;
3483
3484        if(node->pagecount > 1)
3485        {
3486                node->scrollbarheight = (float)node->iheight / node->pagecount;
3487                node->scrollbarpos = ((float)node->iheight / node->pagecount) * (node->aktpage - 1);
3488                if(node->scrollbar == AUTONO) node->scrollbar = AUTOYES;
3489        }
3490        else if(node->scrollbar == AUTOYES)
3491                node->scrollbar = AUTONO;
3492
3493        if(node->scrollbar == YES || node->scrollbar == AUTOYES)
3494        {
3495                node->iwidth -= (SCROLLBARWIDTH + 5);
3496                node->scrollbarwidth = SCROLLBARWIDTH;
3497                node->scrollbarbordersize = SCROLLBARBORDERSIZE;
3498                if(node->iposy + node->scrollbarpos > node->iposy + node->iheight) node->scrollbarpos = node->iposy + node->iheight;
3499                if(node->scrollbarpos < 0) node->scrollbarpos = 0;
3500                if(node->iposy + node->scrollbarpos + node->scrollbarheight > node->iposy + node->iheight) node->scrollbarheight = node->iheight - node->scrollbarpos;
3501                if(node->scrollbarheight < 1) node->scrollbarheight = 1;
3502        }
3503}
3504
3505void calclistboxchild(struct skin* node, struct skin* parent)
3506{
3507        if((parent->type & GRID) && (node->type & GRIDBR))
3508        {
3509                if(parent->poscount > 0) parent->poscount += node->rheight;
3510                if(parent->poscount == 0) parent->poscount = 1;
3511        }
3512        node->rposy = node->rposy + parent->poscount;
3513        node->iposy = node->iposy + parent->poscount;
3514        if((parent->type & LISTBOX) || ((parent->type & FILELIST) && !(parent->type & GRID)))
3515                parent->poscount += node->rheight;
3516}
3517
3518int calclistbox(struct skin* node)
3519{
3520        struct skin* child = NULL, *last = NULL, *found = NULL;
3521        int selcol = 0;
3522
3523        if(node->type == FILELIST)
3524                selcol = status.filelistselectcol;
3525        else
3526                selcol = status.listboxselectcol;
3527
3528        node->poscount = 0;
3529        if(node->aktline == 0) node->aktline = 1;
3530        node->pagecount = 1;
3531        node->linecount = 0;
3532
3533        child = node->next;
3534        while(child != NULL)
3535        {
3536                if(child->parentpointer == NULL)
3537                {
3538                        if(child->parent == NULL)
3539                        {
3540                                child = child->next;
3541                                continue;
3542                        }
3543                        else if(ostrcmp(child->parent, node->name) != 0 || child->hidden == YES)
3544                        {
3545                                child = child->next;
3546                                continue;
3547                        }
3548                }
3549                else if(child->parentpointer != node || child->hidden == YES)
3550                {
3551                        child = child->next;
3552                        continue;
3553                }
3554
3555                if(child->locked == YES)
3556                {
3557                        child = child->next;
3558                        continue;
3559                }
3560
3561                calcrheight(child, node);
3562
3563                if((node->type & LISTBOX) || ((node->type & FILELIST) && !(node->type & GRID)) || ((node->type & GRID) && (child->type & GRIDBR)))
3564                        node->poscount = node->poscount + child->posy + child->rheight;
3565
3566                if(node->poscount > node->iheight)
3567                {
3568                        node->pagecount++;
3569                        node->poscount = child->rheight;
3570                }
3571
3572                child->pagecount = node->pagecount;
3573
3574                if(child->deaktivcol > -1)
3575                {
3576                        child = child->next;
3577                        continue;
3578                }
3579
3580                node->linecount++;
3581                last = child;
3582
3583                if(node->aktline == -1 && child->pagecount == node->aktpage)
3584                {
3585                        node->aktline = node->linecount;
3586                        found = child;
3587                }
3588                else if(node->aktline == node->linecount)
3589                        found = child;
3590
3591                child->bordersize = 0;
3592                if(status.listboxselecttype == 3)
3593                {
3594                        changeselectpic(child, NULL);
3595                        if(child->bgcol == status.markcol)
3596                                child->bgcol = child->bordercol;
3597                }
3598                if(child->bgcol == selcol || child->bgcol == status.markcol) //&& status.listboxselecttype == 1)
3599                        child->bgcol = child->bordercol;
3600                if(child->fontcol == selcol || child->fontcol == status.markcol) //&& status.listboxselecttype == 2)
3601                        child->fontcol = child->bordercol;
3602
3603                child = child->next;
3604        }
3605
3606        if(found == NULL)
3607        {
3608                found = last;
3609                node->aktline = node->linecount;
3610        }
3611
3612        if(found != NULL)
3613        {
3614                if(node->aktline == -2) node->aktline = node->linecount;
3615                if(status.listboxselecttype == 0)
3616                {
3617                        found->bordersize = 1;
3618                        if(status.markmodus > 0)
3619                        {
3620                                found->bordercol = status.markcol;
3621                                int i = 0;
3622                                struct skin* tmpskin = found;
3623                                for(i = 0; i < status.moveblockcount; i++)
3624                                {
3625                                        tmpskin = tmpskin->next;
3626                                        if(tmpskin != NULL)
3627                                                tmpskin->bordercol = status.markcol;
3628                                        else
3629                                                break;
3630                                }
3631                        }
3632                        else
3633                                found->bordercol = selcol;
3634                }
3635                else if(status.listboxselecttype == 1)
3636                {
3637                        if(found->bgcol != selcol && found->bgcol != status.markcol)
3638                        {
3639                                found->bordercol = found->bgcol;
3640                                int i = 0;
3641                                struct skin* tmpskin = found;
3642                                for(i = 0; i < status.moveblockcount; i++)
3643                                {
3644                                        tmpskin = tmpskin->next;
3645                                        if(tmpskin != NULL)
3646                                                tmpskin->bordercol = found->bgcol;
3647                                        else
3648                                                break;
3649                                }
3650                        }
3651                        if(status.markmodus > 0)
3652                        {
3653                                found->bgcol = status.markcol;
3654                                int i = 0;
3655                                struct skin* tmpskin = found;
3656                                for(i = 0; i < status.moveblockcount; i++)
3657                                {
3658                                        tmpskin = tmpskin->next;
3659                                        if(tmpskin != NULL)
3660                                                tmpskin->bgcol = status.markcol;
3661                                        else
3662                                                break;
3663                                }
3664                        }
3665                        else
3666                                found->bgcol = selcol;
3667                }
3668                else if(status.listboxselecttype == 2)
3669                {
3670                        if(found->fontcol != selcol && found->fontcol != status.markcol)
3671                        {
3672                                found->bordercol = found->fontcol;
3673                                int i = 0;
3674                                struct skin* tmpskin = found;
3675                                for(i = 0; i < status.moveblockcount; i++)
3676                                {
3677                                        tmpskin = tmpskin->next;
3678                                        if(tmpskin != NULL)
3679                                                tmpskin->bordercol = found->fontcol;
3680                                        else
3681                                                break;
3682                                }
3683                        }
3684                        if(status.markmodus > 0)
3685                        {
3686                                found->fontcol = status.markcol;
3687                                int i = 0;
3688                                struct skin* tmpskin = found;
3689                                for(i = 0; i < status.moveblockcount; i++)
3690                                {
3691                                        tmpskin = tmpskin->next;
3692                                        if(tmpskin != NULL)
3693                                                tmpskin->fontcol = status.markcol;
3694                                        else
3695                                                break;
3696                                }
3697                        }
3698                        else
3699                                found->fontcol = selcol;
3700                }
3701                else if(status.listboxselecttype == 3)
3702                {
3703                        if(status.markmodus > 0)
3704                        {
3705                                found->bordersize = 1;
3706                                found->bordercol = status.markcol;
3707                                int i = 0;
3708                                struct skin* tmpskin = found;
3709                                for(i = 0; i < status.moveblockcount; i++)
3710                                {
3711                                        tmpskin = tmpskin->next;
3712                                        if(tmpskin != NULL)
3713                                        {
3714                                                tmpskin->bordersize = 1;
3715                                                tmpskin->bordercol = status.markcol;
3716                                        }
3717                                        else
3718                                                break;
3719                                }
3720                        }
3721                        else
3722                                changeselectpic(found, status.selectpic);
3723                }
3724
3725                if(node->aktpage == -1)
3726                        node->aktpage = found->pagecount;
3727                node->select = found;
3728        }
3729
3730        if(node->aktpage == -1) node->aktpage = 0;
3731        if(node->aktpage > node->pagecount)
3732        {
3733                if(node->pagecount == 0) node->aktpage = 0;
3734                else node->aktpage = 1;
3735        }
3736        node->poscount = 0;
3737        return 0;
3738}
3739
3740int calcrwidth(struct skin* node, struct skin* parent)
3741{
3742        int scrollbarwidth = 0;
3743
3744        if(node->prozwidth == 1)
3745                node->rwidth = (((parent->iwidth * 100) / 100) * node->width) / 100;
3746        else
3747                node->rwidth = node->width;
3748
3749        if(node->scrollbar == YES || node->scrollbar == AUTOYES || node->scrollbar == AUTONO) scrollbarwidth = SCROLLBARWIDTH;
3750
3751        if(node->rwidth < (node->bordersize << 1) + scrollbarwidth) node->rwidth = (node->bordersize << 1) + scrollbarwidth;
3752
3753        return 0;
3754}
3755
3756int calcrheight(struct skin* node, struct skin* parent)
3757{
3758        if(node->prozheight == 1)
3759                node->rheight = (((parent->iheight * 100) / 100) * node->height) / 100;
3760        else
3761        {
3762                node->rheight = node->height;
3763                if(node->fontsize == 0) node->fontsize = parent->fontsize;
3764                if(node->fontsize == 0) node->fontsize = 1;
3765                if(node->rheight == 0) node->rheight = node->fontsize + 2;
3766        }
3767
3768        if(node->rheight < (node->bordersize << 1) + node->titlesize) node->rheight = (node->bordersize << 1) + node->titlesize;
3769
3770        return 0;
3771}
3772
3773int calcrposx(struct skin* node, struct skin* parent)
3774{
3775        if(node->prozposx == 1)
3776                node->rposx = (((parent->iwidth * 100) / 100) * node->posx) / 100;
3777        else
3778                node->rposx = node->posx;
3779
3780        if(node->posx == CENTER || (node->posx == 0 && parent->halign == CENTER))
3781                node->rposx = parent->iposx + (parent->iwidth >> 1) - (node->rwidth >> 1);
3782        else if(node->posx == LEFT)
3783                node->rposx = parent->iposx;
3784        else if(node->posx == RIGHT || (node->posx == 0 && parent->halign == RIGHT))
3785                node->rposx = parent->iposx + parent->iwidth - node->rwidth;
3786        else
3787                node->rposx = parent->iposx + node->rposx;
3788
3789        if(node->rposx > parent->iposx + parent->iwidth)
3790                node->rposx = parent->iposx + parent->iwidth;
3791
3792        return 0;
3793}
3794
3795int calcrposy(struct skin* node, struct skin* parent)
3796{
3797        if(node->prozposy == 1)
3798                node->rposy = (((parent->iheight * 100) / 100) * node->posy) / 100;
3799        else
3800                node->rposy = node->posy;
3801
3802        if(node->posy == MIDDLE || (node->posy == 0 && parent->valign == MIDDLE))
3803                node->rposy = parent->iposy + (parent->iheight >> 1) - (node->rheight >> 1);
3804        else if(node->posy == TOP)
3805                node->rposy = parent->iposy;
3806        else if(node->posy == BOTTOM || (node->posy ==0 && parent->valign == BOTTOM))
3807                node->rposy = parent->iposy + parent->iheight - node->rheight;
3808        else
3809                node->rposy = parent->iposy + node->rposy;
3810
3811        if(node->rposy > parent->iposy + parent->iheight)
3812                node->rposy = parent->iposy + parent->iheight;
3813
3814        return 0;
3815}
3816
3817int setnodeattr(struct skin* node, struct skin* parent, int screencalc)
3818{
3819        if(node != skin) node->flag = clearbit(node->flag, 0);
3820        if((parent->type & LISTBOX) || (parent->type & FILELIST) || (parent->type & GRID))
3821                if(node->pagecount != parent->aktpage) return 1;
3822
3823        int shadowlx = 0, shadowrx = 0, shadowoy = 0, shadowuy = 0;
3824        unsigned int linecount = 0, pagecount = 0, poscount = 0;
3825        char* tmpstr = NULL;
3826
3827        if(node->child != NULL && status.picbordersize > 0)
3828                node->bordersize = status.picbordersize;
3829
3830        if(node->nodestyle != 0)
3831        {
3832                if(node->nodestyle == 2 && getconfigint("skinblinkoff", NULL) == 0)
3833                        node->nodestyle = 1;
3834                else if(node->nodestyle == 1 && getconfigint("skinblinkoff", NULL) == 1)
3835                        node->nodestyle = 2;
3836                if(node->nodestyle == 1)
3837                        setblink(node);
3838        }
3839
3840        if(node->skinfunc != NULL)
3841        {
3842                if(node->funcrettype == FUNCPIC)
3843                {
3844                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3845                        changepic(node, tmpstr);
3846                }
3847                else if(node->funcrettype == FUNCPICOLED)
3848                {
3849                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3850                        if(tmpstr != NULL)
3851                                changepic(node, tmpstr);
3852                }
3853                else if(node->funcrettype == FUNCPROGRESS)
3854                {
3855                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3856                        if(tmpstr != NULL)
3857                        {
3858                                node->hidden = NO;
3859                                node->progresssize = atoi(tmpstr);
3860                        }
3861                        else
3862                                node->hidden = YES;
3863                }
3864                else
3865                {
3866                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3867                        changetext(node, _(tmpstr));
3868                }
3869                free(tmpstr);
3870        }
3871
3872        if(screencalc != 2)
3873        {
3874                if(node->hidden == YES || parent->hidden == YES || node->locked == YES || parent->locked == YES) return 1;
3875                if(checkbit(parent->flag, 0) == 0) return 1;
3876        }
3877
3878        calcrwidth(node, parent);
3879        if(!(parent->type & LISTBOX) && !(parent->type & FILELIST) && !(parent->type & GRID))
3880                calcrheight(node, parent);
3881        calcrposx(node, parent);
3882        calcrposy(node, parent);
3883
3884        if(node->height < 0)
3885                node->rheight = parent->iheight + node->height - (node->rposy - parent->iposy);
3886        if(node->width < 0)
3887                node->rwidth = parent->iwidth + node->width - (node->rposx - parent->iposx);
3888
3889        node->iposx = node->rposx + node->bordersize + node->hspace;
3890        node->iposy = node->rposy + node->bordersize + node->titlesize + node->vspace;
3891        node->iwidth = node->rwidth - (node->bordersize << 1) - (node->hspace << 1);
3892        node->iheight = node->rheight - (node->bordersize << 1) - node->titlesize - (node->vspace << 1);
3893
3894        switch(node->shadowpos)
3895        {
3896                case BOTTOMLEFT: shadowlx = shadowuy = node->shadowsize; break;
3897                case BOTTOMRIGHT: shadowrx = shadowuy = node->shadowsize; break;
3898                case TOPLEFT: shadowlx = shadowoy = node->shadowsize; break;
3899                default: shadowrx = shadowoy = node->shadowsize; break;
3900        }
3901
3902        if((parent->type & LISTBOX) || (parent->type & FILELIST) || (parent->type & GRID))
3903                calclistboxchild(node, parent);
3904
3905        if(node->picprozwidth == 1)
3906                node->rpicwidth = (((node->iwidth * 100) / 100) * node->picwidth) / 100;
3907        else
3908                node->rpicwidth = node->picwidth;
3909        if(node->picprozheight == 1)
3910                node->rpicheight = (((node->iheight * 100) / 100) * node->picheight) / 100;
3911        else
3912                node->rpicheight = node->picheight;
3913
3914        if(node->rposx - shadowlx < parent->iposx)
3915        {
3916                if(screencalc == 0) err("node (%s posx=%d) out of parent (%s posx=%d)", node->name, node->rposx - shadowlx, parent->name, parent->iposx);
3917                node->rposx = parent->iposx + shadowlx;
3918                //return 1;
3919        }
3920        if(node->rposy - shadowoy < parent->iposy)
3921        {
3922                if(screencalc == 0) err("node (%s posy=%d) out of parent (%s posy=%d)", node->name, node->rposy - shadowoy, parent->name, parent->iposy);
3923                node->rposy = parent->iposy + shadowoy;
3924                //return 1;
3925        }
3926        if(node->rposx + node->rwidth + shadowrx > parent->iposx + parent->iwidth)
3927        {
3928                if(screencalc == 0) err("node (%s posxx=%d) out of parent (%s posxx=%d)", node->name, node->rposx + node->rwidth + shadowrx, parent->name, parent->iposx + parent->iwidth);
3929                node->rwidth = parent->iwidth - node->rposx - shadowrx;
3930                //return 1;
3931        }
3932        if(node->rposy + node->rheight + shadowuy > parent->iposy + parent->iheight)
3933        {
3934                if(screencalc == 0) err("node (%s posyy=%d) out of parent (%s posyy=%d)", node->name, node->rposy + node->rheight + shadowuy, parent->name, parent->iposy + parent->iheight);
3935                node->rheight = parent->iheight - node->rposy - shadowuy;
3936                //return 1;
3937        }
3938
3939        if(node->font == NULL && parent->font != NULL)
3940        {
3941                changefont(node, parent->font);
3942                if(node->font == NULL)
3943                {
3944                        err("no memory");
3945                }
3946        }
3947
3948        if(node->fontsize == 0) node->fontsize = parent->fontsize;
3949        if(node->fontsize == 0) node->fontsize = 1;
3950        if(node->fontsize2 == 0) node->fontsize2 = parent->fontsize2;
3951        if(node->fontsize2 == 0) node->fontsize2 = 1;
3952        if(node->fontcol == 0) node->fontcol = parent->fontcol;
3953        if(node->fontcol2 == 0) node->fontcol2 = parent->fontcol2;
3954
3955        if((node->type & INPUTBOX) || (node->type & INPUTBOXNUM))
3956        {
3957                if(node->aktpage < 1) node->aktpage = 1;
3958                checkinputboxnumright(node);
3959                changeret(node, node->input);
3960        }
3961
3962        if((node->type & LISTBOX) || (node->type & FILELIST) || (node->type & GRID))
3963        {
3964                if(node->aktpage == 0) node->aktpage = 1;
3965                calclistbox(node);
3966                if(node->scrollbar != NO)
3967                        calcscrollbar(node);
3968        }
3969        if(node->type & TEXTBOX)
3970        {
3971                if(node->aktpage < 1) node->aktpage = 1;
3972                if(node->text == NULL && node->text2 == NULL)
3973                        node->pagecount = 0;
3974                else
3975                {
3976                        if(node->wrap == YES)
3977                        {
3978                                wrapstr(node->text, node->font, node->fontsize, node->iwidth - node->textposx, node->charspace);
3979                                wrapstr(node->text2, node->font, node->fontsize2, node->iwidth - node->textposx2, node->charspace);
3980                        }
3981                        calctext(node->text, node->text2, &node->linecount, &node->pagecount, &node->poscount, node->iheight / node->fontsize, node->aktpage);
3982                }
3983                if(node->text2 != NULL) node->scrollbar = NO;
3984                if(node->scrollbar != NO)
3985                        calcscrollbar(node);
3986        }
3987
3988        if(node->type & GRIDBR)
3989        {
3990                if(node->aktpage < 1) node->aktpage = 1;
3991                if(node->text == NULL && node->text2 == NULL)
3992                        node->pagecount = 0;
3993                else
3994                {
3995                        if(node->wrap == YES)
3996                        {
3997                                wrapstr(node->text, node->font, node->fontsize, node->iwidth - node->textposx2, node->charspace);
3998                                wrapstr(node->text2, node->font, node->fontsize2, node->iwidth - node->textposx2, node->charspace);
3999                        }
4000                        calctext(node->text, node->text2, &node->linecount, &node->pagecount, &node->poscount, node->iheight / node->fontsize, node->aktpage);
4001                }
4002                if(node->text2 != NULL) node->scrollbar = NO;
4003                if(node->scrollbar != NO)
4004                        calcscrollbar(node);
4005        }
4006
4007        if((node->type & CHOICEBOX) && node->input != NULL)
4008        {
4009                char* pos = NULL;
4010                calctext(node->input, NULL, &node->linecount, &node->pagecount, &node->poscount, 1, node->aktpage);
4011
4012                free(node->ret);
4013                node->ret = NULL;
4014
4015                if(node->choiceboxvalue != NULL)
4016                {
4017                        calctext(node->choiceboxvalue, NULL, &linecount, &pagecount, &poscount, 1, node->aktpage);
4018                        pos = strchr(node->choiceboxvalue + poscount, '\n');
4019                        if(pos == NULL)
4020                                changeret(node, node->choiceboxvalue + poscount);
4021                        else
4022                                node->ret = strndup(node->choiceboxvalue + poscount, pos - (node->choiceboxvalue + poscount));
4023                }
4024                else if(node->input != NULL)
4025                {
4026                        pos = strchr(node->input + node->poscount, '\n');
4027                        if(pos == NULL)
4028                                changeret(node, node->input + node->poscount);
4029                        else
4030                                node->ret = strndup(node->input + node->poscount, pos - (node->input + node->poscount));
4031                }
4032        }
4033
4034        //set parent transparent to child
4035        //if(node->transparent == 0 && parent != skin)
4036                //node->transparent = parent->transparent;
4037
4038        return 0;
4039}
4040
4041int clearscreenalways()
4042{
4043        int i, ret = 0;
4044        int tmp = sizeof(status.drawallways) / sizeof(skin);
4045
4046        for(i = 0; i < tmp; i++)
4047        {
4048                if(status.drawallways[i] != NULL)
4049                {
4050                        clearrect(status.drawallways[i]->rposx, status.drawallways[i]->rposy, status.drawallways[i]->rwidth, status.drawallways[i]->rheight);
4051                }
4052        }
4053
4054        return ret;
4055}
4056
4057int drawscreenalways(struct skin* node, int screencalc)
4058{
4059        int i, ret = 0;
4060        int tmp = sizeof(status.drawallways) / sizeof(skin);
4061
4062        m_lock(&status.oledmutex, 25);
4063        for(i = 0; i < tmp; i++)
4064        {
4065                if(status.drawallways[i] != NULL)
4066                {
4067                        if(node != status.drawallways[i])
4068                        {
4069                                if(status.drawallwaysbg[i] != NULL)
4070                                        free(status.drawallwaysbg[i]);
4071                                status.drawallwaysbg[i] = savescreen(status.drawallways[i]);
4072       
4073                                ret = drawscreen(status.drawallways[i], screencalc, 1);
4074                        }
4075                }
4076        }
4077        m_unlock(&status.oledmutex, 25);
4078
4079        return ret;
4080}
4081
4082int drawscreennode(struct skin *node, char* nodename, int screencalc)
4083{
4084        node = getscreennode(node, nodename);
4085
4086        m_lock(&status.drawingmutex, 0);
4087        if(node != status.skinerr)
4088                drawnode(node, 1);
4089        drawscreenalways(node, screencalc);
4090
4091        blitfb(0);
4092        m_unlock(&status.drawingmutex, 0);
4093
4094        return 0;
4095}
4096
4097int drawscreennodebyname(char* screenname, char* nodename, int screencalc)
4098{
4099        struct skin *node;
4100
4101        node = getscreennodebyname(screenname, nodename);
4102        m_lock(&status.drawingmutex, 0);
4103        if(node != status.skinerr)
4104                drawnode(node, 1);
4105
4106        drawscreenalways(node, screencalc);
4107        blitfb(0);
4108        m_unlock(&status.drawingmutex, 0);
4109
4110        return 0;
4111}
4112
4113//flag 0: draw normal with allways
4114//flag 1: draw without allways
4115//flag 2: from thread (mutex is set in thread)
4116//flag 3: unused
4117//flag 4: same as 0 but animate
4118//screencalc 0: calculate and draw
4119//screencalc 1: only calculate without hidden nodes
4120//screencalc 2: only calculate hidden nodes
4121int drawscreen(struct skin* node, int screencalc, int flag)
4122{
4123        //struct fb* merkskinfb = NULL;
4124        int ret;
4125        struct skin *child = NULL, *parent = NULL, *oldparent = NULL;
4126
4127        if(node == NULL)
4128        {
4129                err("node = NULL");
4130                return 1;
4131        }
4132
4133        if(status.skinblink == 0)
4134                status.skinblink = 1;
4135        else
4136                status.skinblink = 0;
4137
4138        if(flag == 0 || flag == 4)
4139                m_lock(&status.drawingmutex, 0);
4140
4141        parent = skin;
4142
4143        ret = setnodeattr(node, parent, screencalc);
4144        if(ret == 1)
4145        {
4146                if(flag == 0 || flag == 4)
4147                        m_unlock(&status.drawingmutex, 0);
4148                err("setnodeattr ret = 1");
4149                return 1;
4150        }
4151        debug(100, "start drawscreen with screenname=%s", node->name);
4152        if(node->name != NULL && ostrstr(node->name, "LCD_") != NULL)
4153        {
4154                m_lock(&status.oledmutex, 25);
4155                if(lcdskinfb == NULL) {
4156#ifndef MIPSEL
4157                        if(node->name != NULL && ostrstr(node->name, "LCD_spf87") != NULL) {
4158                                unsigned char *newskinfb = calloc(1, 4 * 800 * 480);
4159                                if(newskinfb == NULL)
4160                                {
4161                                        if(flag == 0 || flag == 4)
4162                                                m_unlock(&status.drawingmutex, 0);
4163                                        m_unlock(&status.oledmutex, 25);
4164                                        return -2;
4165                                }
4166                                lcdskinfb = addfb("lcdskinfb", 999, 800, 480, 4, -1, newskinfb, 4 * 800 * 480, 0);
4167                        }
4168                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf72") != NULL) {
4169                                unsigned char *newskinfb = calloc(1, 4 * 800 * 480);
4170                                if(newskinfb == NULL)
4171                                {
4172                                        if(flag == 0 || flag == 4)
4173                                                m_unlock(&status.drawingmutex, 0);
4174                                        m_unlock(&status.oledmutex, 25);
4175                                        return -2;
4176                                }
4177                                lcdskinfb = addfb("lcdskinfb", 999, 800, 480, 4, -1, newskinfb, 4 * 800 * 480, 0);
4178                        }
4179                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf83") != NULL) {
4180                                unsigned char *newskinfb = calloc(1, 4 * 800 * 600);
4181                                if(newskinfb == NULL)
4182                                {
4183                                        if(flag == 0 || flag == 4)
4184                                                m_unlock(&status.drawingmutex, 0);
4185                                        m_unlock(&status.oledmutex, 25);
4186                                        return -2;
4187                                }
4188                                lcdskinfb = addfb("lcdskinfb", 999, 800, 600, 4, -1, newskinfb, 4 * 800 * 600, 0);
4189                        }
4190                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf85") != NULL) {
4191                                unsigned char *newskinfb = calloc(1, 4 * 800 * 600);
4192                                if(newskinfb == NULL)
4193                                {
4194                                        if(flag == 0 || flag == 4)
4195                                                m_unlock(&status.drawingmutex, 0);
4196                                        m_unlock(&status.oledmutex, 25);
4197                                        return -2;
4198                                }
4199                                lcdskinfb = addfb("lcdskinfb", 999, 800, 600, 4, -1, newskinfb, 4 * 800 * 600, 0);
4200                        }
4201                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf75") != NULL) {
4202                                unsigned char *newskinfb = calloc(1, 4 * 800 * 480);
4203                                if(newskinfb == NULL)
4204                                {
4205                                        if(flag == 0 || flag == 4)
4206                                                m_unlock(&status.drawingmutex, 0);
4207                                        m_unlock(&status.oledmutex, 25);
4208                                        return -2;
4209                                }
4210                                lcdskinfb = addfb("lcdskinfb", 999, 800, 480, 4, -1, newskinfb, 4 * 800 * 480, 0);
4211                        }
4212                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf107") != NULL) {
4213                                unsigned char *newskinfb = calloc(1, 4 * 1024 * 600);
4214                                if(newskinfb == NULL)
4215                                {
4216                                        if(flag == 0 || flag == 4)
4217                                                m_unlock(&status.drawingmutex, 0);
4218                                        m_unlock(&status.oledmutex, 25);
4219                                        return -2;
4220                                }
4221                                lcdskinfb = addfb("lcdskinfb", 999, 1024, 600, 4, -1, newskinfb, 4 * 1024 * 600, 0);
4222                        }
4223                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf105") != NULL) {
4224                                unsigned char *newskinfb = calloc(1, 4 * 1024 * 600);
4225                                if(newskinfb == NULL)
4226                                {
4227                                        if(flag == 0 || flag == 4)
4228                                                m_unlock(&status.drawingmutex, 0);
4229                                        m_unlock(&status.oledmutex, 25);
4230                                        return -2;
4231                                }
4232                                lcdskinfb = addfb("lcdskinfb", 999, 1024, 600, 4, -1, newskinfb, 4 * 1024 * 600, 0);
4233                        }
4234                        else if(node->name != NULL && ostrstr(node->name, "LCD_d320") != NULL) {
4235                                unsigned char *newskinfb = calloc(1, 4 * 320 * 240);
4236                                if(newskinfb == NULL)
4237                                {
4238                                        if(flag == 0 || flag == 4)
4239                                                m_unlock(&status.drawingmutex, 0);
4240                                        m_unlock(&status.oledmutex, 25);
4241                                        return -2;
4242                                }
4243                                lcdskinfb = addfb("lcdskinfb", 999, 320, 240, 4, -1, newskinfb, 4 * 320 * 240, 0);
4244                        }
4245                        else {
4246                                unsigned char *newskinfb = calloc(1, 4 * 320 * 240);
4247                                if(newskinfb == NULL)
4248                                {
4249                                        if(flag == 0 || flag == 4)
4250                                                m_unlock(&status.drawingmutex, 0);
4251                                        m_unlock(&status.oledmutex, 25);
4252                                        return -2;
4253                                }
4254                                lcdskinfb = addfb("lcdskinfb", 999, 320, 240, 4, -1, newskinfb, 4 * 320 * 240, 0);
4255                        }
4256#else
4257                        if(node->name != NULL && ostrstr(node->name, "LCD_spf87") != NULL)
4258                                lcdskinfb = oledaddfb(800, 480);
4259                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf72") != NULL)
4260                                lcdskinfb = oledaddfb(800, 480);
4261                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf83") != NULL)
4262                                lcdskinfb = oledaddfb(800, 600);
4263                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf85") != NULL)
4264                                lcdskinfb = oledaddfb(800, 600);
4265                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf75") != NULL)
4266                                lcdskinfb = oledaddfb(800, 480);
4267                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf107") != NULL)
4268                                lcdskinfb = oledaddfb(1024, 600);
4269                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf105") != NULL)
4270                                lcdskinfb = oledaddfb(1024, 600);
4271                        else if(node->name != NULL && ostrstr(node->name, "LCD_spf_d320") != NULL)
4272                                lcdskinfb = oledaddfb(320, 240);
4273                        else
4274                                lcdskinfb = oledaddfb(320, 240);
4275                        if(lcdskinfb == NULL)
4276                        {
4277                                if(flag == 0 || flag == 4)
4278                                        m_unlock(&status.drawingmutex, 0);
4279                                m_unlock(&status.oledmutex, 25);
4280                                return -2;
4281                        }
4282#endif
4283                }
4284                merkskinfb = skinfb;
4285                //memset(lcdskinfb->fb, 0, lcdskinfb->varfbsize);
4286                skinfb = lcdskinfb;
4287        }
4288        else if(node->name != NULL && ostrstr(node->name, "OLED_") != NULL)
4289        {
4290                m_lock(&status.oledmutex, 25);
4291                if(oledskinfb == NULL) {
4292                        if(node->name != NULL && ostrstr(node->name, "OLED_nemesis") != NULL) {
4293                                debug(100, "alloc OLED_nemesis framebuffer");
4294                                oledskinfb = oledaddfb(256, 64);
4295                                if(oledskinfb == NULL)
4296                                {
4297                                        if(flag == 0 || flag == 4)
4298                                                m_unlock(&status.drawingmutex, 0);
4299                                        return -2;
4300                                }
4301                        }
4302                        else if(node->name != NULL && ostrstr(node->name, "OLED_dream1") != NULL) {
4303                                debug(100, "alloc OLED_dream1 framebuffer");
4304                                oledskinfb = oledaddfb(128, 64);
4305                                if(oledskinfb == NULL)
4306                                {
4307                                        if(flag == 0 || flag == 4)
4308                                                m_unlock(&status.drawingmutex, 0);
4309                                        return -2;
4310                                }
4311                        }
4312                        else if(node->name != NULL && ostrstr(node->name, "OLED_dream2") != NULL) {
4313                                debug(100, "alloc OLED_dream2 framebuffer");
4314                                oledskinfb = oledaddfb(400, 240);
4315                                if(oledskinfb == NULL)
4316                                {
4317                                        if(flag == 0 || flag == 4)
4318                                                m_unlock(&status.drawingmutex, 0);
4319                                        return -2;
4320                                }
4321                        }
4322                        else if(node->name != NULL && ostrstr(node->name, "OLED_vu1") != NULL) {
4323                                debug(100, "alloc OLED_vu1 framebuffer");
4324                                oledskinfb = oledaddfb(480, 320);
4325                                if(oledskinfb == NULL)
4326                                {
4327                                        if(flag == 0 || flag == 4)
4328                                                m_unlock(&status.drawingmutex, 0);
4329                                        return -2;
4330                                }
4331                        }
4332                        else if(node->name != NULL && ostrstr(node->name, "OLED_vu2") != NULL) {
4333                                debug(100, "alloc OLED_vu2 framebuffer");
4334                                oledskinfb = oledaddfb(400, 240);
4335                                if(oledskinfb == NULL)
4336                                {
4337                                        if(flag == 0 || flag == 4)
4338                                                m_unlock(&status.drawingmutex, 0);
4339                                        return -2;
4340                                }
4341                        }
4342                }
4343                merkskinfb = skinfb;
4344                skinfb = oledskinfb;
4345        }
4346
4347        if(screencalc == 0 || flag == 4)
4348        {
4349                if(flag == 0 || flag == 2 || flag == 4) clearscreenalways();
4350                drawnode(node, 0);
4351        }
4352        parent = node;
4353        oldparent = node;
4354        child = node->child;
4355
4356        while(child != NULL)
4357        {
4358                if(child->parentpointer != NULL)
4359                        parent = child->parentpointer;
4360                else if(child->parent != NULL)
4361                {
4362                        parent = getscreennode(node, child->parent);
4363                        if(parent == status.skinerr) parent = oldparent;
4364                }
4365                else
4366                        parent = oldparent;
4367
4368                // hid minitvbg
4369                if(child->name != NULL && ostrstr(child->name, "minitvbg") != NULL && getskinconfigint("minitv", NULL) == 1)
4370                        child->hidden = YES;
4371
4372                if(setnodeattr(child, parent, screencalc) == 0 && screencalc == 0)
4373                        drawnode(child, 1);
4374                child = child->next;
4375        }
4376
4377        if(flag == 0 || flag == 2 || flag == 4)
4378        {
4379                if(screencalc == 0)
4380                {
4381                        if(merkskinfb != NULL)
4382                        {
4383                                if(node->name != NULL && ostrstr(node->name, "LCD_spf") != NULL)
4384                                        write_FB_to_JPEG_file(skinfb->fb, skinfb->width, skinfb->height, "/tmp/titanlcd.jpg", 75);
4385                                else if(node->name != NULL && ostrstr(node->name, "OLED_") != NULL)
4386                                        write2oled(skinfb->fb, skinfb->width, skinfb->height);
4387                                else
4388                                        pngforlcd(skinfb->fb, skinfb->width, skinfb->height);
4389                        }
4390                        else
4391                        {
4392                                status.drawscreencount++;
4393                                drawscreenalways(node, screencalc);
4394                                if(flag == 4)
4395                                        blitfb(1);
4396                                else
4397                                        blitfb(0);
4398                        }
4399                }
4400        }
4401
4402        if(merkskinfb != NULL)
4403        {
4404                debug(100, "no framebuffer screenname=%s", node->name);
4405                /*delete temporary FB*/
4406#ifndef MIPSEL
4407                if(skinfb == oledskinfb)
4408#else
4409                if(skinfb == oledskinfb || skinfb == lcdskinfb)
4410#endif
4411                {
4412                        skinfb = merkskinfb;
4413                        merkskinfb = NULL;
4414                }
4415                else
4416                {
4417                        debug(100, "free lcdskinfb");
4418                        free(skinfb->fb); skinfb->fb = NULL;
4419                        skinfb = merkskinfb;
4420                        merkskinfb = NULL;
4421                        delfb("lcdskinfb");
4422                        lcdskinfb = NULL;
4423                }
4424                debug(100, "no framebuffer end");
4425                m_unlock(&status.oledmutex, 25);
4426        }
4427        //else
4428        //{
4429        //      if(ostrcmp(getconfig("write_fb_to_jpeg", NULL), "yes") == 0)
4430        //              write_FB_to_JPEG_file(skinfb->fb, skinfb->width, skinfb->height, "/tmp/fb.jpg", 3);
4431        //}
4432        if(flag == 0 || flag == 4)
4433                m_unlock(&status.drawingmutex, 0);
4434        debug(100, "ende drawscreen with screenname=%s", node->name);
4435        return 0;
4436}
4437
4438int drawscreenbyname(char* screenname, int screencalc, int flag)
4439{
4440        int ret;
4441        struct skin* node = NULL;
4442
4443        node = getscreen(screenname);
4444        if(node == status.skinerr)
4445        {
4446                err("screen not found (%s)", screenname);
4447                return 1;
4448        }
4449
4450        ret = drawscreen(node, screencalc, flag);
4451        return ret;
4452}
4453
4454int changeinput(struct skin* node, char* text)
4455{
4456        int ret = 1;
4457
4458        if(node != NULL)
4459        {
4460                free(node->input);
4461                if(text != NULL)
4462                {
4463                        if((node->type & INPUTBOXNUM) && node->mask != NULL && strlen(text) == 0)
4464                                node->input = strdup(node->mask);
4465                        else
4466                                node->input = strdup(text);
4467                }
4468                else
4469                {
4470                        if((node->type & INPUTBOXNUM) && node->mask != NULL)
4471                                node->input = strdup(node->mask);
4472                        else
4473                                node->input = text;
4474                }
4475                ret = 0;
4476        }
4477
4478        return ret;
4479}
4480
4481int changetext(struct skin* node, char* text)
4482{
4483        int ret = 1;
4484
4485        if(node != NULL)
4486        {
4487                free(node->text);
4488                if(text != NULL)
4489                        node->text = strdup(text);
4490                else
4491                        node->text = text;
4492                ret = 0;
4493        }
4494
4495        return ret;
4496}
4497
4498int changetext2(struct skin* node, char* text)
4499{
4500        int ret = 1;
4501
4502        if(node != NULL)
4503        {
4504                free(node->text2);
4505                if(text != NULL)
4506                        node->text2 = strdup(text);
4507                else
4508                        node->text2 = text;
4509                ret = 0;
4510        }
4511
4512        return ret;
4513}
4514
4515
4516int changename(struct skin* node, char* text)
4517{
4518        int ret = 1;
4519
4520        if(node != NULL)
4521        {
4522                free(node->name);
4523                if(text != NULL)
4524                        node->name = strdup(text);
4525                else
4526                        node->name = strdup("unknown");
4527                ret = 0;
4528        }
4529
4530        return ret;
4531}
4532
4533int changepicmem(struct skin* node, char* text, int timeout, int del)
4534{
4535        unsigned long width = 0, height = 0, rowbytes = 0;
4536        int ret = 1, channels = 0, memfd = -1, length = 0;
4537        unsigned char* buf = NULL;
4538
4539        if(node != NULL)
4540        {
4541                free(node->pic);
4542                if(text != NULL)
4543                {
4544                        node->picmem = 1;
4545                        node->pic = changepicpath(text);
4546
4547                        if(getpic(node->pic) == NULL)
4548                        {
4549                                length = strlen(node->pic);
4550                                if(node->pic[length - 1] == 'g' && node->pic[length - 2] == 'n' && node->pic[length - 3] == 'p')
4551                                        buf = readpng(node->pic, &width, &height, &rowbytes, &channels, 0, 0, 0, 0, 0, 0);
4552                                else if(getconfigint("pichwdecode", NULL) == 1)
4553                                        readjpg(node->pic, &width, &height, &rowbytes, &channels, &buf, &memfd);
4554                                else
4555                                        buf = loadjpg(node->pic, &width, &height, &rowbytes, &channels, 1);
4556                                addpic(node->pic, buf, memfd, width, height, rowbytes, channels, timeout, del, NULL);
4557                        }
4558                }
4559                else
4560                        node->pic = text;
4561                ret = 0;
4562        }
4563
4564        return ret;
4565}
4566
4567int changepic(struct skin* node, char* text)
4568{
4569        int ret = 1;
4570
4571        if(node != NULL)
4572        {
4573                node->picmem = 0;
4574                free(node->pic);
4575                if(text != NULL)
4576                        node->pic = changepicpath(text);
4577                else
4578                        node->pic = text;
4579                ret = 0;
4580        }
4581
4582        return ret;
4583}
4584
4585int changeselectpic(struct skin* node, char* text)
4586{
4587        int ret = 1;
4588
4589        if(node != NULL)
4590        {
4591                free(node->selectpic);
4592                if(text != NULL)
4593                        node->selectpic = changepicpath(text);
4594                else
4595                        node->selectpic = text;
4596                ret = 0;
4597        }
4598
4599        return ret;
4600}
4601
4602int changetitle(struct skin* node, char* text)
4603{
4604        int ret = 1;
4605
4606        struct skin* titletext = getscreennode(node, "titletext");
4607        if( (text != NULL) && (titletext != status.skinerr) )
4608                changetext(titletext, text);
4609        else
4610                debug(10, "failed titletext=%s", text);
4611
4612        if(node != NULL)
4613        {
4614                free(node->title);
4615                if( (text != NULL) && (node->fontsize > 1) )
4616                {
4617                        node->title = strdup(text);
4618                        node->titlesize = node->fontsize + 6;
4619                }
4620                else
4621                {
4622                        node->title = NULL;
4623                        node->titlesize = 0;
4624                }
4625                ret = 0;
4626        }
4627
4628        return ret;
4629}
4630
4631int changemask(struct skin* node, char* text)
4632{
4633        int ret = 1;
4634
4635        if(node != NULL)
4636        {
4637                free(node->mask);
4638                if(text != NULL)
4639                {
4640                        if((node->type & INPUTBOXNUM) && (node->input == NULL || strlen(node->input) == 0))
4641                        {
4642                                node->mask = strdup(text);
4643                                free(node->input);
4644                                node->input = strdup(text);
4645                        }
4646                        else
4647                                node->mask = strdup(text);
4648                }
4649                else
4650                        node->mask = text;
4651                ret = 0;
4652        }
4653
4654        return ret;
4655}
4656
4657int changeret(struct skin* node, char* text)
4658{
4659        int ret = 1;
4660
4661        if(node != NULL)
4662        {
4663                free(node->ret);
4664                if(text != NULL)
4665                        node->ret = strdup(text);
4666                else
4667                        node->ret = text;
4668                ret = 0;
4669        }
4670
4671        return ret;
4672}
4673
4674int changeparent(struct skin* node, char* text)
4675{
4676        int ret = 1;
4677
4678        if(node != NULL)
4679        {
4680                free(node->parent);
4681                if(text != NULL)
4682                        node->parent = strdup(text);
4683                else
4684                        node->parent = text;
4685                ret = 0;
4686        }
4687
4688        return ret;
4689}
4690
4691int changefont(struct skin* node, char* text)
4692{
4693        int ret = 1;
4694
4695        if(node != NULL)
4696        {
4697                free(node->font);
4698                if(text != NULL)
4699                        node->font = strdup(text);
4700                else
4701                        node->font = text;
4702                ret = 0;
4703        }
4704
4705        return ret;
4706}
4707
4708int changeparam1(struct skin* node, char* text)
4709{
4710        int ret = 1;
4711
4712        if(node != NULL)
4713        {
4714                free(node->param1);
4715                if(text != NULL)
4716                        node->param1 = strdup(text);
4717                else
4718                        node->param1 = text;
4719                ret = 0;
4720        }
4721
4722        return ret;
4723}
4724
4725int changeparam2(struct skin* node, char* text)
4726{
4727        int ret = 1;
4728
4729        if(node != NULL)
4730        {
4731                free(node->param2);
4732                if(text != NULL)
4733                        node->param2 = strdup(text);
4734                else
4735                        node->param2 = text;
4736                ret = 0;
4737        }
4738
4739        return ret;
4740}
4741
4742int changechoiceboxvalue(struct skin* node, char* text)
4743{
4744        int ret = 1;
4745
4746        if(node != NULL)
4747        {
4748                free(node->choiceboxvalue);
4749                if(text != NULL)
4750                        node->choiceboxvalue = strdup(text);
4751                else
4752                        node->choiceboxvalue = text;
4753                ret = 0;
4754        }
4755
4756        return ret;
4757}
4758
4759unsigned char * resize(unsigned char *origin, int ox, int oy, int dx, int dy, int type, unsigned char * dst, int flag)
4760{
4761        unsigned char * cr;
4762
4763        if(dst == NULL)
4764        {
4765                cr = (unsigned char*) malloc(dx*dy*3);
4766
4767                if(cr == NULL)
4768                {
4769                        printf("Error: malloc\n");
4770                        return(origin);
4771                }
4772        }
4773        else
4774                cr = dst;
4775
4776        if(type == 1)
4777        {
4778                unsigned char *p,*l;
4779                int i,j,k,ip;
4780                l = cr;
4781
4782                for(j=0; j<dy; j++, l += dx*3)
4783                {
4784                        p = origin + (j*oy/dy*ox*3);
4785                        for(i=0, k=0; i<dx; i++, k+=3)
4786                        {
4787                                ip=i*ox/dx*3;
4788                                memmove(l+k, p+ip, 3);
4789                        }
4790                }
4791        }
4792        else
4793        {
4794                unsigned char *p,*q;
4795                int i,j,k,l,ya,yb;
4796                int sq,r,g,b;
4797
4798                p=cr;
4799
4800                int xa_v[dx];
4801                for(i=0;i<dx;i++)
4802                        xa_v[i] = i*ox/dx;
4803                int xb_v[dx+1];
4804
4805                for(i=0;i<dx;i++)
4806                {
4807                        xb_v[i]= (i+1)*ox/dx;
4808                        if(xb_v[i]>=ox)
4809                                xb_v[i]=ox-1;
4810                }
4811
4812                for(j=0;j<dy;j++)
4813                {
4814                        ya= j*oy/dy;
4815                        yb= (j+1)*oy/dy; if(yb>=oy) yb=oy-1;
4816                        for(i=0;i<dx;i++,p+=3)
4817                        {
4818                                for(l=ya,r=0,g=0,b=0,sq=0;l<=yb;l++)
4819                                {
4820                                        q=origin+((l*ox+xa_v[i])*3);
4821                                        for(k=xa_v[i];k<=xb_v[i];k++,q+=3,sq++)
4822                                        {
4823                                                r+=q[0]; g+=q[1]; b+=q[2];
4824                                        }
4825                                }
4826                                p[0]=r/sq; p[1]=g/sq; p[2]=b/sq;
4827                        }
4828                }
4829        }
4830
4831        if(flag == 1)
4832                free(origin);
4833
4834        return(cr);
4835}
4836
4837#endif
Note: See TracBrowser for help on using the repository browser.