source: titan/titan/skin.h @ 26912

Last change on this file since 26912 was 24784, checked in by nit, 10 years ago

optimize

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