source: titan/titan/skin.h @ 23982

Last change on this file since 23982 was 23982, checked in by nit, 9 years ago

[titan] test optimize

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