source: titan/titan/skin.h @ 23983

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

[titan] optimize

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