Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

xml_Gui.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 // xml_Gui.h
00025 
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <xmlparse.h>
00029 
00030 #include "debug.h"
00031 #include "macros.h"
00032 #include "Common.h"
00033 #include "Memory.h"
00034 #include "Locale.h"
00035 #include "Skin.h"
00036 #include "Window.h"
00037 
00038 #include "xml_Gui.h"
00039 
00040 
00041 #define GXML_MAXIMUM_LEVEL  64
00042 #define GXML_TAGLISTSIZE    32
00043 
00044 struct gxml_GadgetInfo
00045 {
00046   u32 gadget_id;
00047   char *class_name;
00048 };
00049 
00050 
00051 struct gxml_UserData
00052 {
00053   Gadget_t *tree;
00054   int level;
00055   int status;
00056   char *layoutname;
00057   char *layouttype;
00058   Window_t *window;
00059   gadget_Check_t *check;
00060   List_t *gadget_list;
00061   int err;
00062   gadget_Binding_t *commonbind;
00063   char *appname;
00064   Locale_t *locale;
00065   u32 gadget_id_base;
00066   Gadget_t *gadgets[GXML_MAXIMUM_LEVEL];
00067   tag taglist[GXML_TAGLISTSIZE];
00068 };
00069 
00070 
00071 #define ERR_NONE                  0
00072 #define ERR_OUT_OF_MEMORY         1
00073 #define ERR_INVALID_DATATYPE      2
00074 #define ERR_CANT_CREATE_GADGET    3
00075 #define ERR_TOO_DEEP_HIERARCHY    4
00076 #define ERR_ILLEGAL_CLASS         5
00077 #define ERR_VALIDATE_ERROR        6
00078 #define ERR_XML_ERROR             7
00079 #define ERR_REQUIRED_MISSING      8
00080 #define ERR_TYPE_MISMATCH         9
00081 
00082 
00083 static u32 (*call_vector[GXML_FUNC_DONE-GXML_FUNCBASE+1])(tag *);
00084 
00085 
00086 #if DEBUG_LEVEL >= 1
00087 static char *errstr[]=
00088 {
00089   "OK",
00090   "Out of memory",
00091   "Invalid datatype",
00092   "Can't create gadget",
00093   "Too deep hierarchy",
00094   "Illegal class",
00095   "Validate error",
00096   "XML error",
00097   "Required ID missing",
00098   "Type mismatch",
00099   NULL
00100 };
00101 #endif
00102 
00103 
00104 static int gxml_HandleAttr(struct gxml_UserData *u, tag *curr_tag, char *name, char *value, gadget_Binding_t *bind)
00105 {
00106   debug_Begin();
00107 
00108   curr_tag->Name=TAG_SKIP;
00109   if(u->commonbind!=NULL) gadget_Bind(TAG_GADGET_LOCALE,u->locale,TAG_GADGET_BINDING,u->commonbind,
00110               TAG_GADGET_NAME,name,TAG_GADGET_VALUE,value,TAG_GADGET_TAGNAME,&curr_tag->Name,
00111               TAG_GADGET_TAGVALUE,&curr_tag->Data,TAG_DONE);
00112   if(curr_tag->Name==TAG_SKIP) gadget_Bind(TAG_GADGET_LOCALE,u->locale,TAG_GADGET_BINDING,bind,
00113               TAG_GADGET_NAME,name,TAG_GADGET_VALUE,value,TAG_GADGET_TAGNAME,&curr_tag->Name,
00114               TAG_GADGET_TAGVALUE,&curr_tag->Data,TAG_DONE);
00115 
00116   debug_End();
00117 
00118   return(1);
00119 }
00120 
00121 
00122 static void gxml_StartElement(void *userData, const char *name, const char **atts)
00123 {
00124   struct gxml_UserData *u=(struct gxml_UserData *)userData;
00125   int i,_w,_i,tagindex;
00126   char *id,*app,*type;
00127   gadget_Descriptor_t dsc;
00128   gadget_ClassData_t *gadget_class;
00129   Gadget_t *parent;
00130   gadget_Binding_t *bind;
00131   Node_t *node;
00132   struct gxml_GadgetInfo *ginfo;
00133 
00134   debug_Begin();
00135 
00136   u->level++;
00137 //printf("START> %s\n",name);
00138   if(u->status==0)
00139   {
00140     if((strcmp(name,"Gui")==0))
00141     {
00142       if(u->appname!=NULL)
00143       {
00144         if(NULL!=(app=common_GetAttr(atts,"App")))
00145         {
00146 //printf("  FOUND gui name '%s'\n",app);
00147           if(strcmp(u->appname,app)==0) u->status=1;
00148         }
00149         else u->status=1;
00150       }
00151       else  u->status=1;
00152     }
00153   }
00154   else if(u->status==1)
00155   {
00156     if((strcmp(name,"Layout")==0)&&NULL!=(id=common_GetAttr(atts,"id"))&&NULL!=(type=common_GetAttr(atts,"type")))
00157     {
00158       if(strcmp(id,u->layoutname)==0)
00159       {
00160         if(NULL==u->layouttype||0==strcmp(type,u->layouttype))
00161 //printf("  FOUND window name '%s'\n",id);
00162         if(NULL!=u->layouttype)
00163         {
00164           if(strcmp(type,"system")==0) u->gadget_id_base=GADGET_SYSBASE;
00165           else if(strcmp(type,"gadget")==0) u->gadget_id_base=GADGET_SUBGADGET_BASE;
00166         }
00167         u->status=2;
00168       }
00169     }
00170   }
00171   else if(u->status>1)
00172   {
00173     dsc.level=u->level-3;
00174     dsc.class_name=(char *)name;
00175     //NEWSKIN: Ha meg nincs regisztralva a class (NULL==gadget_FindClassByName) akkor
00176     //NEWSKIN: itt kell a dsc.class_name-t betolteni OpenModule()
00177     //NEWSKIN:   ha nem sikerul, akkor elkerjuk a klienstol!
00178     //NEWSKIN: majd a hozza tartozo skin-t is betolteni:
00179     //NEWSKIN: skin_LoadSkin(window_GetSkin(u->window),dsc.class_name);
00180     //NEWSKIN: az UnloadSkin-t is beepiteni majd!
00181     if(NULL==(gadget_class=(gadget_ClassData_t *)gadget_FindClassByName(TAG_GADGET_CLASS_NAME,dsc.class_name,TAG_DONE)))
00182     {
00183       gadget_LoadClass(window_GetApp(u->window),dsc.class_name,window_GetSkin(u->window));
00184     }
00185 //printf("  CLASS level=%d '%s'\n",dsc.level,name);
00186     if(NULL!=(gadget_class=(gadget_ClassData_t *)gadget_FindClassByName(TAG_GADGET_CLASS_NAME,dsc.class_name,TAG_DONE)))
00187     {
00188       bind=gadget_class->xmlbinding;
00189       dsc.gadget_id=GADGET_ILLEGAL_ID;
00190       dsc.weight=1;
00191       for(i=0;atts[i]!=NULL;i+=2);
00192       i>>=1;
00193       dsc.taglist=u->taglist;
00194       if(i>=GXML_TAGLISTSIZE) dsc.taglist=mem_malloc((i+1)*sizeof(tag));  //ITT a memoriaigeny novekedhet!
00195       if(dsc.taglist!=NULL)
00196       {
00197         for(tagindex=_w=_i=i=0;atts[i]!=NULL;i+=2)
00198         {
00199 //printf("    TAG %s=%s\n",atts[i],atts[i+1]);
00200           if(_w==0&&strcmp(atts[i],"weight")==0)
00201           {
00202             _w=1;
00203             dsc.weight=atoi(atts[i+1]);
00204 //printf("      WEIGHT=%d\n",dsc.weight);
00205           }
00206           else if(_i==0&&strcmp(atts[i],"id")==0)
00207           {
00208             _i=1;
00209             dsc.gadget_id=atoi(atts[i+1])+u->gadget_id_base;
00210 //printf("      GADGET_ID=%ld\n",dsc.gadget_id);
00211             node=list_CreateNode();
00212             if(node!=NULL&&NULL!=(ginfo=mem_malloc(sizeof(struct gxml_GadgetInfo))))
00213             {
00214               ginfo->gadget_id=dsc.gadget_id;
00215               ginfo->class_name=gadget_class->class_name;
00216               list_SetNodeData(node,ginfo);
00217               list_InsertNodeTail(u->gadget_list,node);
00218             } else u->err=ERR_OUT_OF_MEMORY;
00219           }
00220           else
00221           {
00222             tagindex+=gxml_HandleAttr(u,&dsc.taglist[tagindex],(char *)atts[i],(char *)atts[i+1],bind);
00223           }
00224         }
00225         if(dsc.level<GXML_MAXIMUM_LEVEL)
00226         {
00227           parent=NULL;
00228           if(dsc.level>0) parent=u->gadgets[dsc.level-1];
00229           //ITT megvizsgaljuk a skinclass default taglist-jet, es ahol olyat
00230           // talalunk ami meg nincs a jelenlegi taglist-ben azt hozzatesszuk
00231           dsc.taglist[tagindex].Name=TAG_DONE;
00232           dsc.taglist[tagindex].Data=0L;
00233           u->gadgets[dsc.level]=(Gadget_t *)gadget_New(TAG_GADGET_DESCRIPTOR,&dsc,TAG_GADGET_WINDOW,u->window,TAG_GADGET_PARENT,parent,TAG_DONE);
00234           if(u->gadgets[dsc.level]==NULL) u->err=ERR_CANT_CREATE_GADGET;
00235         }
00236         else u->err=ERR_TOO_DEEP_HIERARCHY;
00237         if(dsc.taglist!=u->taglist) mem_free(dsc.taglist);
00238       }
00239     } else { u->err=ERR_ILLEGAL_CLASS; debug_Error("Illegal class found!"); }
00240   }
00241 
00242   debug_End();
00243 }
00244 
00245 
00246 static void gxml_EndElement(void *userData, const char *name)
00247 {
00248   struct gxml_UserData *u=(struct gxml_UserData *)userData;
00249 
00250   debug_Begin();
00251 
00252 //printf("END< %s\n",name);
00253   u->level--;
00254   if(strcmp(name,"Layout")==0&&u->status>1&&u->level<=4) u->status=-1;
00255 
00256   debug_End();
00257 }
00258 
00259 
00260 static int gxml_CheckGui(gadget_Check_t *check, List_t *gadget_list)
00261 {
00262   int ret=0,i;
00263   Node_t *node;
00264   struct gxml_GadgetInfo *ginfo;
00265 
00266   debug_Begin();
00267 
00268   for(i=0;check[i].gadget_id!=GADGET_ILLEGAL_ID;i++)
00269   {
00270 //printf("%d: id=%ld class=%ld\n",i,check[i].gadget_id,check[i].class_id);
00271     for(ginfo=NULL,node=list_GetNodeHead(gadget_list);node!=NULL;node=list_GetNodeNext(gadget_list,node))
00272     {
00273       ginfo=(struct gxml_GadgetInfo *)list_GetNodeData(node);
00274       if(ginfo->gadget_id==check[i].gadget_id) break;
00275       ginfo=NULL;
00276     }
00277     if((check[i].flags&GADGET_REQUIRED)!=0&&ginfo==NULL) { ret=ERR_REQUIRED_MISSING; break; }
00278     if(ginfo!=NULL&&0!=strcmp(ginfo->class_name,check[i].class_name)) { ret=ERR_TYPE_MISMATCH; break; }
00279   }
00280 
00281   debug_End();
00282 
00283   return(ret);
00284 }
00285 
00286 
00296 u32 gxml_CreateGadgetTree(u32 firsttag, ...)
00297 {
00298   return(gxml_CreateGadgetTreeTL((tag *)&firsttag));
00299 }
00300 u32 gxml_CreateGadgetTreeTL(tag *taglist)
00301 {
00302   char *xml_file;
00303   Locale_t *locale;
00304   char *type;
00305   char *layoutname;
00306   char *appname;
00307   Window_t *window;
00308   gadget_Check_t *check;
00309 
00310   Gadget_t *ret=NULL;
00311   int xmlret,valid=0,err=ERR_OUT_OF_MEMORY;
00312   XML_Parser ctxt;
00313   struct gxml_UserData *userdata;
00314   Node_t *node,*nextnode;
00315   struct gxml_GadgetInfo *ginfo;
00316 
00317   debug_Begin();
00318 
00319   xml_file=(char *)tag_GetTagData(taglist,TAG_GXML_XML_FILE,0L);
00320   locale=(Locale_t *)tag_GetTagData(taglist,TAG_GXML_LOCALE,0L);
00321   type=(char *)tag_GetTagData(taglist,TAG_GXML_TYPE,0L);
00322   layoutname=(char *)tag_GetTagData(taglist,TAG_GXML_LAYOUTNAME,0L);
00323   appname=(char *)tag_GetTagData(taglist,TAG_GXML_APPNAME,0L);
00324   window=(Window_t *)tag_GetTagData(taglist,TAG_GXML_WINDOW,0L);
00325   check=(gadget_Check_t *)tag_GetTagData(taglist,TAG_GXML_CHECK,0L);
00326 
00327   if(xml_file!=NULL&&NULL!=(userdata=mem_malloc(sizeof(struct gxml_UserData))))
00328   {
00329     userdata->tree=NULL;
00330     userdata->level=0;
00331     userdata->status=0;
00332     userdata->layoutname=layoutname;
00333     userdata->window=window;
00334     userdata->gadgets[0]=NULL;
00335     userdata->check=check;
00336     userdata->err=0;
00337     userdata->commonbind=gadget_GetCommonBind();
00338     userdata->appname=appname;
00339     userdata->layouttype=type;
00340     userdata->locale=locale;
00341     userdata->gadget_id_base=0;
00342     if(NULL!=(userdata->gadget_list=list_CreateList()))
00343     {
00344       if((ctxt=XML_ParserCreate(NULL)))
00345       {
00346         XML_SetUserData(ctxt,userdata);
00347         XML_SetElementHandler(ctxt,gxml_StartElement,gxml_EndElement);
00348         xmlret=XML_Parse(ctxt,xml_file,strlen(xml_file),TRUE);
00349         if(!xmlret)
00350         {
00351           debug_Error("%s at line %d\n",XML_ErrorString(XML_GetErrorCode(ctxt)),XML_GetCurrentLineNumber(ctxt));
00352           userdata->err=ERR_XML_ERROR;
00353         }
00354         XML_ParserFree(ctxt);
00355       }
00356       if(userdata->check!=NULL) valid=gxml_CheckGui(userdata->check,userdata->gadget_list);
00357       for(node=list_GetNodeHead(userdata->gadget_list);node!=NULL;node=nextnode)
00358       {
00359         nextnode=list_GetNodeNext(userdata->gadget_list,node);
00360         list_RemoveNode(userdata->gadget_list,node);
00361         if(NULL!=(ginfo=list_GetNodeData(node)))
00362         {
00363           list_SetNodeData(node,NULL);
00364           mem_free(ginfo);
00365         }
00366         list_DeleteNode(node);
00367       }
00368       list_DeleteList(userdata->gadget_list);
00369       if(valid!=0)
00370       {
00371         userdata->err=valid;
00372         if(NULL!=userdata->gadgets[0]) gadget_DeleteSubtree(TAG_GADGET_OBJECT,userdata->gadgets[0],TAG_DONE);
00373         userdata->gadgets[0]=NULL;
00374       }
00375     }
00376     ret=userdata->gadgets[0];
00377     err=userdata->err;
00378     mem_free(userdata);
00379   }
00380   if(err!=0) debug_Error("%s\n",errstr[err]);
00381 
00382   debug_End();
00383 
00384   return((u32)ret);
00385 }
00386 
00387 int gxml_Init(void)
00388 {
00389   call_vector[GXML_CREATEGADGETTREE-GXML_FUNCBASE]=gxml_CreateGadgetTreeTL;
00390   bases_modules.gxml_Call=gxml_Call;
00391   bases_modules.gxml_CallTL=gxml_CallTL;
00392   return(0);
00393 }
00394 
00395 void gxml_CleanUp(void)
00396 {
00397   debug_Begin();
00398   debug_End();
00399 
00400     return;
00401 }
00402 
00403 
00404 u32 gxml_Call(int function, u32 firsttag, ...)
00405 {
00406   return(gxml_CallTL(function,(tag *)&firsttag));
00407 }
00408 u32 gxml_CallTL(int function, tag *taglist)
00409 {
00410   u32 ret=~0L;
00411 
00412   debug_Begin();
00413 
00414   debug_Message("function ID : %d",function-GXML_FUNCBASE);
00415 
00416   if(function>=GXML_FUNCBASE&&function<GXML_FUNC_DONE)
00417   {
00418     ret=call_vector[function-GXML_FUNCBASE](taglist);
00419   }
00420   else debug_Warning("%s(): Function code out of range! code=0x%04x",__FUNCTION__,function);
00421 
00422   debug_End();
00423 
00424   return(ret);
00425 }

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