source: titan/titan/skin.h @ 15508

Last change on this file since 15508 was 15508, checked in by nit, 12 years ago

fix

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