source: titan/titan/skin.h @ 15242

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

fix

File size: 95.2 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        cinfo.scale_denom = 1;
1423        jpeg_start_decompress(&cinfo);
1424        width = cinfo.output_width;
1425        height = cinfo.output_height;
1426
1427        row_stride = cinfo.output_width * cinfo.output_components;
1428        buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
1429
1430        if(accelfb != NULL && accelfb->varfbsize > width * 8 && (scalewidth != 0 || scaleheight != 0))
1431        {
1432                //auto scale to mwidth / mheight
1433                if(scalewidth == 1 && scaleheight == 1)
1434                        calcautoscale(width, height, mwidth, mheight, &scalewidth, &scaleheight);
1435               
1436                if(scalewidth == 0) scalewidth = width;
1437                if(scaleheight == 0) scaleheight = height;
1438                if(scalewidth > mwidth) scalewidth = mwidth;
1439                if(scaleheight > mheight) scaleheight = mheight;
1440
1441                if(halign == CENTER)
1442                        posx += mwidth / 2 - scalewidth / 2;
1443                else if(halign == RIGHT)
1444                        posx += mwidth - scalewidth;
1445                if(valign == MIDDLE)
1446                        posy += mheight / 2 - scaleheight / 2;
1447                else if(valign == BOTTOM)
1448                        posy += mheight - scaleheight;
1449       
1450                int nposy = posy;
1451                py = -1;
1452
1453                m_lock(&status.accelfbmutex, 16);
1454                while(cinfo.output_scanline < height)
1455                {
1456                        jpeg_read_scanlines(&cinfo, buffer, 1);
1457                        py++;
1458                        for(x = 0; x < width; x++)
1459                        {
1460                                red = buffer[0][cinfo.output_components * x];
1461                                if(cinfo.output_components > 2)
1462                                {
1463                                        green = buffer[0][cinfo.output_components * x + 1];
1464                                        blue = buffer[0][cinfo.output_components * x + 2];
1465                                }
1466                                else
1467                                {
1468                                        green = red;
1469                                        blue = red;
1470                                }
1471                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1472                                drawpixelfb(accelfb, (width * py) + x, 0, color);
1473                        }
1474                        if((py * width * 4) + (width * 8) >= accelfb->varfbsize)
1475                        {
1476                                if(scaleheight > 0)
1477                                {
1478                                        float tmp = (float)height / (float)scaleheight;
1479                                        if(tmp > 0)
1480                                        {
1481                                                tmp = (float)py / tmp;
1482                                                blitscale(posx, nposy, width, py, scalewidth, (int)tmp, 0);
1483                                                nposy += tmp;
1484                                        }
1485                                }
1486                                py = -1;
1487                        }
1488                }
1489                //blit the rest
1490                if(scaleheight > 0 && py > 0)
1491                {
1492                        float tmp = (float)height / (float)scaleheight;
1493                        if(tmp > 0)
1494                        {
1495                                tmp = (float)py / tmp;
1496                                blitscale(posx, nposy, width, py, scalewidth, (int)tmp, 0);
1497                        }
1498                }
1499                m_unlock(&status.accelfbmutex, 16);
1500        }
1501        else
1502        {
1503                if(width > mwidth) width = mwidth;
1504                if(height > mheight) height = mheight;
1505
1506                if(halign == CENTER)
1507                        posx += mwidth / 2 - width / 2;
1508                else if(halign == RIGHT)
1509                        posx += mwidth - width;
1510                if(valign == MIDDLE)
1511                        posy += mheight / 2 - height / 2;
1512                else if(valign == BOTTOM)
1513                        posy += mheight - height;
1514
1515                while(cinfo.output_scanline < height)
1516                {
1517                        jpeg_read_scanlines(&cinfo, buffer, 1);
1518                        py = (posy + cinfo.output_scanline - 1) * skinfb->width;
1519                        for(x = 0; x < width; x++)
1520                        {
1521                                red = buffer[0][cinfo.output_components * x];
1522                                if(cinfo.output_components > 2)
1523                                {
1524                                        green = buffer[0][cinfo.output_components * x + 1];
1525                                        blue = buffer[0][cinfo.output_components * x + 2];
1526                                }
1527                                else
1528                                {
1529                                        green = red;
1530                                        blue = red;
1531                                }
1532                                color = (255 << 24) | (red << 16) | (green << 8) | blue;
1533                                drawpixelfast(posx + x, py, color);
1534                        }
1535                }
1536        }
1537        jpeg_finish_decompress(&cinfo);
1538        jpeg_destroy_decompress(&cinfo);
1539        fclose(fd);
1540        return 0;
1541}
1542
1543unsigned 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)
1544{
1545        debug(1000, "in");
1546        FILE *fd = NULL;
1547        int ret, bit_depth, color_type;
1548        unsigned char *buf = NULL;
1549        static png_structp png_ptr = NULL;
1550        static png_infop info_ptr = NULL;
1551        double gamma;
1552        png_uint_32 y;
1553        png_bytepp row_pointers = NULL;
1554        png_bytep sig = NULL;
1555        unsigned char* directbuf = NULL;
1556
1557        fd = fopen(filename, "rb");
1558        if(fd == NULL)
1559        {
1560                perr("open png file %s", filename);
1561                return NULL;
1562        }
1563
1564        sig = malloc(8);
1565        if(sig == NULL)
1566        {
1567                err("no memory");
1568                fclose(fd);
1569                return NULL;
1570        }
1571
1572        fread(sig, 1, 8, fd);
1573        ret = png_check_sig(sig, 8);
1574        if(ret == 0)
1575        {
1576                err("%s is not a PNG file", filename);
1577                free(sig);
1578                fclose(fd);
1579                return NULL;
1580        }
1581
1582        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1583        if(png_ptr == NULL)
1584        {
1585                err("%s no memory", filename);
1586                free(sig);
1587                fclose(fd);
1588                return NULL;
1589        }
1590
1591        info_ptr = png_create_info_struct(png_ptr);
1592        if(info_ptr == NULL)
1593        {
1594                png_destroy_read_struct(&png_ptr, NULL, NULL);
1595                err("%s no memory", filename);
1596                free(sig);
1597                fclose(fd);
1598                return NULL;
1599        }
1600
1601        ret = setjmp(png_jmpbuf(png_ptr));
1602        if(ret != 0)
1603        {
1604                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1605                err("%s has bad IHDR (libpng longjmp)", filename);
1606                free(sig);
1607                fclose(fd);
1608                return NULL;
1609        }
1610
1611        png_init_io(png_ptr, fd);
1612        png_set_sig_bytes(png_ptr, 8);
1613        png_read_info(png_ptr, info_ptr);
1614        png_get_IHDR(png_ptr, info_ptr, width, height, &bit_depth, &color_type, NULL, NULL, NULL);
1615
1616        ret = setjmp(png_jmpbuf(png_ptr));
1617        if(ret != 0)
1618        {
1619                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1620                err("%s unknown error", filename);
1621                free(sig);
1622                fclose(fd);
1623                return NULL;
1624        }
1625
1626        if(color_type == PNG_COLOR_TYPE_PALETTE)
1627                png_set_expand(png_ptr);
1628        if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1629                png_set_expand(png_ptr);
1630        if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1631                png_set_expand(png_ptr);
1632        if(bit_depth == 16)
1633                png_set_strip_16(png_ptr);
1634        if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1635                png_set_gray_to_rgb(png_ptr);
1636        if(png_get_gAMA(png_ptr, info_ptr, &gamma))
1637                png_set_gamma(png_ptr, 2.2, gamma);
1638
1639/*
1640        if(mwidth > 0 && mheight > 0 && *width <= mwidth && *height <= mheight)
1641        {
1642                if(halign == CENTER)
1643                        posx += mwidth / 2 - (*width) / 2;
1644                else if(halign == RIGHT)
1645                        posx += mwidth - (*width);
1646                if(valign == MIDDLE)
1647                        posy += mheight / 2 - (*height) / 2;
1648                else if(valign == BOTTOM)
1649                        posy += mheight - (*height);
1650                directbuf = skinfb->fb + (posy * skinfb->pitch) + (posx * skinfb->colbytes);
1651                if(color_type == PNG_COLOR_TYPE_RGB)
1652                        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
1653                png_set_bgr(png_ptr);
1654        }
1655*/
1656
1657        png_read_update_info(png_ptr, info_ptr);
1658        *rowbytes = png_get_rowbytes(png_ptr, info_ptr);
1659        *channels = (int)png_get_channels(png_ptr, info_ptr);
1660
1661        //if(directbuf == NULL)
1662                buf = malloc((*rowbytes) * (*height));
1663        //else
1664        //      buf = directbuf;
1665
1666        if(buf == NULL)
1667        {
1668                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1669                err("%s no memory", filename);
1670                free(sig);
1671                fclose(fd);
1672                return NULL;
1673        }
1674
1675        row_pointers = (png_bytepp)malloc((*height) * sizeof(png_bytep));
1676        if(row_pointers == NULL)
1677        {
1678                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1679                err("%s unknown error", filename);
1680                free(sig);
1681                if(directbuf == NULL) free(buf);
1682                fclose(fd);
1683                return NULL;
1684        }
1685
1686        //if(directbuf == NULL)
1687        //{
1688                for (y = 0; y < (*height); ++y)
1689                        row_pointers[y] = (png_bytep)buf + y * (*rowbytes);
1690        //}
1691        //else
1692        //{
1693        //      for (y = 0;  y < (*height);  ++y)
1694        //              row_pointers[y] = (png_bytep)buf + y * skinfb->pitch;
1695        //}
1696
1697        png_read_image(png_ptr, row_pointers);
1698        free(row_pointers);
1699        row_pointers = NULL;
1700
1701        png_read_end(png_ptr, NULL);
1702        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1703
1704        free(sig);
1705        fclose(fd);
1706
1707        debug(100, "png width=%ld height=%ld channels=%d rowbytes=%ld", *width, *height, *channels, *rowbytes);
1708
1709        debug(1000, "out");
1710        //if(directbuf == NULL)
1711                return buf;
1712        //else
1713        //      return NULL;
1714}
1715
1716void drawpic(const char* filename, int posx, int posy, int scalewidth, int scaleheight, int mwidth, int mheight, int halign, int valign)
1717{
1718        debug(1000, "in");
1719        unsigned char *buf = NULL, *scalebuf = NULL;
1720        int memfd = -1, py = 0, pyh = 0, pxw = 0, diff = 0; //px = 0
1721        unsigned long width, height, rowbytes;
1722        int channels, length;
1723        unsigned char *src; // red, green, blue, alpha;
1724        //unsigned long color;
1725        png_uint_32 y, x;
1726        struct pic* picnode = NULL;
1727        int decoding = getconfigint("pichwdecode", NULL);
1728        int pictype = 0; //0 = png, 1 = jpg HW, 2 = jpg SW
1729
1730        length = strlen(filename);
1731        if(filename[length - 1] == 'g' && filename[length - 2] == 'n' && filename[length - 3] == 'p')
1732                pictype = 0;
1733        else if(decoding == 1)
1734                pictype = 1;
1735        else
1736                pictype = 2;
1737
1738        picnode = getpic((char*)filename);
1739        if(picnode == NULL)
1740        {
1741                if(pictype == 0)
1742                {
1743                        //deaktivate: draws transparent pixel
1744                        //read direkt into framebuffer
1745                        //if(scaleheight == 0 && scalewidth == 0)
1746                        //      buf = readpng(filename, &width, &height, &rowbytes, &channels, posx, posy, mwidth, mheight, halign, valign);
1747                        //else
1748                        buf = readpng(filename, &width, &height, &rowbytes, &channels, 0, 0, 0, 0, 0, 0);
1749                }
1750                else if(pictype == 1)
1751                        readjpg(filename, &width, &height, &rowbytes, &channels, &buf, &memfd);
1752                else if(pictype == 2)
1753                        readjpgsw(filename, posx, posy, mwidth, mheight, scalewidth, scaleheight, halign, valign);
1754        }
1755        else
1756        {
1757                buf = picnode->picbuf;
1758                width = picnode->width;
1759                height = picnode->height;
1760                rowbytes = picnode->rowbytes;
1761                channels = picnode->channels;
1762                memfd = picnode->memfd;
1763        }
1764
1765        if((pictype == 0 || pictype == 1) && buf == NULL) return;
1766
1767        if(pictype == 0 && (scalewidth != 0 || scaleheight != 0))
1768        {
1769                //auto scale to mwidth / mheight
1770                if(scalewidth == 1 && scaleheight == 1)
1771                        calcautoscale(width, height, mwidth, mheight, &scalewidth, &scaleheight);
1772       
1773                if(scalewidth == 0) scalewidth = width;
1774                if(scaleheight == 0) scaleheight = height;
1775                if(picnode == NULL)
1776                        scalebuf = scale(buf, rowbytes / channels, height, channels, scalewidth, scaleheight, 1);
1777                else
1778                {
1779                        scalebuf = scale(buf, rowbytes / channels, height, channels, scalewidth, scaleheight, 0);
1780                        buf = NULL;
1781                        picnode = NULL;
1782                }
1783                if(scalebuf != NULL)
1784                {
1785                        buf = scalebuf;
1786                        width = scalewidth;
1787                        height = scaleheight;
1788                        rowbytes = scalewidth * (channels);
1789                }
1790        }
1791
1792        if(width > mwidth) width = mwidth;
1793        if(height > mheight) height = mheight;
1794
1795        if(halign == CENTER)
1796                posx += mwidth / 2 - width / 2;
1797        else if(halign == RIGHT)
1798                posx += mwidth - width;
1799        if(valign == MIDDLE)
1800                posy += mheight / 2 - height / 2;
1801        else if(valign == BOTTOM)
1802                posy += mheight - height;
1803
1804        if(pictype == 0)
1805        {
1806                py = (posy * skinfb->width) + posx;
1807                pyh = py + (height * skinfb->width);
1808                src = buf;
1809                diff = rowbytes - (width * channels);
1810
1811                if(channels == 3)
1812                {
1813                        for(y = py; y < pyh; y += skinfb->width)
1814                        {
1815                                pxw = y + width;
1816                                for(x = y; x < pxw; x++)
1817                                {
1818                                        skinfb->fblong[x] = (255 << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
1819                                        src += 3;
1820                                }
1821                                src += diff;
1822                        }
1823                }
1824                else
1825                {
1826                        for(y = py; y < pyh; y += skinfb->width)
1827                        {
1828                                pxw = y + width;
1829                                for(x = y; x < pxw; x++)
1830                                {
1831                                        if(src[3] < 10)
1832                                        {
1833                                                src += 4;
1834                                                continue;
1835                                        }
1836                                        skinfb->fblong[x] = (src[3] << 24) | (src[0] << 16) | (src[1] << 8) | src[2];
1837                                        src += 4;
1838                                }
1839                                src += diff;
1840                        }
1841                }
1842/*
1843                for (y = 0; y < height; ++y)
1844                {
1845                        py = (posy + y) * skinfb->width;
1846                        src = buf + y * rowbytes;
1847                        for (x = 0; x < width; x++)
1848                        {
1849                                red = *src++;
1850                                green = *src++;
1851                                blue = *src++;
1852                                if(channels == 3)
1853                                        alpha = 255;
1854                                else
1855                                        alpha = *src++;
1856
1857                                if(alpha == 0) continue;
1858                                color = (alpha << 24) | (red << 16) | (green << 8) | blue;
1859                                //if(color & 0xff000000 == 0) continue;
1860                                drawpixelfast(posx + x, py, color);
1861                        }
1862                }
1863*/
1864        }
1865        else if(pictype == 1 && memfd > -1)
1866                blitjpg(buf, posx, posy, width, height, scalewidth, scaleheight );
1867
1868        if(picnode == NULL)
1869        {
1870                if(pictype == 0)
1871                        free(buf);
1872                else if(pictype == 1)
1873                        freebpamem(memfd, buf, width * height * 3);
1874        }
1875       
1876        debug(1000, "out");
1877}
1878
1879//flag 0: don't del outside
1880//flag 1: del outside
1881void drawcircle(int x0, int y0, int radius, int startangle, int endangle, long color, int transparent, char* bg, int flag)
1882{
1883        float d = (5/4.0) - radius, theta;
1884        int x = 0, y = radius, px = 0, py = 0;
1885
1886        transparent = (transparent - 255) * -1;
1887        unsigned long tmpcol = color | ((transparent & 0xff) << 24);
1888
1889        while(y > x)
1890        {
1891                if(d < 0)
1892                        d += 2 * x + 3;
1893                else
1894                {
1895                        d += (2 * x) - (2 * y) + 5;
1896                        y--;
1897                }
1898                x++;
1899
1900                theta = (atan((float)y / x)) * (180 / 3.14);
1901
1902                //rt2
1903                if(theta >= startangle && theta <= endangle)
1904                {
1905                        px = x0 + x;
1906                        py = (y0 - y) * skinfb->width;
1907                        drawpixelfast(px, py, tmpcol);
1908                        if(flag == 1)
1909                        {
1910                                int i = radius - x;
1911                                int r = radius - y;
1912                                for(; i > 0; i--)
1913                                        drawpixelfast(px + i, py, getpixelbuf(bg, x + i - 1, r, radius));
1914                        }
1915                }
1916                //rb2
1917                if(360 - theta >= startangle && 360 - theta <= endangle)
1918                {
1919                        px = x0 + x;
1920                        py = (y0 + y) * skinfb->width;
1921                        drawpixelfast(px, py, tmpcol);
1922                        if(flag == 1)
1923                        {
1924                                int i = radius - x;
1925                                int r = y - 1;
1926                                for(; i > 0; i--)
1927                                        drawpixelfast(px + i, py, getpixelbuf(bg, x + i - 1, r, radius));
1928                        }
1929                }
1930                //rt1
1931                if(90 - theta >= startangle && 90 - theta <= endangle)
1932                {
1933                        px = x0 + y;
1934                        py = (y0 - x) * skinfb->width;
1935                        drawpixelfast(px, py, tmpcol);
1936                        if(flag == 1)
1937                        {
1938                                int i = radius - y;
1939                                int r = radius - x;
1940                                for(; i > 0; i--)
1941                                        drawpixelfast(px + i, py, getpixelbuf(bg, y + i - 1, r, radius));
1942                        }
1943                }
1944                //rb1
1945                if(270 + theta >= startangle && 270 + theta <= endangle)
1946                {
1947                        px = x0 + y;
1948                        py = (y0 + x) * skinfb->width;
1949                        drawpixelfast(px, py, tmpcol);
1950                        if(flag == 1)
1951                        {
1952                                int i = radius - y;
1953                                int r = x - 1;
1954                                for(; i > 0; i--)
1955                                        drawpixelfast(px + i, py, getpixelbuf(bg, y + i - 1, r, radius));
1956                        }
1957                }
1958                //lt2
1959                if(180 - theta >= startangle && 180 - theta <= endangle)
1960                {
1961                        px = x0 - x;
1962                        py = (y0 - y) * skinfb->width;
1963                        drawpixelfast(px, py, tmpcol);
1964                        if(flag == 1)
1965                        {
1966                                int i = radius - x;
1967                                int r = radius - y;
1968                                for(; i > 0; i--)
1969                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - x - i, r, radius));
1970                        }
1971                }
1972                //lb2
1973                if(180 + theta >= startangle && 180 + theta <= endangle)
1974                {
1975                        px = x0 - x;
1976                        py = (y0 + y) * skinfb->width;
1977                        drawpixelfast(px, py, tmpcol);
1978                        if(flag == 1)
1979                        {
1980                                int i = radius - x;
1981                                int r = y - 1;
1982                                for(; i > 0; i--)
1983                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - x - i, r, radius));
1984                        }
1985                }
1986                //lt1
1987                if(90 + theta >= startangle && 90 + theta <= endangle)
1988                {
1989                        px = x0 - y;
1990                        py = (y0 - x) * skinfb->width;
1991                        drawpixelfast(px, py, tmpcol);
1992                        if(flag == 1)
1993                        {
1994                                int i = radius - y;
1995                                int r = radius - x;
1996                                for(; i > 0; i--)
1997                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - y - i, r, radius));
1998                        }
1999                }
2000                //lb1
2001                if(270 - theta >= startangle && 270 - theta <= endangle)
2002                {
2003                        px = x0 - y;
2004                        py = (y0 + x) * skinfb->width;
2005                        drawpixelfast(px, py, tmpcol);
2006                        if(flag == 1)
2007                        {
2008                                int i = radius - y;
2009                                int r = x - 1;
2010                                for(; i > 0; i--)
2011                                        drawpixelfast(px - i, py, getpixelbuf(bg, radius - y - i , r, radius));
2012                        }
2013                }
2014        }
2015}
2016
2017int drawchar(struct font* font, FT_ULong currentchar, int posx, int posy, int mwidth, int height, long color, int transparent, int charspace, int test)
2018{
2019//      debug(1000, "in");
2020        int space = 0, row, pitch, bit, y = 0, x = 0, px = 0, py = 0, pxw = 0, pyh = 0, max = 220, min = 35;
2021        FT_UInt glyphindex;
2022        FT_Vector kerning;
2023        FT_Error ret;
2024        FTC_SBit sbit;
2025        unsigned long tmpcol = 0, tmpcol1 = 0;
2026        long buffercol = 0;
2027        unsigned char red, green, blue, r, g, b;
2028        unsigned char* src = NULL;
2029
2030        if(currentchar == 32) space = 1;
2031
2032        glyphindex = FT_Get_Char_Index(font->face, currentchar);
2033        if(glyphindex == 0)
2034        {
2035                debug(100, "FT_Get_Char_Index for char %x %c failed", (int)currentchar, (int)currentchar);
2036                return 0;
2037        }
2038
2039        FTC_Node anode;
2040        ret = FTC_SBitCache_Lookup(font->cache, &font->desc, glyphindex, &sbit, &anode);
2041
2042        if(ret != 0)
2043        {
2044                err("FTC_SBitCache_Lookup for char %x %c failed. Error: 0x%.2X", (int)currentchar, (int)currentchar, ret);
2045                return 0;
2046        }
2047
2048        if(font->use_kerning)
2049        {
2050                FT_Get_Kerning(font->face, font->prev_glyphindex, glyphindex, ft_kerning_default, &kerning);
2051                font->prev_glyphindex = glyphindex;
2052                kerning.x >>= 6;
2053        }
2054        else
2055                kerning.x = 0;
2056
2057        if (test == 1 || space == 1)
2058        {
2059                //debug(1000, "out -> test or space");
2060                return sbit->xadvance + kerning.x + charspace;
2061        }
2062        if(posx + sbit->xadvance > mwidth)
2063        {
2064                //debug(1000, "out -> text to long");
2065                return -1;
2066        }
2067
2068        if(status.fasttextrender == 1) max = min - 1;
2069       
2070        red = (color & 0xff0000) >> 16;
2071        green = (color & 0x00ff00) >> 8;
2072        blue = color & 0xff;
2073        transparent = transparent & 0xff;
2074        tmpcol = color | transparent << 24;
2075        posy = posy + height - sbit->top;
2076        posx = posx + sbit->left + kerning.x;
2077               
2078        py = (posy * skinfb->width) + posx;
2079        pyh = py + (sbit->height * skinfb->width);
2080        src = sbit->buffer;
2081               
2082        for(y = py; y < pyh; y += skinfb->width)
2083        {
2084                pxw = y + sbit->pitch;
2085                for(x = y; x < pxw; x++)
2086                {
2087                        buffercol = src[0];
2088                        src++;
2089                        if(buffercol)
2090                        {
2091                                //renderquality 255-0 = best
2092                                if(buffercol > max)
2093                                        skinfb->fblong[x] = tmpcol;
2094                                else if(buffercol < min)
2095                                        continue;
2096                                else
2097                                {
2098                                        tmpcol1 = skinfb->fblong[x];
2099                                        alpha_composite(r, red, buffercol, (tmpcol1 & 0xff0000) >> 16);
2100                                        alpha_composite(g, green, buffercol, (tmpcol1 & 0x00ff00) >> 8);
2101                                        alpha_composite(b, blue, buffercol, tmpcol1 & 0xff);
2102                                        skinfb->fblong[x] = transparent << 24 | r << 16 | g << 8 | b;
2103                                }
2104                        }
2105                }
2106        }
2107
2108//      debug(1000, "out");
2109        return sbit->xadvance + kerning.x + charspace;
2110}
2111
2112void getstringwh(struct font* font, char *string, int *stringwidth, int *stringheight, int charspace)
2113{
2114        debug(1000, "in");
2115        FT_ULong cret = 0;
2116        if(string == NULL) return;
2117
2118        while(*string != '\0' && *string != '\n')
2119        {
2120                string += strfreetype(string, &cret);
2121                *stringwidth += drawchar(font, cret, 0, 0, 0, 0, 0, 0, charspace, 1);
2122                string++;
2123        }
2124        debug(1000, "out");
2125}
2126
2127int calcstrhalign(struct font* aktfont, char *string, int posx, int mwidth, int halign, int charspace)
2128{
2129        int stringwidth = 0, stringheight = 0;
2130        if(string == NULL) return 0;
2131
2132        switch(halign)
2133        {
2134                case TEXTCENTER:
2135                case CENTER:
2136                        getstringwh(aktfont, string, &stringwidth, &stringheight, charspace);
2137                        if(stringwidth < mwidth) posx += (mwidth - stringwidth) / 2;
2138                        break;
2139                case TEXTRIGHT:
2140                case RIGHT:
2141                        getstringwh(aktfont, string, &stringwidth, &stringheight, charspace);
2142                        if(stringwidth < mwidth) posx += mwidth - stringwidth;
2143                        break;
2144        }
2145        return posx;
2146}
2147
2148int calcstrvalign(char *string, int posy, int oldposy, int mheight, int fontsize, int linecount, int valign)
2149{
2150        if(string == NULL) return 0;
2151
2152        switch(valign)
2153        {
2154                case TEXTMIDDLE:
2155                case MIDDLE:
2156                        posy += mheight / 2 - (fontsize * linecount) / 2;
2157                        if(posy < oldposy) posy = oldposy;
2158                        break;
2159                case TEXTBOTTOM:
2160                case BOTTOM:
2161                        posy += mheight - (fontsize * linecount);
2162                        if(posy < oldposy) posy = oldposy;
2163                        break;
2164        }
2165
2166        return posy;
2167}
2168
2169struct font* setaktfont(char* fontname, int fontsize)
2170{
2171        struct font* aktfont = NULL;
2172
2173        if(fontname != NULL) aktfont = getfont(fontname);
2174        if(aktfont == NULL) aktfont = font;
2175
2176        aktfont->desc.width = fontsize;
2177        aktfont->desc.height = fontsize;
2178        if(status.fasttextrender == 1)
2179                aktfont->desc.flags = FT_LOAD_MONOCHROME;
2180        else
2181                aktfont->desc.flags = FT_LOAD_DEFAULT;
2182
2183        aktfont->prev_glyphindex = 0;
2184
2185        return aktfont;
2186}
2187
2188void wrapstr(char* string, char* fontname, int fontsize, int mwidth, int charspace)
2189{
2190        int posx = 0;
2191        int stringheight = 0, stringwidth = 0;
2192        struct font* aktfont = NULL;
2193        char* tmpstr = NULL, *origstr = string;
2194        unsigned char c = 0;
2195
2196        aktfont = setaktfont(fontname, fontsize);
2197
2198        while(*string != '\0')
2199        {
2200                stringheight = 0; stringwidth = 0;
2201
2202                tmpstr = string;
2203
2204                while(*string != '\0' && *string != '\n' && *string != ' ' && *string != '-')
2205                        string++;
2206                if(*string == '\n')
2207                {
2208                        if(*string != '\0') string++;
2209                        posx = 0;
2210                }
2211                else
2212                {
2213                        if(*string != '\0') string++;
2214                        c = *string; *string = '\0';
2215
2216                        getstringwh(aktfont, tmpstr, &stringwidth, &stringheight, charspace);
2217                        *string = c;
2218
2219                        posx += stringwidth;
2220                }
2221
2222                if(posx > mwidth && tmpstr > origstr)
2223                {       
2224                        tmpstr--;
2225                        *tmpstr = '\n';
2226                        posx = stringwidth;
2227                }
2228        }
2229}
2230
2231
2232int 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)
2233{
2234        debug(1000, "in");
2235        int charwidth = 0, lineend = 0;
2236        int charcount = 0;
2237        if(lastposy == NULL || *lastposy == 0) posy=posy + FONTPOSYOFFSET;
2238        int oldposx = posx, aktheight = 0, ret = 0;
2239        int oldposy = posy, oldmwidth = mwidth;
2240        struct font* aktfont = NULL;
2241        long tmpcol = color;
2242        FT_ULong cret = 0;
2243
2244        if(string == NULL) return 1;
2245
2246        transparent = (transparent - 255) * -1;
2247
2248        if(linecount < 2 && (fontsize == 0 || fontsize > mheight))
2249                fontsize = mheight;
2250
2251        aktfont = setaktfont(fontname, fontsize);
2252
2253        string = string + poscount;
2254
2255        if(fontsize < 5)
2256        {
2257                debug(1000, "out -> fontsize to small");
2258                return 1;
2259        }
2260
2261        posx = calcstrhalign(aktfont, string, posx, oldmwidth, halign, charspace);
2262        posy = calcstrvalign(string, posy, oldposy, mheight, fontsize, linecount, valign);
2263
2264        mwidth = posx + mwidth;
2265        aktheight += fontsize;
2266        if(aktheight > mheight)
2267        {
2268                debug(1000, "out -> to many textlines");
2269                return 1;
2270        }
2271
2272        while(*string != '\0')
2273        {
2274                charcount++;
2275                if(markpos == charcount)
2276                        color = convertcol("markcol");
2277                else
2278                        color = tmpcol;
2279
2280                if(*string == '\n')
2281                {
2282                        if(linecount < 2) break;
2283                        lineend = 0;
2284                        aktheight += fontsize;
2285                        if(aktheight > mheight)
2286                        {
2287                                ret = 1;
2288                                break;
2289                        }
2290                        posy = posy + fontsize;
2291                        posx = oldposx;
2292                        string++;
2293                        posx = calcstrhalign(aktfont, string, posx, oldmwidth, halign, charspace);
2294                        continue;
2295                }
2296
2297                if(lineend == 1)
2298                {
2299                        string++;
2300                        continue;
2301                }
2302
2303                string += strfreetype(string, &cret);
2304
2305                if((charwidth = drawchar(aktfont, cret, posx, posy, mwidth, fontsize, color, transparent, charspace, 0)) == -1)
2306                        lineend = 1;
2307
2308                posx += charwidth;
2309                if(len != NULL) *len += charwidth;
2310                string++;
2311        }
2312        if(lastposx != NULL) *lastposx = posx;
2313        if(lastposy != NULL) *lastposy = posy + fontsize;
2314        debug(1000, "out");
2315        return ret;
2316}
2317
2318char* saverect(int posx, int posy, int width, int height)
2319{
2320        debug(1000, "in");
2321        char* buf;
2322        int y;
2323
2324        buf = malloc(width * height * skinfb->colbytes);
2325        if(buf == NULL)
2326        {
2327                err("no memory");
2328                return NULL;
2329        }
2330
2331        for(y = 0; y < height; y++)
2332        {
2333                memcpy(buf + width * skinfb->colbytes * y, skinfb->fb + ((y + posy) * skinfb->pitch) + (posx * skinfb->colbytes), width * skinfb->colbytes);
2334        }
2335
2336        debug(1000, "out");
2337        return buf;
2338}
2339
2340char* savescreen(struct skin* node)
2341{
2342        return saverect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth + (node->shadowsize * 2), node->rheight + (node->shadowsize * 2));
2343}
2344
2345void restorerect(char* buf, int posx, int posy, int width, int height)
2346{
2347        debug(1000, "in");
2348        int y;
2349
2350        if(buf != NULL)
2351        {
2352                for(y = 0; y < height; y++)
2353                {
2354                        memcpy(skinfb->fb + ((y + posy) * skinfb->pitch) + (posx * skinfb->colbytes), buf + width * skinfb->colbytes * y,  width * skinfb->colbytes);
2355                }
2356                free(buf);
2357                buf = NULL;
2358        }
2359        debug(1000, "out");
2360}
2361
2362void restorescreen(char* buf, struct skin* node)
2363{
2364        restorerect(buf, node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth + (node->shadowsize * 2), node->rheight + (node->shadowsize * 2));
2365}
2366
2367//*************** GOST LCD
2368void lcd_fillrect(int posx, int posy, int width, int height, long color, int transparent)
2369{
2370        //debug(1000, "in");
2371        int y, x;
2372        unsigned long tmpcol;
2373
2374        if(posx < 0) posx = 0;
2375        if(posx > skinfb->width) posx = skinfb->width;
2376        if(posy < 0) posy = 0;
2377        if(posy > skinfb->height) posy = skinfb->height;
2378        if(posx + width > skinfb->width) width = skinfb->width - posx;
2379        if(posy + height > skinfb->height) height = skinfb->height - posy;
2380
2381        if(width <= 0 || height <= 0) return;
2382
2383        transparent = (transparent - 255) * -1;
2384        tmpcol = color | ((transparent & 0xff) << 24);
2385
2386        for(y = 0; y < height; y++)
2387        {
2388                for(x = 0; x < width; x++)
2389                {
2390                        drawpixel(posx + x, posy + y, tmpcol);
2391                }
2392        }
2393        //debug(1000, "out");
2394}
2395
2396void lcd_drawrect(int posx, int posy, int width, int height, long color, int transparent)
2397{
2398        //debug(1000, "in");
2399        fillrect(posx, posy, width, 1, color, transparent);
2400        fillrect(posx, posy + height - 1, width, 1, color, transparent);
2401        fillrect(posx, posy, 1, height, color, transparent);
2402        fillrect(posx + width - 1, posy, 1, height, color, transparent);
2403        //debug(1000, "out");
2404}
2405//*************** GOST LCD
2406
2407/*
2408void fillrect(int posx, int posy, int width, int height, long color, int transparent)
2409{
2410        int r, g, b;
2411
2412        r = (color >> 16) & 0xFF;
2413        g = (color >> 8) & 0xFF;
2414        b = color & 0xFF;
2415
2416        primary->SetDrawingFlags(primary, DSDRAW_NOFX);
2417        primary->SetColor(primary, r, g, b, transparent);
2418        primary->FillRectangle(primary, posx, posy, width, height);
2419        primary->Flip(primary, NULL, DSFLIP_WAITFORSYNC);
2420}
2421
2422void drawrect(int posx, int posy, int width, int height, long color, int transparent)
2423{
2424        int r, g, b;
2425
2426        r = (color >> 16) & 0xFF;
2427        g = (color >> 8) & 0xFF;
2428        b = color & 0xFF;
2429
2430        primary->SetDrawingFlags(primary, DSDRAW_NOFX);
2431        primary->SetColor(primary, r, g, b, transparent);
2432        primary->DrawRectangle(primary, posx, posy, width, height);
2433        primary->Flip(primary, NULL, DSFLIP_WAITFORSYNC);
2434}
2435*/
2436
2437void fillrect(int posx, int posy, int width, int height, long color, int transparent)
2438{
2439        if(skinfb != lcdskinfb)
2440                blitrect(posx, posy, width, height, color, transparent, 0);
2441        else
2442                lcd_fillrect(posx, posy, width, height, color, transparent);
2443}
2444
2445void drawrect(int posx, int posy, int width, int height, long color, int transparent)
2446{
2447        if(skinfb != lcdskinfb)
2448                blitrect(posx, posy, width, height, color, transparent, 1);
2449        else
2450                lcd_drawrect(posx, posy, width, height, color, transparent);
2451}
2452
2453void clearrect(int posx, int posy, int width, int height)
2454{
2455        fillrect(posx, posy, width, height, 0, 255);
2456}
2457
2458void clearscreen(struct skin* node)
2459{
2460        m_lock(&status.drawingmutex, 0);
2461        clearrect(node->rposx, node->rposy, node->rwidth, node->rheight);
2462        clearshadow(node);
2463        m_unlock(&status.drawingmutex, 0);
2464}
2465
2466void clearscreennolock(struct skin* node)
2467{
2468        clearrect(node->rposx, node->rposy, node->rwidth, node->rheight);
2469        clearshadow(node);
2470}
2471
2472//flag 0 = horizontal
2473//flag 1 = vertical
2474//flag 2 = horizontal (begin to middle, middle to end)
2475//flag 3 = vertical (begin to middle, middle to end)
2476void drawgradient(int posx, int posy, int width, int height, long col1, long col2, int transparent, int flag)
2477{
2478        int p, i, x, y, steps, xstep, ystep;
2479        int xcount = 0, ycount = 0, owidth = width, oheight = height;
2480        unsigned char r3, g3, b3;
2481        unsigned long col = 0;
2482
2483        transparent = (transparent - 255) * -1;
2484
2485        if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
2486        {
2487                if(flag == LEFTMIDDLE) width = width / 2;
2488                if(width < 100)
2489                        steps = width;
2490                else
2491                        steps = width / 5;
2492                xstep = width / steps;
2493                ystep = height;
2494        }
2495        else
2496        {
2497                if(flag == TOPMIDDLE) height = height / 2;
2498                if(height < 100)
2499                        steps = height;
2500                else
2501                        steps = height / 5;
2502                xstep = width;
2503                ystep = height / steps;
2504        }
2505
2506        unsigned char r1 = (col1 >> 16) & 0xff;
2507        unsigned char g1 = (col1 >> 8) & 0xff;
2508        unsigned char b1 = col1 & 0xff;
2509
2510        unsigned char r2 = (col2 >> 16) & 0xff;
2511        unsigned char g2 = (col2 >> 8) & 0xff;
2512        unsigned char b2 = col2 & 0xff;
2513
2514        for(i = 0; i < steps; i++)
2515        {
2516                p = steps - i;
2517                r3 = (r1 * p + r2 * i) / steps;
2518                g3 = (g1 * p + g2 * i) / steps;
2519                b3 = (b1 * p + b2 * i) / steps;
2520                col = (transparent << 24) | (r3 << 16) | (g3 << 8) | b3;
2521               
2522                for(y = 0; y < ystep; y++)
2523                        for(x = 0; x < xstep; x++)
2524                                drawpixel(posx + x, posy + y, col);
2525
2526                if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
2527                {
2528                        posx += xstep;
2529                        xcount += xstep;
2530                }
2531                else
2532                {
2533                        posy += ystep;
2534                        ycount += ystep;
2535                }
2536        }
2537
2538        if(flag == LEFTMIDDLE || flag == TOPMIDDLE)
2539        {
2540                for(i = 0; i < steps; i++)
2541                {
2542                        p = steps - i;
2543                        r3 = (r2 * p + r1 * i) / steps;
2544                        g3 = (g2 * p + g1 * i) / steps;
2545                        b3 = (b2 * p + b1 * i) / steps;
2546                        col = (transparent << 24) | (r3 << 16) | (g3 << 8) | b3;
2547               
2548                        for(y = 0; y < ystep; y++)
2549                                for(x = 0; x < xstep; x++)
2550                                        drawpixel(posx + x, posy + y, col);
2551                        if(flag == LEFTMIDDLE)
2552                        {
2553                                posx += xstep;
2554                                xcount += xstep;
2555                        }
2556                        else
2557                        {
2558                                posy += ystep;
2559                                ycount += ystep;
2560                        }
2561                }
2562        }
2563
2564        if(flag == LEFTRIGHT || flag == LEFTMIDDLE)
2565        {
2566                if(owidth > xcount)
2567                {
2568                        for(y = 0; y < ystep; y++)
2569                                for(x = 0; x < (owidth - xcount); x++)
2570                                        drawpixel(posx + x, posy + y, col);
2571                }
2572        }
2573        if(flag == TOPBOTTOM || flag == TOPMIDDLE)
2574        {
2575                if(oheight > ycount)
2576                {
2577                        for(y = 0; y < (oheight - ycount); y++)
2578                                for(x = 0; x < xstep; x++)
2579                                        drawpixel(posx + x, posy + y, col);
2580                }
2581        }
2582}
2583
2584void drawtitlebggradient(struct skin* node)
2585{
2586        debug(1000, "in");
2587        if(status.picbordersize > 0)
2588                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);
2589        else
2590                drawgradient(node->rposx, node->rposy, node->rwidth, node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->titlebgcol2, node->transparent, node->titlegradient);
2591        debug(1000, "out");
2592}
2593
2594void drawbggradient(struct skin* node)
2595{
2596        debug(1000, "in");
2597        drawgradient(node->rposx, node->rposy, node->rwidth, node->rheight, node->bgcol, node->bgcol2, node->transparent, node->gradient);
2598        debug(1000, "out");
2599}
2600
2601void drawtitlebgcol(struct skin* node)
2602{
2603        debug(1000, "in");
2604        if(status.picbordersize > 0)
2605                fillrect(node->rposx + status.picbordersize, node->rposy + status.picbordersize, node->rwidth - (status.picbordersize * 2), node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->transparent);
2606        else
2607                fillrect(node->rposx, node->rposy, node->rwidth, node->rheight - (node->rheight - node->titlesize), node->titlebgcol, node->transparent);
2608        debug(1000, "out");
2609}
2610
2611void drawbginnercol(struct skin* node)
2612{
2613        debug(1000, "in");
2614        fillrect(node->rposx + node->bordersize, node->rposy + node->bordersize, node->rwidth - node->bordersize * 2, node->rheight - node->bordersize * 2, node->bgcol, node->transparent);
2615        debug(1000, "out");
2616}
2617
2618void drawbgcol(struct skin* node)
2619{
2620        debug(1000, "in");
2621        fillrect(node->rposx + node->bgspace, node->rposy + node->bgspace, node->rwidth - (node->bgspace * 2), node->rheight - (node->bgspace * 2), node->bgcol, node->transparent);
2622        debug(1000, "out");
2623}
2624
2625void drawtitle(struct skin* node)
2626{
2627        debug(1000, "in");
2628        if(status.titlelinesize > 0)
2629                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);
2630        else
2631                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);
2632        if(status.titlelinesize > 0)
2633                fillrect(node->rposx, node->rposy + node->titlesize + status.picbordersize, node->rwidth, status.titlelinesize, node->bordercol, node->transparent);
2634        else if(node->bordersize > 0)
2635                fillrect(node->rposx, node->rposy + node->titlesize, node->rwidth, node->bordersize, node->bordercol, node->transparent);
2636        debug(1000, "out");
2637}
2638
2639void drawprogressbar(struct skin* node)
2640{
2641        debug(1000, "in");
2642        int val = 0;
2643
2644        if(node->progresssize > 100) node->progresssize = 100;
2645        val = ((float)node->iwidth / 100) * node->progresssize;
2646        fillrect(node->rposx + node->bordersize, node->rposy + node->bordersize, val, node->iheight, node->progresscol, node->transparent);
2647        debug(1000, "out");
2648}
2649
2650void drawmultiprogressbar(struct skin* node)
2651{
2652        debug(1000, "in");
2653        struct epgrecord* epgrecord = node->epgrecord;
2654        int val1 = 0, val2 = 0;
2655
2656        while(epgrecord != NULL)
2657        {
2658               
2659                if(epgrecord->posx > 100) epgrecord->posx = 100;
2660                val1 = ((float)node->iwidth / 100) * epgrecord->posx;
2661                if(epgrecord->size > 100) epgrecord->size = 100;
2662                val2 = ((float)node->iwidth / 100) * epgrecord->size;
2663
2664                if(val2 > val1)
2665                        fillrect(node->rposx + node->bordersize + val1, node->rposy + node->bordersize, val2 - val1, node->iheight, node->progresscol, node->transparent);
2666                epgrecord = epgrecord->next;
2667        }
2668        debug(1000, "out");
2669}
2670
2671void drawroundborder(struct skin* node, char* bglt, char* bglb, char* bgrt, char* bgrb)
2672{
2673        int i, rad = status.borderradius;
2674
2675        if(node->borderradius > 0) rad = node->borderradius;
2676        if(rad > node->rheight / 2) rad = node->rheight / 2;
2677        int tmpbordersize = rad - node->bordersize;
2678
2679        //left - top
2680        for(i = rad; i > tmpbordersize; i--)
2681                drawcircle(node->rposx + rad, node->rposy + rad, i, 90, 180, node->bordercol, node->transparent, bglt, i == rad);
2682        //left - bottom
2683        for(i = rad; i > tmpbordersize; i--)
2684                drawcircle(node->rposx + rad, node->rposy + node->rheight - 1 - rad, i, 180, 270, node->bordercol, node->transparent, bglb, i == rad);
2685        //right - top
2686        for(i = rad; i > tmpbordersize; i--)
2687                drawcircle(node->rposx + node->rwidth - 1 - rad, node->rposy + rad, i, 0, 90, node->bordercol, node->transparent, bgrt, i == rad);
2688        //right - bottom
2689        for(i = rad; i > tmpbordersize; i--)
2690                drawcircle(node->rposx + node->rwidth - 1 - rad, node->rposy + node->rheight - 1 - rad, i, 270, 360, node->bordercol, node->transparent, bgrb, i == rad);
2691}
2692
2693//TODO: not full implemented
2694void drawpicborder(struct skin* node)
2695{
2696        debug(1000, "in");
2697        int borderwidth = status.picbordersize;
2698        int borderheight = status.picbordersize;
2699
2700        //top-left
2701        //drawpic("/home/nit/titan/skin/bs_tl.png", node->rposx + node->bordersize - borderwidth, node->rposy + node->bordersize - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP);
2702        drawpic("/home/nit/titan/skin/bs_tl.png", node->rposx, node->rposy, 0, 0, borderwidth, borderheight, LEFT, TOP);
2703        //top-right
2704        //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);
2705        drawpic("/home/nit/titan/skin/bs_tr.png", node->rposx + node->rwidth - borderwidth, node->rposy, 0, 0, borderwidth, borderheight, LEFT, TOP);
2706        //bottom-left
2707        //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);
2708        drawpic("/home/nit/titan/skin/bs_bl.png", node->rposx, node->rposy + node->rheight - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP);
2709        //bottom-right
2710        //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);
2711        drawpic("/home/nit/titan/skin/bs_br.png", node->rposx + node->rwidth - borderwidth, node->rposy + node->rheight - borderheight, 0, 0, borderwidth, borderheight, LEFT, TOP);
2712
2713        //top
2714        //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);
2715        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);
2716        //bottom
2717        //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);
2718        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);
2719        //left
2720        //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);
2721        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);
2722        //right
2723        //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);
2724        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);
2725        debug(1000, "out");
2726}
2727
2728void drawborder(struct skin* node)
2729{
2730        debug(1000, "in");
2731        if(node->bordersize == 1 && node->rheight > 2 && node->bordertype == 0)
2732                drawrect(node->rposx, node->rposy, node->rwidth, node->rheight, node->bordercol, node->transparent);
2733        else if(node->bordersize == 1 && node->rheight <= 2 && node->bordertype == 0)
2734                fillrect(node->rposx, node->rposy, node->rwidth, node->rheight, node->bordercol, node->transparent);
2735        else
2736        {
2737                if(node->bordertype == 0 || checkbit(node->bordertype, 0) == 1)
2738                        fillrect(node->rposx, node->rposy, node->rwidth, node->bordersize, node->bordercol, node->transparent);
2739                if(node->bordertype == 0 || checkbit(node->bordertype, 1) == 1)
2740                        fillrect(node->rposx, node->rposy + node->rheight - node->bordersize, node->rwidth, node->bordersize, node->bordercol, node->transparent);
2741                if(node->bordertype == 0 || checkbit(node->bordertype, 2) == 1)
2742                        fillrect(node->rposx, node->rposy, node->bordersize, node->rheight, node->bordercol, node->transparent);
2743                if(node->bordertype == 0 || checkbit(node->bordertype, 3) == 1)
2744                        fillrect(node->rposx + node->rwidth - node->bordersize, node->rposy, node->bordersize, node->rheight, node->bordercol, node->transparent);
2745        }
2746        debug(1000, "out");
2747}
2748
2749void drawscrollbar(struct skin* node)
2750{
2751        debug(1000, "in");
2752        if(node->bordersize == 0)
2753                drawrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy, node->scrollbarwidth, node->iheight, node->bordercol, node->transparent);
2754        else
2755                fillrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy, node->scrollbarbordersize, node->iheight, node->bordercol, node->transparent);
2756
2757        fillrect(node->rposx + node->rwidth - node->bordersize - node->scrollbarwidth, node->iposy + node->scrollbarpos, node->scrollbarwidth, node->scrollbarheight, node->bordercol, node->transparent);
2758        debug(1000, "out");
2759}
2760
2761void clearshadow(struct skin* node)
2762{
2763        debug(1000, "in");
2764
2765        if(node->shadowsize < 1) return;
2766        switch(node->shadowpos)
2767        {
2768                case BOTTOMLEFT:
2769                clearrect(node->rposx - node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize);
2770                clearrect(node->rposx - node->shadowsize, node->rposy + node->shadowsize, node->shadowsize, node->rheight);
2771                break;
2772                case BOTTOMRIGHT:
2773                clearrect(node->rposx + node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize);
2774                clearrect(node->rposx + node->rwidth, node->rposy + node->shadowsize, node->shadowsize, node->rheight);
2775                break;
2776                case TOPLEFT:
2777                clearrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize);
2778                clearrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->shadowsize, node->rheight);
2779                break;
2780                default:
2781                clearrect(node->rposx + node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize);
2782                clearrect(node->rposx + node->rwidth, node->rposy - node->shadowsize, node->shadowsize, node->rheight);
2783                break;
2784        }
2785        debug(1000, "out");
2786}
2787
2788void drawshadow(struct skin* node)
2789{
2790        debug(1000, "in");
2791        switch(node->shadowpos)
2792        {
2793                case BOTTOMLEFT:
2794                fillrect(node->rposx - node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
2795                fillrect(node->rposx - node->shadowsize, node->rposy + node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
2796                break;
2797                case BOTTOMRIGHT:
2798                fillrect(node->rposx + node->shadowsize, node->rposy + node->rheight, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
2799                fillrect(node->rposx + node->rwidth, node->rposy + node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
2800                break;
2801                case TOPLEFT:
2802                fillrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
2803                fillrect(node->rposx - node->shadowsize, node->rposy - node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
2804                break;
2805                default:
2806                fillrect(node->rposx + node->shadowsize, node->rposy - node->shadowsize, node->rwidth, node->shadowsize, node->shadowcol, node->transparent);
2807                fillrect(node->rposx + node->rwidth, node->rposy - node->shadowsize, node->shadowsize, node->rheight, node->shadowcol, node->transparent);
2808                break;
2809        }
2810        debug(1000, "out");
2811}
2812
2813//flag 0: del background
2814//flag 1: don't del background
2815void drawnode(struct skin* node, int flag)
2816{
2817        long color = 0, color2 = 0;
2818        int len = 0;
2819        char* bglt = NULL, *bglb = NULL, *bgrt = NULL, *bgrb = NULL;
2820
2821        debug(1000, "in");
2822       
2823        node->flag = setbit(node->flag, 0);
2824
2825        if(node->bordersize > 0)
2826        {
2827                if((node->child != NULL && status.borderradius > 0) || node->borderradius > 0)
2828                {
2829                        int rad = status.borderradius;
2830
2831                        if(node->borderradius > 0) rad = node->borderradius;
2832                        if(rad > node->rheight / 2) rad = node->rheight / 2;
2833
2834                        bglt = saverect(node->rposx, node->rposy, rad, rad);
2835                        bglb = saverect(node->rposx, node->rposy + node->rheight - rad, rad, rad);
2836                        bgrt = saverect(node->rposx + node->rwidth - rad, node->rposy, rad, rad);
2837                        bgrb = saverect(node->rposx + node->rwidth - rad, node->rposy + node->rheight - rad, rad, rad);
2838                }
2839        }
2840
2841        if(flag == 0 && node->bgcol == -1)
2842        {
2843                if(node->child != NULL && status.picbordersize > 0)
2844                {
2845                        clearrect(node->rposx + node->bordersize, node->rposy + node->bordersize, node->rwidth - node->bordersize * 2, node->rheight - node->bordersize * 2);
2846                }
2847                else
2848                        clearscreennolock(node);
2849        }
2850
2851        if(node->deaktivcol > -1)
2852        {
2853                color = node->deaktivcol;
2854                color2 = node->deaktivcol;
2855        }
2856        else
2857        {
2858                color = node->fontcol;
2859                color2 = node->fontcol2;
2860        }
2861
2862        if(node->shadowsize > 0)
2863                drawshadow(node);
2864        if(node->bgcol > -1)
2865        {
2866                if(node->child != NULL && status.picbordersize > 0)
2867                        drawbginnercol(node);
2868                else
2869                        drawbgcol(node);
2870        }
2871        if(node->gradient > 0)
2872                drawbggradient(node);
2873        if(node->titlebgcol > -1)
2874                drawtitlebgcol(node);
2875        if(node->titlegradient > 0)
2876                drawtitlebggradient(node);
2877        if(node->progresssize > 0)
2878                drawprogressbar(node);
2879        if(node->type & MULTIPROGRESSBAR)
2880                drawmultiprogressbar(node);
2881        if(node->selectpic != NULL && !(node->type & FILELIST))
2882                drawpic(node->selectpic, node->iposx, node->iposy, node->rpicwidth, node->rpicheight, node->iwidth, node->iheight, CENTER, MIDDLE);
2883        if(node->pic != NULL && !(node->type & FILELIST))
2884                drawpic(node->pic, node->iposx, node->iposy, node->rpicwidth, node->rpicheight, node->iwidth, node->iheight, node->halign, node->valign);
2885        if(node->input != NULL)
2886        {
2887                if(node->type & CHOICEBOX)
2888                        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);
2889                if((node->type & INPUTBOX) || (node->type & INPUTBOXNUM))
2890                        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);
2891        }
2892        if(node->text != NULL)
2893        {
2894                if(node->type & TEXTBOX)
2895                {
2896                        int lastposy = 0;
2897                        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);
2898                        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);
2899                }
2900                else
2901                {
2902                        int lastposx = 0;
2903                        if(node->textposx2 > 0)
2904                                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);
2905                        else
2906                                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);
2907                        if(node->textposx2 > 0)
2908                                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);
2909                        else
2910                                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);
2911                }
2912        }
2913        if(status.filelistextend > 2 && node->filelist != NULL)
2914        {
2915                char* tmpnr = NULL;
2916
2917                if(status.filelistextend == 3)
2918                {
2919                        if(node->filelist->size >= 1073741824)
2920                        {
2921                                tmpnr = oftoa64((double)node->filelist->size / 1073741824, "2");
2922                                tmpnr = ostrcat(tmpnr, "G", 1, 0);
2923                        }
2924                        else if(node->filelist->size >= 1048576)
2925                        {
2926                                tmpnr = oftoa64((double)node->filelist->size / 1048576, "2");
2927                                tmpnr = ostrcat(tmpnr, "M", 1, 0);
2928                        }
2929                        else if(node->filelist->size >= 1024)
2930                        {
2931                                tmpnr = oftoa64((double)node->filelist->size / 1024, "2");
2932                                tmpnr = ostrcat(tmpnr, "K", 1, 0);
2933                        }
2934                        else
2935                        {
2936                                tmpnr = oitoa64(node->filelist->size);
2937                                tmpnr = ostrcat(tmpnr, "B", 1, 0);
2938                        }
2939                }
2940                if(status.filelistextend == 4)
2941                {
2942                        tmpnr = malloc(MINMALLOC);
2943                        if(tmpnr == NULL)
2944                        {
2945                                err("no mem");
2946                                return;
2947                        }
2948
2949                        struct tm* loctime = olocaltime(&node->filelist->date);
2950                        if(loctime != NULL)
2951                                strftime(tmpnr, MINMALLOC, "%H:%M %d-%m-%Y", loctime);
2952                        free(loctime);
2953                }
2954                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);
2955                free(tmpnr);
2956        }
2957        if(node->title != NULL)
2958                drawtitle(node);
2959        if(node->scrollbar == YES || node->scrollbar == AUTOYES)
2960                drawscrollbar(node);
2961        if(node->bordersize > 0)
2962        {
2963                if(node->child != NULL && status.picbordersize > 0)
2964                        drawpicborder(node);
2965                else
2966                        drawborder(node);
2967                if((node->child != NULL && status.borderradius > 0) || node->borderradius > 0)
2968                        drawroundborder(node, bglt, bglb, bgrt, bgrb);
2969        }
2970
2971        free(bglt); free(bglb); free(bgrt); free(bgrb);
2972        debug(1000, "out");
2973}
2974
2975void calcscrollbar(struct skin* node)
2976{
2977        debug(1000, "in");
2978
2979        node->scrollbarheight = node->iheight;
2980
2981        if(node->pagecount > 1)
2982        {
2983                node->scrollbarheight = (float)node->iheight / node->pagecount;
2984                node->scrollbarpos = ((float)node->iheight / node->pagecount) * (node->aktpage - 1);
2985                if(node->scrollbar == AUTONO) node->scrollbar = AUTOYES;
2986        }
2987        else if(node->scrollbar == AUTOYES)
2988                node->scrollbar = AUTONO;
2989
2990        if(node->scrollbar == YES || node->scrollbar == AUTOYES)
2991        {
2992                node->iwidth -= (SCROLLBARWIDTH + 5);
2993                node->scrollbarwidth = SCROLLBARWIDTH;
2994                node->scrollbarbordersize = SCROLLBARBORDERSIZE;
2995                if(node->iposy + node->scrollbarpos > node->iposy + node->iheight) node->scrollbarpos = node->iposy + node->iheight;
2996                if(node->scrollbarpos < 0) node->scrollbarpos = 0;
2997                if(node->iposy + node->scrollbarpos + node->scrollbarheight > node->iposy + node->iheight) node->scrollbarheight = node->iheight - node->scrollbarpos;
2998                if(node->scrollbarheight < 1) node->scrollbarheight = 1;
2999        }
3000        debug(1000, "out");
3001}
3002
3003void calclistboxchild(struct skin* node, struct skin* parent)
3004{
3005        if((parent->type & GRID) && (node->type & GRIDBR))
3006        {
3007                if(parent->poscount > 0) parent->poscount += node->rheight;
3008                if(parent->poscount == 0) parent->poscount = 1;
3009        }
3010        node->rposy = node->rposy + parent->poscount;
3011        node->iposy = node->iposy + parent->poscount;
3012        if((parent->type & LISTBOX) || ((parent->type & FILELIST) && !(parent->type & GRID)))
3013                parent->poscount += node->rheight;
3014}
3015
3016int calclistbox(struct skin* node)
3017{
3018        debug(1000, "in");
3019        struct skin* child = NULL, *last = NULL, *found = NULL;
3020        int selcol = convertcol("listboxselect");
3021        int markcol = convertcol("markcol");
3022        char* selectpic = getskinconfig("selectpic", NULL);
3023
3024        node->poscount = 0;
3025        if(node->aktline == 0) node->aktline = 1;
3026        node->pagecount = 1;
3027        node->linecount = 0;
3028
3029        child = node->next;
3030        while(child != NULL)
3031        {
3032                if(child->parentpointer == NULL)
3033                {
3034                        if(child->parent == NULL)
3035                        {
3036                                child = child->next;
3037                                continue;
3038                        }
3039                        else if(ostrcmp(child->parent, node->name) != 0 || child->hidden == YES || child->locked == YES)
3040                        {
3041                                child = child->next;
3042                                continue;
3043                        }
3044                }
3045                else if(child->parentpointer != node || child->hidden == YES || child->locked == YES)
3046                {
3047                        child = child->next;
3048                        continue;
3049                }
3050
3051                calcrheight(child, node);
3052
3053                if((node->type & LISTBOX) || ((node->type & FILELIST) && !(node->type & GRID)) || ((node->type & GRID) && (child->type & GRIDBR)))
3054                        node->poscount = node->poscount + child->posy + child->rheight;
3055
3056                if(node->poscount > node->iheight)
3057                {
3058                        node->pagecount++;
3059                        node->poscount = child->rheight;
3060                }
3061
3062                child->pagecount = node->pagecount;
3063
3064                if(child->deaktivcol > -1)
3065                {
3066                        child = child->next;
3067                        continue;
3068                }
3069
3070                node->linecount++;
3071                last = child;
3072
3073                if(node->aktline == -1 && child->pagecount == node->aktpage)
3074                        node->aktline = node->linecount;
3075
3076                if(node->aktline == node->linecount)
3077                        found = child;
3078
3079                child->bordersize = 0;
3080                if(status.listboxselecttype == 3)
3081                {
3082                        changeselectpic(child, NULL);
3083                        if(child->bgcol == markcol)
3084                                child->bgcol = child->bordercol;
3085                }
3086                if(child->bgcol == selcol) //&& status.listboxselecttype == 1)
3087                        child->bgcol = child->bordercol;
3088                if(child->fontcol == selcol) //&& status.listboxselecttype == 2)
3089                        child->fontcol = child->bordercol;
3090
3091                child = child->next;
3092        }
3093
3094        if(found == NULL)
3095        {
3096                found = last;
3097                node->aktline = node->linecount;
3098        }
3099       
3100        if(found != NULL)
3101        {
3102                if(node->aktline == -2) node->aktline = node->linecount;
3103                if(status.listboxselecttype == 0)
3104                {
3105                        found->bordersize = 1;
3106                        if(status.markmodus > 0)
3107                                found->bordercol = markcol;
3108                        else
3109                                found->bordercol = selcol;
3110                }
3111                else if(status.listboxselecttype == 1)
3112                {
3113                        if(found->bgcol != selcol && found->bgcol != markcol)
3114                                found->bordercol = found->bgcol;
3115                        if(status.markmodus > 0)
3116                                found->bgcol = markcol;
3117                        else
3118                                found->bgcol = selcol;
3119                }
3120                else if(status.listboxselecttype == 2)
3121                {
3122                        if(found->fontcol != selcol && found->fontcol != markcol)
3123                                found->bordercol = found->fontcol;
3124                        if(status.markmodus > 0)
3125                                found->fontcol = markcol;
3126                        else
3127                                found->fontcol = selcol;
3128                }
3129                else if(status.listboxselecttype == 3)
3130                {
3131                        changeselectpic(found, selectpic);
3132                        if(found->bgcol != markcol)
3133                                found->bordercol = found->bgcol;
3134                        if(status.markmodus > 0)
3135                                found->bgcol = markcol;
3136                }
3137
3138                if(node->aktpage == -1)
3139                        node->aktpage = found->pagecount;
3140                node->select = found;
3141        }
3142
3143        if(node->aktpage == -1) node->aktpage = 0;
3144        if(node->aktpage > node->pagecount)
3145        {
3146                if(node->pagecount == 0) node->aktpage = 0;
3147                else node->aktpage = 1;
3148        }
3149        node->poscount = 0;
3150        debug(1000, "out");
3151        return 0;
3152}
3153
3154int calcrwidth(struct skin* node, struct skin* parent)
3155{
3156        int scrollbarwidth = 0;
3157
3158        if(node->prozwidth == 1)
3159                node->rwidth = ((float)parent->iwidth / 100) * node->width;
3160        else
3161                node->rwidth = node->width;
3162
3163        if(node->scrollbar == YES || node->scrollbar == AUTOYES || node->scrollbar == AUTONO) scrollbarwidth = SCROLLBARWIDTH;
3164
3165        if(node->rwidth < (node->bordersize * 2) + scrollbarwidth) node->rwidth = (node->bordersize * 2) + scrollbarwidth;
3166
3167        return 0;
3168}
3169
3170int calcrheight(struct skin* node, struct skin* parent)
3171{
3172        if(node->prozheight == 1)
3173                node->rheight = ((float)parent->iheight / 100) * node->height;
3174        else
3175        {
3176                node->rheight = node->height;
3177                if(node->fontsize == 0) node->fontsize = parent->fontsize;
3178                if(node->fontsize == 0) node->fontsize = 1;
3179                if(node->rheight == 0) node->rheight = node->fontsize + 2;
3180        }
3181
3182        if(node->rheight < (node->bordersize * 2) + node->titlesize) node->rheight = (node->bordersize * 2) + node->titlesize;
3183
3184        return 0;
3185}
3186
3187int calcrposx(struct skin* node, struct skin* parent)
3188{
3189        if(node->prozposx == 1)
3190                node->rposx = ((float)parent->iwidth / 100) * node->posx;
3191        else
3192                node->rposx = node->posx;
3193
3194        if(node->posx == CENTER || (node->posx == 0 && parent->halign == CENTER))
3195                node->rposx = parent->iposx + parent->iwidth / 2 - node->rwidth / 2;
3196        else if(node->posx == LEFT)
3197                node->rposx = parent->iposx;
3198        else if(node->posx == RIGHT || (node->posx == 0 && parent->halign == RIGHT))
3199                node->rposx = parent->iposx + parent->iwidth - node->rwidth;
3200        else
3201                node->rposx = parent->iposx + node->rposx;
3202
3203        if(node->rposx > parent->iposx + parent->iwidth)
3204                node->rposx = parent->iposx + parent->iwidth;
3205
3206        return 0;
3207}
3208
3209int calcrposy(struct skin* node, struct skin* parent)
3210{
3211        if(node->prozposy == 1)
3212                node->rposy = ((float)parent->iheight / 100) * node->posy;
3213        else
3214                node->rposy = node->posy;
3215
3216        if(node->posy == MIDDLE || (node->posy == 0 && parent->valign == MIDDLE))
3217                node->rposy = parent->iposy + parent->iheight / 2 - node->rheight / 2;
3218        else if(node->posy == TOP)
3219                node->rposy = parent->iposy;
3220        else if(node->posy == BOTTOM || (node->posy ==0 && parent->valign == BOTTOM))
3221                node->rposy = parent->iposy + parent->iheight - node->rheight;
3222        else
3223                node->rposy = parent->iposy + node->rposy;
3224
3225        if(node->rposy > parent->iposy + parent->iheight)
3226                node->rposy = parent->iposy + parent->iheight;
3227
3228        return 0;
3229}
3230
3231int setnodeattr(struct skin* node, struct skin* parent)
3232{
3233        if(node != skin) node->flag = clearbit(node->flag, 0);
3234        if((parent->type & LISTBOX) || (parent->type & FILELIST) || (parent->type & GRID))
3235                if(node->pagecount != parent->aktpage) return 1;
3236
3237        debug(1000, "in");
3238        int shadowlx = 0, shadowrx = 0, shadowoy = 0, shadowuy = 0;
3239        unsigned int linecount = 0, pagecount = 0, poscount = 0;
3240        char* tmpstr = NULL;
3241
3242        if(node->child != NULL && status.picbordersize > 0)
3243                node->bordersize = status.picbordersize;
3244
3245        if(node->skinfunc != NULL)
3246        {
3247                if(node->funcrettype == FUNCPIC)
3248                {
3249                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3250                        changepic(node, tmpstr);
3251                }
3252                else if(node->funcrettype == FUNCPROGRESS)
3253                {
3254                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3255                        if(tmpstr != NULL)
3256                        {
3257                                node->hidden = NO;
3258                                node->progresssize = atoi(tmpstr);
3259                        }
3260                        else
3261                                node->hidden = YES;
3262                }
3263                else
3264                {
3265                        tmpstr = node->skinfunc(node, node->param1, node->param2);
3266                        changetext(node, _(tmpstr));
3267                }
3268                free(tmpstr);
3269        }
3270
3271        if(status.screencalc != 2)
3272        {
3273                if(node->hidden == YES || parent->hidden == YES || node->locked == YES || parent->locked == YES) return 1;
3274                if(checkbit(parent->flag, 0) == 0) return 1;
3275        }
3276
3277        calcrwidth(node, parent);
3278        if(!(parent->type & LISTBOX) && !(parent->type & FILELIST) && !(parent->type & GRID))
3279                calcrheight(node, parent);
3280        calcrposx(node, parent);
3281        calcrposy(node, parent);
3282
3283        if(node->height < 0)
3284                node->rheight = parent->iheight + node->height - (node->rposy - parent->iposy);
3285        if(node->width < 0)
3286                node->rwidth = parent->iwidth + node->width - (node->rposx - parent->iposx);
3287
3288        node->iposx = node->rposx + node->bordersize + node->hspace;
3289        node->iposy = node->rposy + node->bordersize + node->titlesize + node->vspace;
3290        node->iwidth = node->rwidth - node->bordersize * 2 - node->hspace * 2;
3291        node->iheight = node->rheight - node->bordersize * 2 - node->titlesize - node->vspace * 2;
3292
3293        switch(node->shadowpos)
3294        {
3295                case BOTTOMLEFT: shadowlx = shadowuy = node->shadowsize; break;
3296                case BOTTOMRIGHT: shadowrx = shadowuy = node->shadowsize; break;
3297                case TOPLEFT: shadowlx = shadowoy = node->shadowsize; break;
3298                default: shadowrx = shadowoy = node->shadowsize; break;
3299        }
3300
3301        if((parent->type & LISTBOX) || (parent->type & FILELIST) || (parent->type & GRID))
3302                calclistboxchild(node, parent);
3303
3304        if(node->picprozwidth == 1)
3305                node->rpicwidth = ((float)node->iwidth / 100) * node->picwidth;
3306        else
3307                node->rpicwidth = node->picwidth;
3308        if(node->picprozheight == 1)
3309                node->rpicheight = ((float)node->iheight / 100) * node->picheight;
3310        else
3311                node->rpicheight = node->picheight;
3312
3313
3314        if(node->rposx - shadowlx < parent->iposx)
3315        {
3316                if(status.screencalc == 0) err("node (%s posx=%d) out of parent (%s posx=%d)", node->name, node->rposx - shadowlx, parent->name, parent->iposx);
3317                node->rposx = parent->iposx + shadowlx;
3318                //return 1;
3319        }
3320        if(node->rposy - shadowoy < parent->iposy)
3321        {
3322                if(status.screencalc == 0) err("node (%s posy=%d) out of parent (%s posy=%d)", node->name, node->rposy - shadowoy, parent->name, parent->iposy);
3323                node->rposy = parent->iposy + shadowoy;
3324                //return 1;
3325        }
3326        if(node->rposx + node->rwidth + shadowrx > parent->iposx + parent->iwidth)
3327        {
3328                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);
3329                node->rwidth = parent->iwidth - node->rposx - shadowrx;
3330                //return 1;
3331        }
3332        if(node->rposy + node->rheight + shadowuy > parent->iposy + parent->iheight)
3333        {
3334                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);
3335                node->rheight = parent->iheight - node->rposy - shadowuy;
3336                //return 1;
3337        }
3338
3339        if(node->font == NULL && parent->font != NULL)
3340        {
3341                changefont(node, parent->font);
3342                if(node->font == NULL)
3343                {
3344                        err("no memory");
3345                }
3346        }
3347
3348        if(node->fontsize == 0) node->fontsize = parent->fontsize;
3349        if(node->fontsize == 0) node->fontsize = 1;
3350        if(node->fontsize2 == 0) node->fontsize2 = parent->fontsize2;
3351        if(node->fontsize2 == 0) node->fontsize2 = 1;
3352        if(node->fontcol == 0) node->fontcol = parent->fontcol;
3353        if(node->fontcol2 == 0) node->fontcol2 = parent->fontcol2;
3354
3355        if((node->type & INPUTBOX) || (node->type & INPUTBOXNUM))
3356        {
3357                if(node->aktpage < 1) node->aktpage = 1;
3358                checkinputboxnumright(node);
3359                changeret(node, node->input);
3360        }
3361
3362        if((node->type & LISTBOX) || (node->type & FILELIST) || (node->type & GRID))
3363        {
3364                if(node->aktpage == 0) node->aktpage = 1;
3365                calclistbox(node);
3366                if(node->scrollbar != NO)
3367                        calcscrollbar(node);
3368        }
3369        if(node->type & TEXTBOX)
3370        {
3371                if(node->aktpage < 1) node->aktpage = 1;
3372                if(node->text == NULL && node->text2 == NULL)
3373                        node->pagecount = 0;
3374                else
3375                {
3376                        if(node->wrap == YES)
3377                                wrapstr(node->text, node->font, node->fontsize, node->iwidth, node->charspace);
3378                        calctext(node->text, node->text2, &node->linecount, &node->pagecount, &node->poscount, node->iheight / node->fontsize, node->aktpage);
3379                }
3380                if(node->text2 != NULL) node->scrollbar = NO;
3381                if(node->scrollbar != NO)
3382                        calcscrollbar(node);
3383        }
3384
3385        if((node->type & CHOICEBOX) && node->input != NULL)
3386        {
3387                char* pos = NULL;
3388                calctext(node->input, NULL, &node->linecount, &node->pagecount, &node->poscount, 1, node->aktpage);
3389
3390                free(node->ret);
3391                node->ret = NULL;
3392
3393                if(node->choiceboxvalue != NULL)
3394                {
3395                        calctext(node->choiceboxvalue, NULL, &linecount, &pagecount, &poscount, 1, node->aktpage);
3396                        pos = strchr(node->choiceboxvalue + poscount, '\n');
3397                        if(pos == NULL)
3398                                changeret(node, node->choiceboxvalue + poscount);
3399                        else
3400                                node->ret = strndup(node->choiceboxvalue + poscount, pos - (node->choiceboxvalue + poscount));
3401                }
3402                else if(node->input != NULL)
3403                {
3404                        pos = strchr(node->input + node->poscount, '\n');
3405                        if(pos == NULL)
3406                                changeret(node, node->input + node->poscount);
3407                        else
3408                                node->ret = strndup(node->input + node->poscount, pos - (node->input + node->poscount));
3409                }
3410        }
3411
3412        //set parent transparent to child
3413        //if(node->transparent == 0 && parent != skin)
3414                //node->transparent = parent->transparent;
3415
3416        debug(1000, "out");
3417        return 0;
3418}
3419
3420int clearscreenalways()
3421{
3422        debug(1000, "in");
3423        int i, ret = 0;
3424
3425        for(i = 0; i < sizeof(status.drawallways) / sizeof(skin); i++)
3426        {
3427                if(status.drawallways[i] != NULL)
3428                {
3429                        clearrect(status.drawallways[i]->rposx, status.drawallways[i]->rposy, status.drawallways[i]->rwidth, status.drawallways[i]->rheight);
3430                }
3431        }
3432
3433        debug(1000, "out");
3434        return ret;
3435}
3436
3437int drawscreenalways(struct skin* node)
3438{
3439        debug(1000, "in");
3440        int i, ret = 0;
3441
3442        for(i = 0; i < sizeof(status.drawallways) / sizeof(skin); i++)
3443        {
3444                if(status.drawallways[i] != NULL)
3445                {
3446                        if(node != status.drawallways[i])
3447                        {
3448                                if(status.drawallwaysbg[i] != NULL)
3449                                        free(status.drawallwaysbg[i]);
3450                                status.drawallwaysbg[i] = savescreen(status.drawallways[i]);
3451                                ret = drawscreen(status.drawallways[i], 1);
3452                        }
3453                }
3454        }
3455
3456        debug(1000, "out");
3457        return ret;
3458}
3459
3460int drawscreennode(struct skin *node, char* nodename)
3461{
3462        debug(1000, "in");
3463
3464        node = getscreennode(node, nodename);
3465        m_lock(&status.drawingmutex, 0);
3466        if(node != status.skinerr)
3467                drawnode(node, 1);
3468
3469        drawscreenalways(node);
3470        blitfb(0);
3471        m_unlock(&status.drawingmutex, 0);
3472
3473        debug(1000, "out");
3474        return 0;
3475}
3476
3477int drawscreennodebyname(char* screenname, char* nodename)
3478{
3479        debug(1000, "in");
3480        struct skin *node;
3481
3482        node = getscreennodebyname(screenname, nodename);
3483        m_lock(&status.drawingmutex, 0);
3484        if(node != status.skinerr)
3485                drawnode(node, 1);
3486
3487        drawscreenalways(node);
3488        blitfb(0);
3489        m_unlock(&status.drawingmutex, 0);
3490
3491        debug(1000, "out");
3492        return 0;
3493}
3494
3495//flag 0: draw normal with allways
3496//flag 1: draw without allways
3497//flag 2: from thread (mutex is set in thread)
3498//flag 3: same as 0 but don't use status.screencalc
3499//flag 4: same as 0 but animate
3500int drawscreen(struct skin* node, int flag)
3501{
3502        struct fb* merkskinfb = NULL;
3503
3504        debug(1000, "in");
3505        int ret;
3506        struct skin *child = NULL, *parent = NULL, *oldparent = NULL;
3507
3508        if(node == NULL)
3509        {
3510                err("node = NULL");
3511                return 1;
3512        }
3513
3514        if(flag == 0 || flag == 3 || flag == 4)
3515                m_lock(&status.drawingmutex, 0);
3516
3517        parent = skin;
3518
3519        ret = setnodeattr(node, parent);
3520        if(ret == 1)
3521        {
3522                if(flag == 0 || flag == 3 || flag == 4)
3523                        m_unlock(&status.drawingmutex, 0);
3524                debug(1000, "out -> setnodeattr ret = 1");
3525                return 1;
3526        }
3527       
3528        if(strstr(node->name, "LCD_") != NULL) {
3529                merkskinfb = skinfb;
3530                memset(lcdskinfb->fb, 0, lcdskinfb->varfbsize);
3531                skinfb = lcdskinfb;
3532        }
3533
3534        if(status.screencalc == 0 || flag == 3 || flag == 4)
3535        {
3536                if(flag == 0 || flag == 2 || flag == 3 || flag == 4) clearscreenalways();
3537                drawnode(node, 0);
3538        }
3539        parent = node;
3540        oldparent = node;
3541        child = node->child;
3542
3543        while(child != NULL)
3544        {
3545                if(child->parentpointer != NULL)
3546                        parent = child->parentpointer;
3547                else if(child->parent != NULL)
3548                {
3549                        parent = getscreennode(node, child->parent);
3550                        if(parent == status.skinerr) parent = oldparent;
3551                }
3552                else
3553                        parent = oldparent;
3554
3555                if(setnodeattr(child, parent) == 0 && (status.screencalc == 0 || flag == 3))
3556                        drawnode(child, 1);
3557                child = child->next;
3558        }
3559
3560        if(flag == 0 || flag == 2 || flag == 3 || flag == 4)
3561        {
3562                if(status.screencalc == 0 || flag == 3)
3563                {
3564                        drawscreenalways(node);
3565
3566                        if(merkskinfb != NULL)
3567                                pngforlcd();
3568                        else   
3569                        {
3570                                if(flag == 4)
3571                                        blitfb(1);
3572                                else
3573                                        blitfb(0);
3574                        }
3575                }
3576        }
3577
3578        if(merkskinfb != NULL)
3579        {
3580                skinfb = merkskinfb;
3581                merkskinfb = NULL;
3582        }
3583        else {
3584                if(ostrcmp(getconfig("write_fb_to_jpeg", NULL), "yes") == 0)
3585                        write_FB_to_JPEG_file(skinfb->fb, skinfb->width, skinfb->height, "/tmp/fb.jpg", 3);
3586        }
3587        if(flag == 0 || flag == 3 || flag == 4)
3588                m_unlock(&status.drawingmutex, 0);
3589        debug(1000, "out");
3590        return 0;
3591}
3592
3593int drawscreenbyname(char* screenname)
3594{
3595        debug(1000, "in");
3596        int ret;
3597        struct skin* node = NULL;
3598
3599        node = getscreen(screenname);
3600        if(node == status.skinerr)
3601        {
3602                err("screen not found (%s)", screenname);
3603                return 1;
3604        }
3605
3606        ret = drawscreen(node, 0);
3607        debug(1000, "out");
3608        return ret;
3609}
3610
3611int changeinput(struct skin* node, char* text)
3612{
3613        debug(1000, "in");
3614        int ret = 1;
3615
3616        if(node != NULL)
3617        {
3618                free(node->input);
3619                if(text != NULL)
3620                {
3621                        if((node->type & INPUTBOXNUM) && node->mask != NULL && strlen(text) == 0)
3622                                node->input = strdup(node->mask);
3623                        else
3624                                node->input = strdup(text);
3625                }
3626                else
3627                {
3628                        if((node->type & INPUTBOXNUM) && node->mask != NULL)
3629                                node->input = strdup(node->mask);
3630                        else
3631                                node->input = text;
3632                }
3633                ret = 0;
3634        }
3635        debug(1000, "out");
3636
3637        return ret;
3638}
3639
3640int changetext(struct skin* node, char* text)
3641{
3642        debug(1000, "in");
3643        int ret = 1;
3644
3645        if(node != NULL)
3646        {
3647                free(node->text);
3648                if(text != NULL)
3649                        node->text = strdup(text);
3650                else
3651                        node->text = text;
3652                ret = 0;
3653        }
3654        debug(1000, "out");
3655
3656        return ret;
3657}
3658
3659int changetext2(struct skin* node, char* text)
3660{
3661        debug(1000, "in");
3662        int ret = 1;
3663
3664        if(node != NULL)
3665        {
3666                free(node->text2);
3667                if(text != NULL)
3668                        node->text2 = strdup(text);
3669                else
3670                        node->text2 = text;
3671                ret = 0;
3672        }
3673        debug(1000, "out");
3674
3675        return ret;
3676}
3677
3678
3679int changename(struct skin* node, char* text)
3680{
3681        debug(1000, "in");
3682        int ret = 1;
3683
3684        if(node != NULL)
3685        {
3686                free(node->name);
3687                if(text != NULL)
3688                        node->name = strdup(text);
3689                else
3690                        node->name = text;
3691                ret = 0;
3692        }
3693        debug(1000, "out");
3694
3695        return ret;
3696}
3697
3698int changepicmem(struct skin* node, char* text, int del)
3699{
3700        debug(1000, "in");
3701        unsigned long width = 0, height = 0, rowbytes = 0;
3702        int ret = 1, channels = 0, memfd = -1, length = 0;
3703        unsigned char* buf = NULL;
3704
3705        if(node != NULL)
3706        {
3707                free(node->pic);
3708                if(text != NULL)
3709                {
3710                        node->pic = changepicpath(text);
3711
3712                        if(getpic(node->pic) == NULL)
3713                        {
3714                                length = strlen(node->pic);
3715                                if(node->pic[length - 1] == 'g' && node->pic[length - 2] == 'n' && node->pic[length - 3] == 'p')
3716                                        buf = readpng(node->pic, &width, &height, &rowbytes, &channels, 0, 0, 0, 0, 0, 0);
3717                                else if(getconfigint("pichwdecode", NULL) == 1)
3718                                        readjpg(node->pic, &width, &height, &rowbytes, &channels, &buf, &memfd);
3719                                addpic(node->pic, buf, memfd, width, height, rowbytes, channels, del, NULL);
3720                        }
3721                }
3722                else
3723                        node->pic = text;
3724                ret = 0;
3725        }
3726        debug(1000, "out");
3727
3728        return ret;
3729}
3730
3731int changepic(struct skin* node, char* text)
3732{
3733        debug(1000, "in");
3734        int ret = 1;
3735
3736        if(node != NULL)
3737        {
3738                free(node->pic);
3739                if(text != NULL)
3740                        node->pic = changepicpath(text);
3741                else
3742                        node->pic = text;
3743                ret = 0;
3744        }
3745        debug(1000, "out");
3746
3747        return ret;
3748}
3749
3750int changeselectpic(struct skin* node, char* text)
3751{
3752        debug(1000, "in");
3753        int ret = 1;
3754
3755        if(node != NULL)
3756        {
3757                free(node->selectpic);
3758                if(text != NULL)
3759                        node->selectpic = changepicpath(text);
3760                else
3761                        node->selectpic = text;
3762                ret = 0;
3763        }
3764        debug(1000, "out");
3765
3766        return ret;
3767}
3768
3769int changetitle(struct skin* node, char* text)
3770{
3771        debug(1000, "in");
3772        int ret = 1;
3773
3774        if(node != NULL)
3775        {
3776                free(node->title);
3777                if(text != NULL)
3778                {
3779                        node->title = strdup(text);
3780                        node->titlesize = node->fontsize + 6;
3781                }
3782                else
3783                {
3784                        node->title = text;
3785                        node->titlesize = 0;
3786                }
3787                ret = 0;
3788        }
3789        debug(1000, "out");
3790
3791        return ret;
3792}
3793
3794int changemask(struct skin* node, char* text)
3795{
3796        debug(1000, "in");
3797        int ret = 1;
3798
3799        if(node != NULL)
3800        {
3801                free(node->mask);
3802                if(text != NULL)
3803                {
3804                        if((node->type & INPUTBOXNUM) && (node->input == NULL || strlen(node->input) == 0))
3805                        {
3806                                node->mask = strdup(text);
3807                                free(node->input);
3808                                node->input = strdup(text);
3809                        }
3810                        else
3811                                node->mask = strdup(text);
3812                }
3813                else
3814                        node->mask = text;
3815                ret = 0;
3816        }
3817        debug(1000, "out");
3818
3819        return ret;
3820}
3821
3822int changeret(struct skin* node, char* text)
3823{
3824        debug(1000, "in");
3825        int ret = 1;
3826
3827        if(node != NULL)
3828        {
3829                free(node->ret);
3830                if(text != NULL)
3831                        node->ret = strdup(text);
3832                else
3833                        node->ret = text;
3834                ret = 0;
3835        }
3836        debug(1000, "out");
3837
3838        return ret;
3839}
3840
3841int changeparent(struct skin* node, char* text)
3842{
3843        debug(1000, "in");
3844        int ret = 1;
3845
3846        if(node != NULL)
3847        {
3848                free(node->parent);
3849                if(text != NULL)
3850                        node->parent = strdup(text);
3851                else
3852                        node->parent = text;
3853                ret = 0;
3854        }
3855        debug(1000, "out");
3856
3857        return ret;
3858}
3859
3860int changefont(struct skin* node, char* text)
3861{
3862        debug(1000, "in");
3863        int ret = 1;
3864
3865        if(node != NULL)
3866        {
3867                free(node->font);
3868                if(text != NULL)
3869                        node->font = strdup(text);
3870                else
3871                        node->font = text;
3872                ret = 0;
3873        }
3874        debug(1000, "out");
3875
3876        return ret;
3877}
3878
3879int changeparam1(struct skin* node, char* text)
3880{
3881        debug(1000, "in");
3882        int ret = 1;
3883
3884        if(node != NULL)
3885        {
3886                free(node->param1);
3887                if(text != NULL)
3888                        node->param1 = strdup(text);
3889                else
3890                        node->param1 = text;
3891                ret = 0;
3892        }
3893        debug(1000, "out");
3894
3895        return ret;
3896}
3897
3898int changeparam2(struct skin* node, char* text)
3899{
3900        debug(1000, "in");
3901        int ret = 1;
3902
3903        if(node != NULL)
3904        {
3905                free(node->param2);
3906                if(text != NULL)
3907                        node->param2 = strdup(text);
3908                else
3909                        node->param2 = text;
3910                ret = 0;
3911        }
3912        debug(1000, "out");
3913
3914        return ret;
3915}
3916
3917int changechoiceboxvalue(struct skin* node, char* text)
3918{
3919        debug(1000, "in");
3920        int ret = 1;
3921
3922        if(node != NULL)
3923        {
3924                free(node->choiceboxvalue);
3925                if(text != NULL)
3926                        node->choiceboxvalue = strdup(text);
3927                else
3928                        node->choiceboxvalue = text;
3929                ret = 0;
3930        }
3931        debug(1000, "out");
3932
3933        return ret;
3934}
3935
3936#endif
Note: See TracBrowser for help on using the repository browser.