Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

skin_Bordered.c

Go to the documentation of this file.
00001 /*
00002  *    gui - [gega user interface] the flexible solution for user interface problems
00003  *    Copyright (C) 2002  Gergely Gati
00004  *
00005  *    This program is free software; you can redistribute it and/or modify
00006  *    it under the terms of the GNU General Public License as published by
00007  *    the Free Software Foundation; version 2 of the License.
00008  *
00009  *    This program is distributed in the hope that it will be useful,
00010  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *    GNU General Public License for more details.
00013  *
00014  *    You should have received a copy of the GNU General Public License
00015  *    along with this program; if not, write to the Free Software
00016  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  *    Gergely Gati
00019  *      email:           g.gati@freemail.hu
00020  *      AIM screenname:  GatiGergely
00021  *      ICQ number:      93131690
00022  *
00023  */
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <xmlparse.h>
00027 
00028 #define __SKIN_MODULE
00029 
00030 #include "skins/skin_Bordered.h"
00031 #include "debug.h"
00032 #include "Bases.h"
00033 #include "Module.h"
00034 #include "Memory.h"
00035 #include "Net.h"
00036 #include "Common.h"
00037 #include "Crc.h"
00038 #include "Image.h"
00039 #include "Gadget.h"
00040 #include "Skin.h"
00041 #include "Tag.h"
00042 #include "Locale.h"
00043 #include "Window.h"
00044 #include "macros.h"
00045 
00046 
00047 #define SKNBP_BARTOP              0
00048 #define SKNBP_BARLEFT             1
00049 #define SKNBP_BARRIGHT            2
00050 #define SKNBP_BARBOTTOM           3
00051 #define SKNBP_CORNERTOPLEFT       4
00052 #define SKNBP_CORNERTOPRIGHT      5
00053 #define SKNBP_CORNERBOTTOMLEFT    6
00054 #define SKNBP_CORNERBOTTOMRIGHT   7
00055 
00056 
00057 #define SKNF_BEGIN          0
00058 #define SKNF_INBORDER       1
00059 #define SKNF_SKINFOUND      2
00060 #define SKNF_INGADGET       3
00061 #define SKNF_INSTATE        4
00062 
00063 
00064 #define SKND_DEFAULT        0
00065 #define SKND_SKIP           1
00066 
00067 
00068 struct bordered_xml_userdata
00069 {
00070   int level;
00071   int state;
00072   int skiplevel;
00073   Skin_t *skin;
00074   struct bordered_border *border;
00075   const char *statename;
00076   struct bordered_gadget *curr_gadget;
00077   gadget_ClassData_t *curr_class;
00078   struct bordered_state *curr_state;
00079 };
00080 
00081 
00082 //border related
00083 struct bordered_image
00084 {
00085   Node_t *node;           // hogy konnyen eltavolithassam (mutato a tartalmazo node-ra)
00086   int counter;            // hivatkozasnal novelni, ha nulla akkor unload
00087   char *imgname;          // ha az img NULL akkor kep kell -> megnyitjuk
00088   Image_t *img;           // a kepet es megtartjuk a nevet is
00089   int minwidth;
00090   int maxwidth;
00091   int minheight;
00092   int maxheight;
00093 };
00094 
00095 
00096 //border related
00097 struct bordered_imgorcol
00098 {
00099   struct bordered_image *image;  // csak pointer egy letezo image-re (vagy NULL)
00100   u32 color;                     // ha a felso NULL akkor ez jon. ha ez ~0 akkor semmi
00101 };
00102 
00103 
00104 //border related
00105 struct bordered_border
00106 {
00107   Node_t *node;
00108   int counter;
00109   char *name;             // mindig megmarad a nev
00110   int left,right;         // left+right=horizontal    (in struct bordered_gadget)
00111   int top,bottom;         // top+bottom=vertical
00112   struct bordered_imgorcol borders[8];
00113 };
00114 
00115 
00116 //gadget class related
00117 struct bordered_state
00118 {
00119   int status;                     // 0-unsupported state
00120   struct bordered_border *border; // NULL -> border not required (size unchanged)
00121   struct bordered_imgorcol background;
00122   u32 *colormap;                  // class_data->color_count db u32 color (ha az 0, ez NULL)
00123 };
00124 
00125 
00126 //gadget class related
00127 struct bordered_custom
00128 {
00129   struct bordered_border *border;      // csak pointer egy mar letezo borderre
00130   struct bordered_imgorcol background;
00131 };
00132 
00133 
00134 //gadget class related
00135 struct bordered_gadget
00136 {
00137   Node_t *node;            // hogy konnyen eltavolithassam (mutato a tartalmazo node-ra)
00138   struct bordered_gadget *next;
00139   u32 class_id;
00140   u32 namecrc;             // 0L default (az elso 0L) (ha 0jon ki, 1)
00141   int horizontal,vertical; // az elso state-borderjebol szamitjuk: horiz=left+right, vert=bottom+top
00142   u32 font;
00143   char *font_name;
00144   int font_size;
00145   int font_style;
00146   int font_weight;
00147   int font_decoration;
00148   int custom_count;
00149   struct bordered_custom *custom;             // class_data->custom_count db
00150   struct bordered_state states[GADST_COUNT];  // class_data->state_mask szerint
00151   tag *taglist;
00152   u32 transparent_color;   // ~0 nincs
00153 };
00154 
00155 
00156 struct Skin_s
00157 {
00158   skin_Common_t common;
00159   gui_App_t *app;
00160   char *path;                     //                                   type                     delete
00161   List_t *classlist;              // minden gadget class-nak egy elem (struct bordered_gadget)  gadget_DeleteOne()
00162   List_t *borderlist;             // borderenkent egy elem            (struct bordered_border)  skin_DeleteSkin()
00163   List_t *imagelist;              // felhasznalt image-ek             (struct bordered_image)   ->gadget_DeleteOne()
00164 };
00165 
00166 
00167 static bases_Modules_t *api;
00168 #define TYPE "bordered"
00169 #define VER "1.1"
00170 VERSION("Bordered.skin",1,1,"Gergely Gati","g.gati@freemail.hu");
00171 
00172 
00173 
00174 /****************************************************************************************
00175  *  bordered_image handling functions
00176  ****************************************************************************************/
00177 
00178 static struct bordered_image *bordered_SearchImage(List_t *imagelist, const char *name)
00179 {
00180   struct bordered_image *ret=NULL;
00181   Node_t *node;
00182 
00183   debug_Begin();
00184 
00185   if(imagelist!=NULL)
00186   {
00187     for(node=list_GetNodeHead(imagelist);node!=NULL;node=list_GetNodeNext(imagelist,node))
00188     {
00189       ret=list_GetNodeData(node);
00190       if(strcmp(ret->imgname,name)==0) break;
00191       ret=NULL;
00192     }
00193   }
00194 
00195   debug_End();
00196 
00197   return(ret);
00198 }
00199 
00200 
00201 static struct bordered_image *bordered_AddImage(Skin_t *skin, const char *name)
00202 {
00203   struct bordered_image *ret=NULL;
00204   Node_t *node;
00205   char *imgname=NULL;
00206 
00207   debug_Begin();
00208 
00209   if(skin!=NULL&&skin->imagelist!=NULL&&name!=NULL)
00210   {
00211     if(NULL!=(imgname=mem_malloc(strlen(skin->path)+strlen(name)+7+1)))
00212     {
00213       strcpy(imgname,skin->path);
00214       strcat(imgname,"images/");
00215       strcat(imgname,name);
00216       if(NULL==(ret=bordered_SearchImage(skin->imagelist,imgname)))
00217       {
00218         if(NULL!=(node=list_CreateNode()))
00219         {
00220           if(NULL!=(ret=mem_malloc(sizeof(struct bordered_image))))
00221           {
00222             ret->node=node;
00223             ret->img=NULL;
00224             ret->counter=1;
00225             ret->imgname=imgname;
00226             list_SetNodeData(node,ret);
00227             list_InsertNodeHead(skin->imagelist,node);
00228           }
00229         }
00230       }
00231       else
00232       {
00233         mem_free(imgname);
00234         ret->counter++;
00235       }
00236     }
00237   }
00238   if(ret==NULL&&imgname!=NULL) mem_free(imgname);
00239 
00240   debug_End();
00241 
00242   return(ret);
00243 }
00244 
00245 
00246 static int bordered_DeleteImage(List_t *imagelist, struct bordered_image *image)
00247 {
00248   int ret=-1;
00249   Node_t *node;
00250 
00251   debug_Begin();
00252 
00253   if(NULL!=image)
00254   {
00255     debug_Message(" delete req '%s' counter=%d",image->imgname,image->counter);
00256     ret=0;
00257     if((--image->counter)<=0)
00258     {
00259       debug_Message("  counter zero, remove");
00260       node=image->node;
00261       list_RemoveNode(imagelist,node);
00262       list_DeleteNode(node);
00263       if(image->imgname!=NULL) mem_free(image->imgname);
00264       if(image->img!=NULL) api->img_Call(IMG_CLEANUPIMAGE,TAG_IMG_OBJECT,image->img,TAG_DONE);
00265       mem_free(image);
00266     }
00267   }
00268 
00269   debug_End();
00270 
00271   return(ret);
00272 }
00273 
00274 
00275 /****************************************************************************************
00276  * border handling
00277  ****************************************************************************************/
00278 
00279 
00280 static int bordered_SeekBorderPiece(const char *bp)
00281 {
00282   static char *border_piece_names[]=
00283   {
00284     "Top",
00285     "Left",
00286     "Right",
00287     "Bottom",
00288     "TopLeft",
00289     "TopRight",
00290     "BottomLeft",
00291     "BottomRight",
00292     NULL
00293   };
00294   int ret=-1,i;
00295 
00296   debug_Begin();
00297 
00298   for(i=0;border_piece_names[i]!=NULL;i++)
00299   {
00300     if(strcmp(bp,border_piece_names[i])==0)
00301     {
00302       ret=i;
00303       break;
00304     }
00305   }
00306 
00307   debug_End();
00308 
00309   return(ret);
00310 };
00311 
00312 
00313 static struct bordered_border *bordered_SearchBorder(List_t *borderlist, char *bordername)
00314 {
00315   struct bordered_border *ret=NULL, *border;
00316   Node_t *node;
00317 
00318   debug_Begin();
00319 
00320   if(borderlist!=NULL&&bordername!=NULL)
00321   {
00322     for(node=list_GetNodeHead(borderlist);node!=NULL;node=list_GetNodeNext(borderlist,node))
00323     {
00324       if(NULL!=(border=(struct bordered_border *)list_GetNodeData(node)))
00325       {
00326         if(border->name!=NULL&&strcmp(border->name,bordername)==0)
00327         {
00328           ret=border;
00329           break;
00330         }
00331       }
00332     }
00333   }
00334 
00335   debug_End();
00336 
00337   return(ret);
00338 }
00339 
00340 
00341 static int bordered_DeleteBorder(Skin_t *skin, struct bordered_border *border)
00342 {
00343   int ret=-1,i;
00344 
00345   debug_Begin();
00346 
00347   if(skin!=NULL&&skin->borderlist!=NULL&&border!=NULL&&skin->imagelist!=NULL)
00348   {
00349     debug_Message("Delete req border: '%s' (counter=%d)",border->name,border->counter);
00350     if(--border->counter<=0)
00351     {
00352       debug_Message("  real delete");
00353       list_RemoveNode(skin->borderlist,border->node);
00354       list_DeleteNode(border->node);
00355       if(NULL!=border->name) mem_free(border->name);
00356       for(i=0;i<8;i++) bordered_DeleteImage(skin->imagelist,border->borders[i].image);
00357       mem_free(border);
00358       ret=0;
00359     }
00360   }
00361 
00362   debug_End();
00363 
00364   return(ret);
00365 }
00366 
00367 
00368 /****************************************************************************************
00369  * gadget class handling
00370  ****************************************************************************************/
00371 
00372 
00373 static struct bordered_gadget *bordered_SeekClass(List_t *classlist, u32 class_id)
00374 {
00375   struct bordered_gadget *ret=NULL;
00376   Node_t *node;
00377 
00378   debug_Begin();
00379 
00380   if(classlist!=NULL)
00381   {
00382     for(node=list_GetNodeHead(classlist);node!=NULL;node=list_GetNodeNext(classlist,node))
00383     {
00384       if(NULL!=(ret=list_GetNodeData(node)))
00385       {
00386         if(ret->class_id==class_id) break;
00387         ret=NULL;
00388       }
00389     }
00390   }
00391 
00392   debug_End();
00393 
00394   return(ret);
00395 }
00396 
00397 
00398 /****************************************************************************************
00399  * XML parser
00400  ****************************************************************************************/
00401 
00402 
00403 static tag *bordered_BuildTaglist(Skin_t *skin, char **atts, gadget_ClassData_t *cla)
00404 {
00405   tag *ret=NULL;
00406   int i,nx;
00407   gadget_Binding_t *bind;
00408 
00409   debug_Begin();
00410 
00411   if(skin!=NULL&&atts!=NULL&&cla!=NULL)
00412   {
00413     for(i=0;atts[i]!=NULL;i+=2);
00414     i>>=1;
00415     if(NULL!=(ret=mem_malloc(i*sizeof(tag))))
00416     {
00417       bind=cla->xmlbinding;
00418       for(nx=i=0;atts[i]!=NULL;i+=2)
00419       {
00420         if(0==(api->gadget_Call(GADGET_BIND,
00421             TAG_GADGET_LOCALE,skin->app->locale,
00422             TAG_GADGET_BINDING,bind,
00423             TAG_GADGET_NAME,atts[i],
00424             TAG_GADGET_VALUE,atts[i+1],
00425             TAG_GADGET_TAGNAME,&ret[nx].Name,
00426             TAG_GADGET_TAGVALUE,&ret[nx].Data,
00427             TAG_DONE))) nx++;
00428       }
00429       if(nx==0)
00430       {
00431         mem_free(ret);
00432         ret=NULL;
00433       }
00434       else
00435       {
00436         ret[nx].Name=TAG_DONE;
00437         ret[nx].Data=0L;
00438       }
00439     }
00440   }
00441 
00442   debug_End();
00443 
00444   return(ret);
00445 }
00446 
00447 
00448 static void bordered_StartElement(void *userData, const char *name, const char **atts)
00449 {
00450   struct bordered_xml_userdata *userdata=(struct bordered_xml_userdata *)userData;
00451   char *ver,*nam,*num,*att,*fnam,*type;
00452   int bordertype,i,sta,top,left,bottom,right,ok,n;
00453   struct bordered_border *border;
00454   Node_t *node;
00455   u32 col,namcrc;
00456   gadget_ClassData_t *cla;
00457   struct bordered_gadget *gadget,*item;
00458 
00459   debug_Begin();
00460 
00461   userdata->level++;
00462   if(userdata->skiplevel<0)
00463   {
00464     switch(userdata->state)
00465     {
00466       case SKNF_BEGIN:
00467       {
00468         if(strcmp(name,"Skin")==0)
00469         {
00471           // <Skin>
00473           if(NULL!=(type=common_GetAttr(atts,"type"),TYPE)&&strcmp(type,TYPE)==0)
00474           {
00475             if(NULL!=(ver=common_GetAttr(atts,"version"))&&strcmp(ver,VER)==0)
00476             {
00477               userdata->state=SKNF_SKINFOUND;
00478             }
00479             else debug_Error("wrong skin version (expected: V%s, found: V%s)",VER,ver);
00480           }
00481           else debug_Error("wrong skin type (expected: '%s', found: '%s')",TYPE,type);
00482         }
00483         break;
00484       }
00485       case SKNF_INBORDER:
00486       {
00487         if(0<=(bordertype=bordered_SeekBorderPiece(name)))
00488         {
00490           // border-piece <Top> <Left> <Right> <Bottom> <TopLeft> [...]
00492           if(bordertype==SKNBP_BARTOP&&(userdata->border->top<=0)) bordertype=-1;
00493           else if(bordertype==SKNBP_BARLEFT&&(userdata->border->left<=0)) bordertype=-1;
00494           else if(bordertype==SKNBP_BARRIGHT&&(userdata->border->right<=0)) bordertype=-1;
00495           else if(bordertype==SKNBP_BARBOTTOM&&(userdata->border->bottom<=0)) bordertype=-1;
00496           else if(bordertype==SKNBP_CORNERTOPLEFT&&(userdata->border->top<=0||userdata->border->left<=0)) bordertype=-1;
00497           else if(bordertype==SKNBP_CORNERTOPRIGHT&&(userdata->border->top<=0||userdata->border->right<=0)) bordertype=-1;
00498           else if(bordertype==SKNBP_CORNERBOTTOMLEFT&&(userdata->border->bottom<=0||userdata->border->left<=0)) bordertype=-1;
00499           else if(bordertype==SKNBP_CORNERBOTTOMRIGHT&&(userdata->border->bottom<=0||userdata->border->right<=0)) bordertype=-1;
00500           if(bordertype>=0&&userdata->border!=NULL)
00501           {
00502             if(NULL!=(att=common_GetAttr(atts,"image")))
00503             {
00504               userdata->border->borders[bordertype].image=bordered_AddImage(userdata->skin,att);
00505             }
00506             if(NULL!=(att=common_GetAttr(atts,"color")))
00507             {
00508               sscanf(att,"#%lx",&col);
00509               userdata->border->borders[bordertype].color=col;
00510             }
00511           }
00512         }
00513         break;
00514       }
00515       case SKNF_SKINFOUND:
00516       {
00517         if(strcmp(name,"Border")==0)
00518         {
00520           // <Border>
00522           if(NULL!=(nam=common_GetAttr(atts,"name")))
00523           {
00524             left=right=top=bottom=0;
00525             if(NULL!=(num=common_GetAttr(atts,"top"))) top=atoi(num);
00526             if(NULL!=(num=common_GetAttr(atts,"right"))) right=atoi(num);
00527             if(NULL!=(num=common_GetAttr(atts,"left"))) left=atoi(num);
00528             if(NULL!=(num=common_GetAttr(atts,"bottom"))) bottom=atoi(num);
00529             if(NULL==(border=bordered_SearchBorder(userdata->skin->borderlist,nam)))
00530             {
00531               if(NULL!=(border=mem_calloc(1,sizeof(struct bordered_border))))
00532               {
00533                 if(NULL!=(node=list_CreateNode()))
00534                 {
00535                   border->node=node;
00536                   border->counter=0;
00537                   border->name=common_strdup(nam);
00538                   border->left=left;
00539                   border->right=right;
00540                   border->top=top;
00541                   border->bottom=bottom;
00542                   for(i=0;i<8;i++)
00543                   {
00544                     border->borders[i].image=NULL;
00545                     border->borders[i].color=~0L;
00546                   }
00547                   list_SetNodeData(node,border);
00548                   list_InsertNodeTail(userdata->skin->borderlist,node);
00549                   userdata->state=SKNF_INBORDER;
00550                 }
00551                 else
00552                 {
00553                   mem_free(border);
00554                   border=NULL;
00555                 }
00556               }
00557             }
00558             else debug_Error("redefined border '%s'",nam);
00559             userdata->border=border;
00560           }
00561           else userdata->skiplevel=userdata->level-1;
00562         }
00563         else if(strcmp(name,"Gadget")==0)
00564         {
00566           // <Gadget>
00568           /* plusz feature:
00569              ha van megadva font, akkor megnyitjuk
00570              es eltaroljuk.
00571            */
00572           if(NULL!=(att=common_GetAttr(atts,"class")))
00573           {
00574             if(NULL!=(cla=(gadget_ClassData_t *)api->gadget_Call(GADGET_FIND_CLASS_BY_NAME,TAG_GADGET_CLASS_NAME,att,TAG_DONE)))
00575             {
00576               nam=common_GetAttr(atts,"name");
00577               namcrc=0L;
00578               if(nam!=NULL)
00579               {
00580                 namcrc=crc_CalcBuffer(nam,strlen(nam));
00581                 if(namcrc==0L) namcrc=1L;
00582               }
00583               // lefoglalok egy bordered_gadget struct-ot, kitoltom:
00584               //  next=NULL
00585               //  namecrc=namcrc
00586               //  horizontal,vertical=0
00587               //  states-t inicializalni, status-t beallitani helyesre,
00588               //     colormap-okat lefoglalni, ahol szukseges
00589               // kikeresem az userdata->tablelist -bol a cla->class_id -t:
00590               //  ha benne van, akkor abba a listaba helyezem (ha namcrc
00591               //    0L akkor az elejere, kulonben mashova.
00592               //  ha nincs benne, lefoglalok egy bordered_table -t, kitoltom:
00593               //    class_id=cla->class_id, first=gadget; felfuzom a
00594               //    userdata->tablelist listara
00595               // ha minden OK, akkor userdata->curr_gadget=gadget,
00596               //                     userdata->curr_class=cla
00597               if(NULL!=(gadget=mem_calloc(1,sizeof(struct bordered_gadget))))
00598               {
00599                 gadget->class_id=cla->class_id;
00600                 gadget->namecrc=namcrc;
00601                 gadget->transparent_color=~0L;
00602                 if(NULL!=(fnam=common_GetAttr(atts,"font-name"))) gadget->font_name=common_strdup(fnam);
00603                 if(NULL!=(fnam=common_GetAttr(atts,"font-size"))) gadget->font_size=atoi(fnam);
00604                 if(NULL!=(fnam=common_GetAttr(atts,"font-style"))) gadget->font_style=atoi(fnam);
00605                 if(NULL!=(fnam=common_GetAttr(atts,"font-weight"))) gadget->font_weight=atoi(fnam);
00606                 if(NULL!=(fnam=common_GetAttr(atts,"font-decoration"))) gadget->font_decoration=atoi(fnam);
00607                 if(NULL!=(fnam=common_GetAttr(atts,"transparent"))&&fnam[0]=='#'&&strlen(fnam)>1) sscanf(&fnam[1],"%lx",&gadget->transparent_color);
00608                 //read gadget related atts cla->xmlbinding segitsegevel
00609                 //azokbol epiteni egy taglistet (vegen zaro taggal)
00610                 //ha egyet sem talaltunk, akkor ide NULL keruljon
00611                 gadget->taglist=bordered_BuildTaglist(userdata->skin,(char **)atts,cla);
00612                 if(cla->custom_count>0)
00613                 {
00614                   if(NULL!=(gadget->custom=mem_calloc(sizeof(struct bordered_custom),cla->custom_count)))
00615                   {
00616                     for(i=0;i<cla->custom_count;i++)
00617                     {
00618                       gadget->custom[i].border=NULL;
00619                       gadget->custom[i].background.image=NULL;
00620                       gadget->custom[i].background.color=~0L;
00621                     }
00622                   }
00623                 }
00624                 gadget->custom_count=cla->custom_count;
00625                 for(i=0;i<GADST_COUNT;i++)
00626                 {
00627                   gadget->states[i].border=NULL;
00628                   gadget->states[i].background.color=~0L;
00629                   if((cla->state_mask&(1<<i))!=0)
00630                   {
00631                     gadget->states[i].status=1;
00632                     if(cla->color_count>0) gadget->states[i].colormap=mem_calloc(sizeof(u32),cla->color_count);
00633                   }
00634                   else gadget->states[i].status=0;
00635                 }
00636                 ok=1;
00637                 if(NULL!=(item=bordered_SeekClass(userdata->skin->classlist,cla->class_id)))
00638                 {
00639                   gadget->node=item->node;
00640                   gadget->next=item->next;
00641                   item->next=gadget;
00642                   ok=0;
00643                 }
00644                 else if(NULL!=(node=list_CreateNode()))
00645                 {
00646                   gadget->node=node;
00647                   list_SetNodeData(node,gadget);
00648                   list_InsertNodeTail(userdata->skin->classlist,node);
00649                   ok=0;
00650                 }
00651                 if(ok==0)
00652                 {
00653                   userdata->state=SKNF_INGADGET;
00654                   userdata->curr_class=cla;
00655                   userdata->curr_gadget=gadget;
00656                 }
00657               }
00658             }
00659             else debug_Error("cannot find gadget class '%s'",att);
00660           }
00661           else debug_Error("cannot find class attribute in a gadget declaration");
00662           if(userdata->state!=SKNF_INGADGET) userdata->skiplevel=userdata->level-1;
00663         }
00664         break;
00665       }
00666       case SKNF_INGADGET:
00667       {
00668         if(strcmp("Custom",name)==0)
00669         {
00671           // <Custom>
00673           // a name tagot kiszedni, megallapitani belole a sorszamot (n)
00674           //   ha van image tag, akkor kep, ha color tag van, akkor color.
00675           //    ha color, akkor a szint a userdata->curr_gadget->custom[n].color -ba
00676           //     sscanf(att,"#%lx",&userdata->curr_gadget->custom[n].color);
00677           //    ha image, akkor
00678           //      userdata->curr_gadget->custom[i].image=bordered_AddImage(userdata->skin,nam);
00679           if(userdata->curr_class->custom_count>0&&userdata->curr_gadget->custom!=NULL)
00680           {
00681             if(NULL!=(nam=common_GetAttr(atts,"name")))
00682             {
00683               for(n=-1,i=0;i<userdata->curr_class->custom_count;i++)
00684               {
00685                 if(0==strcmp(nam,userdata->curr_class->custom_names[i])) { n=i; break; }
00686               }
00687               if(n>=0)
00688               {
00689                 if(userdata->curr_gadget->custom[n].background.image==NULL&&userdata->curr_gadget->custom[n].background.color==~0L)
00690                 {
00691                   if(NULL!=(att=common_GetAttr(atts,"background")))
00692                   {
00693                     if(att[0]=='#') sscanf(att,"#%lx",&userdata->curr_gadget->custom[n].background.color);
00694                     else userdata->curr_gadget->custom[n].background.image=bordered_AddImage(userdata->skin,att);
00695                   }
00696                   if(NULL!=(att=common_GetAttr(atts,"border")))
00697                   {
00698                     if(NULL!=(border=bordered_SearchBorder(userdata->skin->borderlist,att)))
00699                     {
00700                       userdata->curr_gadget->custom[n].border=border;
00701                       border->counter++;
00702                       debug_Message("BORDER++ '%s' cnt=%d",border->name,border->counter);
00703                     }
00704                     else debug_Error("Border '%s' not found!",att);
00705                   }
00706                 }
00707                 else debug_Error("Custom data redefinition at class '%s' custom name '%s'",userdata->curr_class->class_name,nam);
00708               }
00709               else debug_Error("The class '%s' doesn't support the custom image '%s'",userdata->curr_class->class_name,nam);
00710             }
00711             else debug_Error("The custom tag has no name attribute");
00712           }
00713           else debug_Error("The class '%s' doesn't support custom images",userdata->curr_class->class_name);
00714         }
00715         else if((userdata->curr_class->state_mask&(1<<(sta=api->gadget_Call(GADGET_GET_STATE_NAME,TAG_GADGET_STATE_NAME,(char *)name,TAG_DONE))))!=0)
00716         {
00718           // state <Normal> <Pressed> <Focused> [...]
00720           if(userdata->curr_gadget->states[sta].status!=0)
00721           {
00722             if(NULL!=(nam=common_GetAttr(atts,"border")))
00723             {
00724               if(NULL!=(border=bordered_SearchBorder(userdata->skin->borderlist,nam)))
00725               {
00726                 userdata->curr_gadget->states[sta].border=border;
00727                 border->counter++;
00728                 debug_Message("BORDER++ '%s' cnt=%d",border->name,border->counter);
00729               }
00730               else debug_Error("border '%s' not found!",nam);
00731             }
00732             if(NULL!=(nam=common_GetAttr(atts,"background")))
00733             {
00734               if(nam[0]=='#') sscanf(nam,"#%lx",&userdata->curr_gadget->states[sta].background.color);
00735               else userdata->curr_gadget->states[sta].background.image=bordered_AddImage(userdata->skin,nam);
00736             }
00737             // border-t (ha van) kikeresni a userdata->skin->borderlist-bol,
00738             // ha nincs benne ->HIBA
00739             // userdata->curr_gadget->states[sta].status==0 ->HIBA
00740             // userdata->curr_gadget->states[sta].border = a fent kikeresett
00741             // .bgimagename= kikeresni a background -ot es ha nem '#' az elso betuje
00742             // .bgimage=NULL
00743             // .bgcolor= ha a background elso betuje # akkor az a szam
00744             userdata->curr_state=&userdata->curr_gadget->states[sta];
00745             userdata->state=SKNF_INSTATE;
00746             userdata->statename=name;
00747           }
00748           else debug_Error("internal error: state validation error!");
00749         }
00750         else
00751         {
00752           debug_Error("Gadget class '%s' does not support state '%s'!",userdata->curr_class->class_name,name);
00753           userdata->skiplevel=userdata->level-1;
00754         }
00755         break;
00756       }
00757       case SKNF_INSTATE:
00758       {
00759         if(0==(strcmp(name,"ColorMap")))
00760         {
00762           // <ColorMap>
00764           // vegig a userdata->curr_class->color_names tombon, minden
00765           // nevet kikeresni az attrs-bol, ha megvan kiolvasni, ha nincs 0L
00766           // kitolteni a userdata->curr_state->colormap[i] -t
00767           if(userdata->curr_class->color_names!=NULL)
00768           {
00769             for(i=0;userdata->curr_class->color_names[i]!=NULL;i++)
00770             {
00771               if(NULL!=(att=common_GetAttr(atts,userdata->curr_class->color_names[i])))
00772               {
00773                 sscanf(att,"#%lx",&userdata->curr_state->colormap[i]);
00774               }
00775             }
00776           }
00777           else debug_Error("Gadget class '%s' has no colormap!",userdata->curr_class->class_name);
00778         }
00779         break;
00780       }
00781       default:
00782       {
00783         debug_Error("Unknown processing state, internal error");
00784         break;
00785       }
00786     }
00787   }
00788 
00789   debug_End();
00790 }
00791 
00792 
00793 static void bordered_EndElement(void *userData, const char *name)
00794 {
00795   struct bordered_xml_userdata *userdata=(struct bordered_xml_userdata *)userData;
00796   struct bordered_gadget *gad;
00797   int j,h,v;
00798 
00799   debug_Begin();
00800 
00801   userdata->level--;
00802   if(userdata->skiplevel==userdata->level) userdata->skiplevel=-1;
00803   if(userdata->state==SKNF_INBORDER&&strcmp(name,"Border")==0) userdata->state=SKNF_SKINFOUND;
00804   else if(userdata->state==SKNF_INGADGET&&strcmp(name,"Gadget")==0)
00805   {
00806     gad=userdata->curr_gadget;
00807     gad->horizontal=gad->vertical=-1;
00808     for(j=0;j<GADST_COUNT;j++)
00809     {
00810       if(gad->states[j].status!=0&&gad->states[j].border!=NULL)
00811       {
00812         h=gad->states[j].border->left+gad->states[j].border->right;
00813         v=gad->states[j].border->top+gad->states[j].border->bottom;
00814         if((gad->horizontal>=0&&h!=gad->horizontal)||(gad->vertical>=0&&v!=gad->vertical))
00815         {
00816           h=v=0;
00817           debug_Error("Illegal border sizes");
00818         }
00819         gad->horizontal=h;
00820         gad->vertical=v;
00821       }
00822     }
00823     if(gad->horizontal<0) gad->horizontal=gad->vertical=0;
00824     userdata->state=SKNF_SKINFOUND;
00825   }
00826   else if(userdata->state==SKNF_INSTATE&&strcmp(name,userdata->statename)==0) userdata->state=SKNF_INGADGET;
00827 
00828   debug_End();
00829 }
00830 
00831 
00832 /****************************************************************************************
00833  * interface functions
00834  ****************************************************************************************/
00835 
00836 
00837 static Skin_t *bordered_CreateSkin(gui_App_t *app, char *path)
00838 {
00839   Skin_t *ret=NULL,*skin;
00840   XML_Parser ctxt;
00841   struct bordered_xml_userdata userdata;
00842   int xmlret;
00843   char *file=NULL,*fnam;
00844 
00845   debug_Begin();
00846 
00847   memset(&userdata,0,sizeof(struct bordered_xml_userdata));
00848   if(path!=NULL&&app!=NULL&&NULL!=(skin=mem_malloc(sizeof(Skin_t))))
00849   {
00850     if(NULL!=(fnam=mem_malloc(strlen(path)+1+11)))
00851     {
00852       skin->app=app;
00853       skin->path=common_strdup(path);
00854       strcpy(fnam,path);
00855       strcat(fnam,"Default.xml");
00856       file=(char *)api->net_Call(NET_LOADFILE,TAG_NET_CONN,app->conn,TAG_NET_NAME,fnam,TAG_DONE);
00857       mem_free(fnam);
00858       if(NULL!=(skin->imagelist=list_CreateList()))
00859       {
00860         if(NULL!=(skin->borderlist=list_CreateList()))
00861         {
00862           if(NULL!=(skin->classlist=list_CreateList()))
00863           {
00864             ret=skin;
00865             if(file!=NULL)
00866             {
00867               if((ctxt=XML_ParserCreate(NULL)))
00868               {
00869                 userdata.state=SKNF_BEGIN;
00870                 userdata.skin=skin;
00871                 userdata.skiplevel=-1;
00872                 XML_SetUserData(ctxt,&userdata);
00873                 XML_SetElementHandler(ctxt,bordered_StartElement,bordered_EndElement);
00874                 xmlret=XML_Parse(ctxt,file,strlen(file),TRUE);
00875                 if(!xmlret)
00876                 {
00877                   debug_Error("%s at line %d\n",XML_ErrorString(XML_GetErrorCode(ctxt)),XML_GetCurrentLineNumber(ctxt));
00878                   ret=NULL;
00879                 }
00880                 XML_ParserFree(ctxt);
00881               }
00882             }
00883           }
00884         }
00885       }
00886       if(file!=NULL) mem_free(file);
00887     }
00888   }
00889 
00890   debug_End();
00891 
00892   return(ret);
00893 }
00894 
00895 
00896 static void bordered_DeleteSkin(Skin_t *skin)
00897 {
00898   struct bordered_border *border;
00899   struct bordered_gadget *gad,*nextgad;
00900   struct bordered_image *image;
00901   Node_t *node;
00902   int j;
00903 
00904   debug_Begin();
00905 
00906   if(skin!=NULL)
00907   {
00908     if(skin->borderlist!=NULL)
00909     {
00910       while(NULL!=(node=list_RemoveNodeHead(skin->borderlist)))
00911       {
00912         if(NULL!=(border=(struct bordered_border *)list_GetNodeData(node)))
00913         {
00914           debug_Message("remove border '%s'",border->name);
00915           if(border->name!=NULL) mem_free(border->name);
00916           border->name=NULL;
00917           mem_free(border);
00918         }
00919         list_DeleteNode(node);
00920       }
00921       list_DeleteList(skin->borderlist);
00922     }
00923     if(skin->classlist!=NULL)
00924     {
00925       while(NULL!=(node=list_RemoveNodeHead(skin->classlist)))
00926       {
00927         gad=(struct bordered_gadget *)list_GetNodeData(node);
00928         while(gad!=NULL)
00929         {
00930           nextgad=gad->next;
00931           if(gad->custom!=NULL) mem_free(gad->custom);
00932           for(j=0;j<GADST_COUNT;j++)
00933           {
00934             if(gad->states[j].status!=0)
00935             {
00936               if(gad->states[j].colormap!=NULL) mem_free(gad->states[j].colormap);
00937             }
00938           }
00939           if(gad->font_name!=NULL) mem_free(gad->font_name);
00940           gad->font_name=NULL;
00941           if(gad->font!=0L) api->glw_Call(GLW_CLOSEFONT,TAG_GLW_FONT,gad->font,TAG_DONE);
00942           gad->font=0L;
00943           if(gad->taglist!=NULL) mem_free(gad->taglist);
00944           mem_free(gad);
00945           gad=nextgad;
00946         }
00947         list_DeleteNode(node);
00948       }
00949       list_DeleteList(skin->classlist);
00950     }
00951     if(skin->imagelist!=NULL)
00952     {
00953       while(NULL!=(node=list_RemoveNodeHead(skin->imagelist)))
00954       {
00955         if(NULL!=(image=list_GetNodeData(node)))
00956         {
00957           if(image->imgname!=NULL) mem_free(image->imgname);
00958           if(image->img!=NULL) api->img_Call(IMG_CLEANUPIMAGE,TAG_IMG_OBJECT,image->img,TAG_DONE);
00959           mem_free(image);
00960         }
00961         list_DeleteNode(node);
00962       }
00963       list_DeleteList(skin->imagelist);
00964     }
00965     if(skin->path!=NULL) mem_free(skin->path);
00966     mem_free(skin);
00967   }
00968 
00969   debug_End();
00970 }
00971 
00972 
00973 /****************************************************************************************
00974  * interface rendering functions
00975  ****************************************************************************************/
00976 
00977 
00978 static void bordered_RenderImgOrCol(Skin_t *skin, Window_t *window, struct bordered_imgorcol *ic, Rect_t *rect, u32 transparent_color)
00979 {
00980   Bitmap_t *bmp=NULL;
00981 
00982   debug_Begin();
00983 
00984   if(ic->image!=NULL)
00985   {
00986     if(ic->image->img==NULL)
00987     {
00988       if(NULL!=(ic->image->img=(Image_t *)api->img_Call(IMG_INITIMAGE,TAG_IMG_APP,skin->app,TAG_IMG_IMAGENAME,ic->image->imgname,TAG_DONE)))
00989       {
00990         ImageInfo_t imginfo;
00991         if(0==api->img_Call(IMG_GETINFO,TAG_IMG_OBJECT,ic->image->img,TAG_IMG_IMGINFO,&imginfo,TAG_DONE))
00992         {
00993           ic->image->minwidth=imginfo.minwidth;
00994           ic->image->maxwidth=imginfo.maxwidth;
00995           ic->image->minheight=imginfo.minheight;
00996           ic->image->maxheight=imginfo.maxheight;
00997         }
00998       }
00999     }
01000     if(transparent_color==~0L)
01001     {
01002       debug_Message("opaque image: '%s'",ic->image->imgname);
01003       if(ic->image->minwidth<=rect->width&&ic->image->minheight<=rect->height &&
01004          ic->image->maxwidth>=rect->width&&ic->image->maxheight>=rect->height)
01005       {
01006         api->img_Call(IMG_PUTIMAGE,TAG_IMG_OBJECT,ic->image->img,TAG_IMG_WINDOW,window,TAG_IMG_RECT,rect,TAG_DONE);
01007       }
01008       else
01009       {
01010         api->img_Call(IMG_PUTIMAGETILED,
01011                   TAG_IMG_OBJECT,ic->image->img,
01012                   TAG_IMG_WINDOW,window,
01013                   TAG_IMG_IMGWIDTH,ic->image->minwidth,
01014                   TAG_IMG_IMGHEIGHT,ic->image->minheight,
01015                   TAG_IMG_RECT,rect,
01016                   TAG_DONE);
01017       }
01018     }
01019     else
01020     {
01021       u8 *buff;
01022       int buffsize,rt=~0L;
01023 
01024       debug_Message("transparent image: '%s'",ic->image->imgname);
01025       buffsize=(rect->width*rect->height*4)+1;
01026       if(NULL!=(buff=mem_malloc(buffsize)))
01027       {
01028         if(ic->image->minwidth<=rect->width&&ic->image->minheight<=rect->height &&
01029            ic->image->maxwidth>=rect->width&&ic->image->maxheight>=rect->height)
01030         {
01031           rt=api->img_Call(IMG_RENDERIMAGE,TAG_IMG_OBJECT,ic->image->img,TAG_IMG_DEST,buff,TAG_IMG_DESTSIZE,buffsize,TAG_IMG_WIDTH,rect->width,TAG_IMG_HEIGHT,rect->height,TAG_DONE);
01032         }
01033         else
01034         {
01035           rt=api->img_Call(IMG_RENDERIMAGETILED,
01036                     TAG_IMG_OBJECT,ic->image->img,
01037                     TAG_IMG_DEST,buff,
01038                     TAG_IMG_DESTSIZE,buffsize,
01039                     TAG_IMG_WIDTH,rect->width,
01040                     TAG_IMG_HEIGHT,rect->height,
01041                     TAG_IMG_IMGWIDTH,ic->image->minwidth,
01042                     TAG_IMG_IMGHEIGHT,ic->image->minheight,
01043                     TAG_DONE);
01044         }
01045         if(rt==0L)
01046         {
01047           Vector_t vec;
01048           bmp=(Bitmap_t *)api->bitmap_Call(BITMAP_CREATE,
01049                                           TAG_BMP_INITTYPE,BMP_ITY_RGB,
01050                                           TAG_BMP_WIDTH,rect->width,
01051                                           TAG_BMP_HEIGHT,rect->height,
01052                                           TAG_BMP_VECTOR,buff,
01053                                           TAG_BMP_VALUE,transparent_color,
01054                                           TAG_DONE);
01055           vec.data=buff;
01056           vec.size=buffsize;
01057           api->glw_Call(GLW_PUTIMAGE,TAG_GLW_WINDOW,window->handle,TAG_GLW_PIXELS,&vec,TAG_GLW_CLIPRECT,rect,TAG_GLW_LEFT,rect->left,TAG_GLW_TOP,rect->top,TAG_GLW_WIDTH,rect->width,TAG_GLW_HEIGHT,rect->height,TAG_DONE);
01058         }
01059         mem_free(buff);
01060       }
01061     }
01062   }
01063   else if(ic->color!=~0L)
01064   {
01065     if(transparent_color!=~0L&&(ic->color&0x00ffffff)==transparent_color)
01066     {
01067       bmp=(Bitmap_t *)api->bitmap_Call(BITMAP_CREATE,
01068                                       TAG_BMP_INITTYPE,BMP_ITY_FILL,
01069                                       TAG_BMP_WIDTH,rect->width,
01070                                       TAG_BMP_HEIGHT,rect->height,
01071                                       TAG_BMP_VALUE,0,
01072                                       TAG_DONE);
01073     }
01074     else
01075     {
01076       api->glw_Call(GLW_SETCOLOR,TAG_GLW_WINDOW,window->handle,TAG_GLW_RGB,ic->color,TAG_DONE);
01077       api->glw_Call(GLW_DRAWFILLEDRECT,TAG_GLW_WINDOW,window->handle,TAG_GLW_LEFT,rect->left,TAG_GLW_TOP,rect->top,TAG_GLW_WIDTH,rect->width,TAG_GLW_HEIGHT,rect->height,TAG_DONE);
01078     }
01079   }
01080   if(bmp!=NULL)
01081   {
01082     api->window_Call(WINDOW_ADDMASK,TAG_WIN_OBJECT,window,
01083                                     TAG_WIN_X,rect->left,
01084                                     TAG_WIN_Y,rect->top,
01085                                     TAG_WIN_BITMAP,bmp,
01086                                     TAG_DONE);
01087     api->bitmap_Call(BITMAP_DELETE,TAG_BMP_OBJECT,bmp,TAG_DONE);
01088   }
01089 
01090   debug_End();
01091 }
01092 
01093 
01094 static int bordered_RenderBorder(Skin_t *skin, struct bordered_border *b, Gadget_t *gad, Rect_t *rect, u32 transparent_color)
01095 {
01096   int ret=-1,i;
01097   Rect_t brect;
01098 
01099   debug_Begin();
01100 
01101   for(i=0;i<8;i++)
01102   {
01103     if(i==SKNBP_BARTOP)                               // 0    000
01104     {
01105       brect.left=b->left;
01106       brect.top=0;
01107       brect.width=rect->width-b->left-b->right;
01108       brect.height=b->top;
01109     }
01110     else if(i==SKNBP_BARLEFT)                         // 1    001
01111     {
01112       brect.left=0;
01113       brect.top=b->top;
01114       brect.width=b->left;
01115       brect.height=rect->height-b->top-b->bottom;
01116     }
01117     else if(i==SKNBP_BARRIGHT)                        // 2    010
01118     {
01119       brect.left=rect->width-b->right;
01120       brect.top=b->top;
01121       brect.width=b->right;
01122       brect.height=rect->height-b->top-b->bottom;
01123     }
01124     else if(i==SKNBP_BARBOTTOM)                       // 3    011
01125     {
01126       brect.left=b->left;
01127       brect.top=rect->height-b->bottom;
01128       brect.width=rect->width-b->left-b->right;
01129       brect.height=b->bottom;
01130     }
01131     else if(i==SKNBP_CORNERTOPLEFT)                   // 4    100
01132     {
01133       brect.left=0;
01134       brect.top=0;
01135       brect.width=b->left;
01136       brect.height=b->top;
01137     }
01138     else if(i==SKNBP_CORNERTOPRIGHT)                  // 5    101
01139     {
01140       brect.left=rect->width-b->right;
01141       brect.top=0;
01142       brect.width=b->right;
01143       brect.height=b->top;
01144     }
01145     else if(i==SKNBP_CORNERBOTTOMLEFT)                // 6    110
01146     {
01147       brect.left=0;
01148       brect.top=rect->height-b->bottom;
01149       brect.width=b->left;
01150       brect.height=b->bottom;
01151     }
01152     else                                              // 7    111
01153     {
01154       brect.left=rect->width-b->right;
01155       brect.top=rect->height-b->bottom;
01156       brect.width=b->right;
01157       brect.height=b->bottom;
01158     }
01159     brect.left+=rect->left;
01160     brect.top+=rect->top;
01161     bordered_RenderImgOrCol(skin,gad->window,&b->borders[i],&brect,transparent_color);
01162   }
01163 
01164   debug_End();
01165 
01166   return(ret);
01167 }
01168 
01169 
01170 static int bordered_RenderBackground(Skin_t *skin, Gadget_t *gad, Rect_t *rect, u32 state)
01171 {
01172   int ret=-1;
01173   struct bordered_gadget *sgad;
01174   Rect_t brect;
01175   int gadstate;
01176 
01177   debug_Begin();
01178 
01179   debug_Message("gadget_id: 0x%08lx",gad->gadget_id);
01180   if(skin!=NULL&&gad!=NULL&&rect!=NULL&&NULL!=(sgad=gad->skin))
01181   {
01182     gadstate=(int)api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,gad,TAG_DONE);
01183     memcpy(&brect,rect,sizeof(Rect_t));
01184     if(NULL!=sgad->states[gadstate].border)
01185     {
01186       brect.width-=sgad->horizontal;
01187       brect.height-=sgad->vertical;
01188       brect.left+=sgad->states[gadstate].border->left;
01189       brect.top+=sgad->states[gadstate].border->top;
01190     }
01191     bordered_RenderImgOrCol(skin,gad->window,&sgad->states[gadstate].background,&brect,sgad->transparent_color);
01192     ret=0;
01193   }
01194 
01195   debug_End();
01196 
01197   return(ret);
01198 }
01199 
01200 
01201 static int bordered_RenderBehind(Skin_t *skin, Gadget_t *gad, Rect_t *rect, u32 state)
01202 {
01203   int ret=-1;
01204   struct bordered_gadget *sgad;
01205   struct bordered_border *border;
01206   Rect_t brect;
01207   int gadstate;
01208 
01209   debug_Begin();
01210 
01211   debug_Message("gadget_id: 0x%08lx",gad->gadget_id);
01212   if(skin!=NULL&&gad!=NULL&&rect!=NULL)
01213   {
01214     ret=0;
01215     memcpy(&brect,rect,sizeof(Rect_t));
01216     if(NULL!=(sgad=gad->skin))
01217     {
01218       gadstate=(int)api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,gad,TAG_DONE);
01219       brect.width-=sgad->horizontal;
01220       brect.height-=sgad->vertical;
01221       if(NULL!=(border=sgad->states[gadstate].border))
01222       {
01223         brect.left+=border->left;
01224         brect.top+=border->top;
01225         if(0!=bordered_RenderBorder(skin,border,gad,rect,sgad->transparent_color)) ret=-1;
01226       }
01227       bordered_RenderImgOrCol(skin,gad->window,&sgad->states[gadstate].background,&brect,sgad->transparent_color);
01228     }
01229   }
01230 
01231   debug_End();
01232 
01233   return(ret);
01234 }
01235 
01236 
01237 static int bordered_RenderOver(Skin_t *skin, Gadget_t *gad, Rect_t *rect, u32 state)
01238 {
01239   int ret=-1;
01240 
01241   debug_Begin();
01242 
01243   if(skin!=NULL&&gad!=NULL&&rect!=NULL)
01244   {
01245     ret=0;
01246   }
01247 
01248   debug_End();
01249 
01250   return(ret);
01251 }
01252 
01253 
01254 static int bordered_RenderCustom(Skin_t *skin, Gadget_t *gad, Rect_t *rect, int custom)
01255 {
01256   int ret=-1;
01257   struct bordered_gadget *sgad;
01258   struct bordered_border *border;
01259   Rect_t brect;
01260 
01261   debug_Begin();
01262 
01263   if(skin!=NULL&&gad!=NULL&&rect!=NULL&&custom<gad->class_data->custom_count)
01264   {
01265     ret=0;
01266     memcpy(&brect,rect,sizeof(Rect_t));
01267     if(NULL!=(sgad=gad->skin))
01268     {
01269       if(NULL!=(border=sgad->custom[custom].border))
01270       {
01271         brect.width-=border->left+border->right;
01272         brect.height-=border->top+border->bottom;
01273         brect.left+=border->left;
01274         brect.top+=border->top;
01275         if(0!=bordered_RenderBorder(skin,border,gad,rect,sgad->transparent_color)) ret=-1;
01276       }
01277       bordered_RenderImgOrCol(skin,gad->window,&sgad->custom[custom].background,&brect,sgad->transparent_color);
01278     }
01279   }
01280 
01281   debug_End();
01282 
01283   return(ret);
01284 }
01285 
01286 
01287 /****************************************************************************************
01288  * interface misc functions
01289  ****************************************************************************************/
01290 
01291 
01292 static u32 bordered_GetFont(Skin_t *skin, Gadget_t *gad)
01293 {
01294   u32 ret=0L;
01295   struct bordered_gadget *sgad;
01296   u32 font_flags=0L;
01297 
01298   debug_Begin();
01299 
01300   if(skin!=NULL&&gad!=NULL)
01301   {
01302     if(NULL!=(sgad=gad->skin))
01303     {
01304       ret=sgad->font;
01305       if(ret==0L)
01306       {
01307         if(sgad->font_name!=NULL)
01308         {
01309           if(sgad->font_style==GADGET_FONTSTYLE_ITALIC) font_flags|=GLWFS_ITALIC;
01310           if(sgad->font_weight==GADGET_FONTWEIGHT_BOLD) font_flags|=GLWFS_BOLD;
01311           if(sgad->font_decoration==GADGET_FONTDECORATION_UNDERLINED) font_flags|=GLWFS_UNDERLINE;
01312           ret=sgad->font=api->glw_Call(GLW_OPENFONT,TAG_GLW_CONN,skin->app->conn,TAG_GLW_FACE,sgad->font_name,TAG_GLW_SIZE,sgad->font_size,TAG_GLW_STYLE,font_flags,TAG_DONE);
01313           mem_free(sgad->font_name);
01314           sgad->font_name=NULL;
01315         }
01316       }
01317     }
01318   }
01319 
01320   debug_End();
01321 
01322   return(ret);
01323 }
01324 
01325 
01326 static int bordered_GetExtent(Skin_t *skin, Gadget_t *gad, Extent_t *ext, Extent_t *outer)
01327 {
01328   int ret=-1;
01329   struct bordered_gadget *sgad;
01330 
01331   debug_Begin();
01332 
01333   if(skin!=NULL&&gad!=NULL&&ext!=NULL&&outer!=NULL)
01334   {
01335     debug_Message("gadget_id: 0x%08lx",gad->gadget_id);
01336     outer->width=ext->width;
01337     outer->height=ext->height;
01338     if(NULL!=(sgad=gad->skin))
01339     {
01340       debug_Message("  ext: %dx%d .. horiz=%d vert=%d",ext->width,ext->height,sgad->horizontal,sgad->vertical);
01341       outer->width+=sgad->horizontal;
01342       outer->height+=sgad->vertical;
01343     }
01344     ret=0;
01345   }
01346 
01347   debug_End();
01348 
01349   return(ret);
01350 }
01351 
01352 
01353 static int bordered_GetInnerRect(Skin_t *skin, Gadget_t *gad, Rect_t *rect, Rect_t *inner)
01354 {
01355   int ret=-1;
01356   struct bordered_gadget *sgad;
01357   struct bordered_border *border;
01358   int gadstate;
01359 
01360   debug_Begin();
01361 
01362   if(skin!=NULL&&gad!=NULL&&rect!=NULL&&inner!=NULL)
01363   {
01364     debug_Message("gadget_id: 0x%08lx",gad->gadget_id);
01365     gadstate=(int)api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,gad,TAG_DONE);
01366     memcpy(inner,rect,sizeof(Rect_t));
01367     if(NULL!=(sgad=gad->skin)&&NULL!=(border=sgad->states[gadstate].border))
01368     {
01369       debug_Message("  rect=%d.%d.%dx%d   border-left=%d border-top=%d horiz=%d vert=%d",rect->left,rect->top,rect->width,rect->height,border->left,border->top,sgad->horizontal,sgad->vertical);
01370       inner->left+=border->left;
01371       inner->top+=border->top;
01372       inner->width-=sgad->horizontal;
01373       inner->height-=sgad->vertical;
01374     }
01375     ret=0;
01376   }
01377 
01378   debug_End();
01379 
01380   return(ret);
01381 }
01382 
01383 
01384 static struct bordered_gadget *bordered_SearchGadget(Skin_t *skin, u32 class_id, u32 namecrc)
01385 {
01386   struct bordered_gadget *ret=NULL,*def=NULL;
01387   Node_t *node;
01388 
01389   debug_Begin();
01390 
01391   for(node=list_GetNodeHead(skin->classlist);node!=NULL;node=list_GetNodeNext(skin->classlist,node))
01392   {
01393     if(NULL!=(ret=list_GetNodeData(node))&&class_id==ret->class_id)
01394     {
01395       while(ret!=NULL)
01396       {
01397         if(ret->namecrc==namecrc) break;
01398         if(ret->namecrc==0L) def=ret;
01399         ret=ret->next;
01400       }
01401       if(ret!=NULL) break;
01402     }
01403     else ret=NULL;
01404   }
01405   if(ret==NULL) ret=def;
01406 
01407   debug_End();
01408 
01409   return(ret);
01410 }
01411 
01412 
01413 static int bordered_FillGadgetInfo(Skin_t *skin, Gadget_t *gad)
01414 {
01415   int ret=-1;
01416   struct bordered_gadget *sgad;
01417 
01418   debug_Begin();
01419 
01420   if(skin!=NULL&&gad!=NULL)
01421   {
01422     if(NULL!=(sgad=bordered_SearchGadget(skin,gad->class_data->class_id,gad->skincrc)))
01423     {
01424       gad->skin=sgad;
01425       //if(gad->font==0L) gad->font=sgad->font;
01426     }
01427     else gad->skin=NULL;
01428     ret=0;
01429   }
01430 
01431   debug_End();
01432 
01433   return(ret);
01434 }
01435 
01436 
01437 static int bordered_FillColorTable(Skin_t *skin, Gadget_t *gad, int state)
01438 {
01439   int ret=-1,i;
01440   struct bordered_gadget *sgad;
01441 
01442   debug_Begin();
01443 
01444   if(skin!=NULL&&gad!=NULL)
01445   {
01446     if(NULL!=(sgad=bordered_SearchGadget(skin,gad->class_data->class_id,gad->skincrc)))
01447     {
01448       for(i=0;i<gad->class_data->color_count;i++)
01449       {
01450         gad->color_table[state][i]=sgad->states[state].colormap[i];
01451       }
01452       ret=0;
01453     }
01454   }
01455 
01456   debug_End();
01457 
01458   return(ret);
01459 }
01460 
01461 
01462 static int bordered_LoadSkin(Skin_t *skin, char *class)
01463 {
01464   int ret=-1;
01465   XML_Parser ctxt;
01466   struct bordered_xml_userdata userdata;
01467   int xmlret;
01468   char *file=NULL,*fnam;
01469 
01470   debug_Begin();
01471 
01472   //NEWSKIN: todo
01473   // skinfile = skin->path + "skin_" + class + ".xml"
01474   // load this file: skin_file=(char *)api->net_Call(NET_LOADFILE,TAG_NET_CONN,app->conn,TAG_NET_NAME,skinfile,TAG_NET_LEN,&file_size,TAG_DONE)
01475   // parse it, and create runtime data (load pictures, build the usual structures)
01476   memset(&userdata,0,sizeof(struct bordered_xml_userdata));
01477   if(skin!=NULL&&class!=NULL&&NULL!=(fnam=mem_malloc(strlen(skin->path)+1+5+4+strlen(class))))
01478   {
01479     debug_Message("load req: '%s'",class);
01480     strcpy(fnam,skin->path);
01481     strcat(fnam,"skin_");
01482     strcat(fnam,class);
01483     strcat(fnam,".xml");
01484     file=(char *)api->net_Call(NET_LOADFILE,TAG_NET_CONN,skin->app->conn,TAG_NET_NAME,fnam,TAG_DONE);
01485     mem_free(fnam);
01486     if(file!=NULL)
01487     {
01488       if((ctxt=XML_ParserCreate(NULL)))
01489       {
01490         userdata.state=SKNF_BEGIN;
01491         userdata.skin=skin;
01492         userdata.skiplevel=-1;
01493         XML_SetUserData(ctxt,&userdata);
01494         XML_SetElementHandler(ctxt,bordered_StartElement,bordered_EndElement);
01495         xmlret=XML_Parse(ctxt,file,strlen(file),TRUE);
01496         if(!xmlret) debug_Error("%s at line %d\n",XML_ErrorString(XML_GetErrorCode(ctxt)),XML_GetCurrentLineNumber(ctxt));
01497         else ret=0;
01498         XML_ParserFree(ctxt);
01499       }
01500     }
01501     if(file!=NULL) mem_free(file);
01502   }
01503 
01504   debug_End();
01505 
01506   return(ret);
01507 }
01508 
01509 
01510 static int bordered_UnloadSkin(Skin_t *skin, u32 class_id)
01511 {
01512   int ret=-1,j;
01513   struct bordered_gadget *gad,*nextgad;
01514 
01515   debug_Begin();
01516 
01517   if(skin!=NULL)
01518   {
01519     debug_Message("unload req class_id %ldL",class_id);
01520     if(NULL!=(gad=bordered_SeekClass(skin->classlist,class_id)))
01521     {
01522       list_RemoveNode(skin->classlist,gad->node);
01523       list_DeleteNode(gad->node);
01524       while(gad!=NULL)
01525       {
01526         nextgad=gad->next;
01527         if(gad->custom!=NULL)
01528         {
01529           // background-okat
01530           for(j=0;j<gad->custom_count;j++)
01531           {
01532             if(NULL!=gad->custom[j].background.image) bordered_DeleteImage(skin->imagelist,gad->custom[j].background.image);
01533             if(NULL!=gad->custom[j].border) bordered_DeleteBorder(skin,gad->custom[j].border);
01534           }
01535           mem_free(gad->custom);
01536         }
01537         for(j=0;j<GADST_COUNT;j++)
01538         {
01539           if(gad->states[j].status!=0)
01540           {
01541             if(NULL!=gad->states[j].colormap) mem_free(gad->states[j].colormap);
01542             if(NULL!=gad->states[j].background.image) bordered_DeleteImage(skin->imagelist,gad->states[j].background.image);
01543             if(NULL!=gad->states[j].border) bordered_DeleteBorder(skin,gad->states[j].border);
01544           }
01545         }
01546         if(gad->font_name!=NULL) mem_free(gad->font_name);
01547         gad->font_name=NULL;
01548         if(gad->font!=0L) api->glw_Call(GLW_CLOSEFONT,TAG_GLW_FONT,gad->font,TAG_DONE);
01549         gad->font=0L;
01550         if(gad->taglist!=NULL) mem_free(gad->taglist);
01551         mem_free(gad);
01552         gad=nextgad;
01553       }
01554     }
01555     ret=0;
01556   }
01557 
01558   debug_End();
01559 
01560   return(ret);
01561 }
01562 
01563 
01564 static u32 bordered_GetCustomTaglist(Skin_t *skin, Gadget_t *gad)
01565 {
01566   tag *ret=NULL;
01567   struct bordered_gadget *sgad;
01568 
01569   debug_Begin();
01570 
01571   if(skin!=NULL&&gad!=NULL)
01572   {
01573     if(NULL!=(sgad=gad->skin))
01574     {
01575       ret=sgad->taglist;
01576     }
01577   }
01578 
01579   debug_End();
01580 
01581   return((u32)ret);
01582 }
01583 
01584 
01585 /****************************************************************************************
01586  * system part
01587  ****************************************************************************************/
01588 
01589 
01590 static int skin_bordered_Init(u32 module)
01591 {
01592   int ret=-1;
01593 
01594   debug_Begin();
01595 
01596   ret=api->skin_Call(SKIN_REGISTERSKIN,
01597                       TAG_SKIN_NAME,"Bordered",
01598                       TAG_SKIN_MODULE,module,
01599                       TAG_SKIN_CREATESKIN,bordered_CreateSkin,
01600                       TAG_SKIN_DELETESKIN,bordered_DeleteSkin,
01601                       TAG_SKIN_RENDERBEHIND,bordered_RenderBehind,
01602                       TAG_SKIN_RENDEROVER,bordered_RenderOver,
01603                       TAG_SKIN_RENDERBACKGROUND,bordered_RenderBackground,
01604                       TAG_SKIN_RENDERCUSTOM,bordered_RenderCustom,
01605                       TAG_SKIN_GETEXTENT,bordered_GetExtent,
01606                       TAG_SKIN_GETINNERRECT,bordered_GetInnerRect,
01607                       TAG_SKIN_FILLCOLORTABLE,bordered_FillColorTable,
01608                       TAG_SKIN_FILLGADGETINFO,bordered_FillGadgetInfo,
01609                       TAG_SKIN_GETFONT,bordered_GetFont,
01610                       TAG_SKIN_LOADSKIN,bordered_LoadSkin,
01611                       TAG_SKIN_UNLOADSKIN,bordered_UnloadSkin,
01612                       TAG_SKIN_GETCUSTOMTAGLIST,bordered_GetCustomTaglist,
01613                       TAG_DONE);
01614 
01615   debug_End();
01616 
01617   return(ret);
01618 }
01619 
01620 
01621 EXPORT int module_Init(u32 module, bases_Modules_t *bases)
01622 {
01623     api=bases;
01624     return(skin_bordered_Init(module));
01625 }
01626 
01627  

Generated on Tue Jan 7 12:11:23 2003 for THEGUI by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002