source: titan/titan/skin.h @ 15251

Last change on this file since 15251 was 15251, checked in by nit, 11 years ago

[titan] use jpg read scale

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