// vim: nowrap // TODO implementar o readerr() em elgumas funções aonde é utilizado o POPEN // retirar o filtro em pop.readout #pragma implementation #include #include #include #include #include #include #include #include #include #include #include #include "xdata.h" #include "../../paths.h" static XDATALIST *loaded_xdatalist = NULL; static int loaded_count = 0; XDATALIST *xdatalist_load() { if (loaded_xdatalist == NULL) loaded_xdatalist = new XDATALIST; loaded_count++; return loaded_xdatalist; } void xdatalist_unload() { loaded_count--; if (loaded_count==0){ delete loaded_xdatalist; loaded_xdatalist = NULL; } } PUBLIC XDATA::XDATA(SSTRING *_name, SSTRING *_desc, char _tpo) { tpo = _tpo; name = _name; desc = _desc; } PUBLIC XDATA::XDATA() { } PUBLIC XDATA::~XDATA() { delete (name); delete (desc); } /* DESCRIPTION: Constructor for XDATALIST */ PUBLIC XDATALIST::XDATALIST() { defnameModel = NULL; defnameLayout = NULL; cmd = "XFconfig"; } PUBLIC XDATALIST::~XDATALIST() { free (defnameModel); free (defnameLayout); } /* DESCRIPTION: Initialization. Get the model and layout name of the XFree keyboard configuration RETURN: 1 if success 0 if layout or model name fail */ PUBLIC int XDATALIST::init() { int ret=0; if ( getXFitem(nameModel, cmd, "--getmodel") && getXFitem(nameLayout, cmd, "--getlayout") ){ if (!nameModel.is_empty()){ defnameModel = strdup(nameModel.get()); } if (!nameLayout.is_empty()){ defnameLayout = strdup(nameLayout.get()); } ret=1; } return ret; } PUBLIC XDATA *XDATALIST::getitem(int no) { return (XDATA*)ARRAY::getitem(no); } /* DESCRIPTION: Execute the command and args and return the stdout of the command in SSTRING& s RETURN: 1 if some STDOUT 0 if nothing in STDOUT or any ERROR */ PRIVATE int XDATALIST::getXFitem(SSTRING &s, const char *command, const char *args) { int ret=0; POPEN pop (command,args); if (pop.isok()){ char buf[500]; while (pop.wait(1)>=0){ if (pop.readout (buf,sizeof(buf)-1)==0){ int d = strlen(buf); if (d>0 && buf[d-1]=='\n') buf[d-1]=0; s.setfrom(buf); ret=1; break; } } } pop.close(); return ret; } /* DESCRIPTION: Get a list of STDOUT's in SSTRINGS &st returned by the command and args RETURN: 0 in any error 1 if success */ PRIVATE int XDATALIST::execlist (SSTRINGS &st, const char *command, const char *args){ int ret=0; POPEN pop (command,args); if (pop.isok()){ ret = 1; char buf[500]; while (pop.wait(1)>=0){ if (pop.readerr (buf,sizeof(buf)-1)==0){ ret=0; break; } while (pop.readout (buf,sizeof(buf)-1)==0){ int d = strlen(buf); if (d>0 && buf[d-1]=='\n') buf[d-1]=0; st.add(new SSTRING(buf)); } } } pop.close(); return ret; } /* DESCRIPTION: Exec the XFconfig to get the layout, model names nd descriptions. RETURN: 0 if any error 1 if success */ PUBLIC int XDATALIST::populateKeyboardConfig(DEVICELIST &dev) { int ret=0; SSTRINGS modelname; SSTRINGS modeldesc; SSTRINGS layoutname; SSTRINGS layoutdesc; if ( execlist(modelname, cmd, "--listmodelnames") && execlist(modeldesc, cmd, "--listmodeldesc") && execlist(layoutname, cmd, "--listlayoutnames") && execlist(layoutdesc, cmd, "--listlayoutdesc")){ // check the integrity of data. The number of model names and model description must be the same // and the layout names and layout descriptions too. if (modelname.getnb()==modeldesc.getnb() && layoutname.getnb()==layoutdesc.getnb()){ modelname.neverdelete(); // the data class will be delete them modeldesc.neverdelete(); layoutname.neverdelete(); layoutdesc.neverdelete(); for (int i=0; iget()); if (d){ // if have a description for its layout name desc->setfrom(d->descr); // set this description } add ( new XDATA (name, desc, LAYOUT) ); // add a DATA info for layout } for (int i=0; i=0){ if (pop.readerr (buffer,sizeof(buffer)-1)==0){ ret=0; break; } } } pop.close(); return ret; } /* DESCRIPTION: Set the nameModel and nameLayout passed by model and layout and call save() RETURN: the return of the save() */ PUBLIC int XDATALIST::save(const char *model, const char *layout) { nameModel.setfrom(model); nameLayout.setfrom(layout); return save(); } /* DESCRIPTION: Point tha layout descriptions in SSTRINGS dest RETURN: Nothing */ PUBLIC void XDATALIST::getlistmodels(SSTRINGS &dest) { for (int i=0; itpo==MODEL) dest.add (d->desc); } } /* DESCRIPTION: Point the layout descriptions in SSTRINGS dest RETURN: Nothing */ PUBLIC void XDATALIST::getlistlayouts(SSTRINGS &dest) { for (int i=0; itpo==LAYOUT) dest.add (d->desc); } } /* DESCRIPTION: Search the XDATA class for models that match with the name model passed by name RETURN: A pointer to description of its name or NULL */ PUBLIC const char *XDATALIST::getmodeldescbyname(const char *name) { for (int i=0; itpo==MODEL && d->name->cmp(name)==0 ) return d->desc->get(); } return NULL; } /* DESCRIPTION: Search the XDATA class for models that match with the description passed by desc RETURN: A pointer to name of its description or NULL */ PUBLIC const char *XDATALIST::getmodelnamebydesc(const char *desc) { for (int i=0; itpo==MODEL && d->desc->cmp(desc)==0 ) return d->name->get(); } return NULL; } /* DESCRIPTION: Search the XDATA class for layouts that match with the name layout passed by name RETURN: A pointer to description of its name or NULL */ PUBLIC const char *XDATALIST::getlayoutdescbyname(const char *name) { for (int i=0; itpo==LAYOUT && d->name->cmp(name)==0 ) return d->desc->get(); } return NULL; } /* DESCRIPTION: Search the XDATA class for layouts that match with the description name passed by desc RETURN: A pointer to name of its description or NULL */ PUBLIC const char *XDATALIST::getlayoutnamebydesc(const char *desc) { for (int i=0; itpo==LAYOUT && d->desc->cmp(desc)==0 ) return d->name->get(); } return NULL; } /* DESCRIPTION: Restore the layout and model names to default value. The default value was taked from X cgf files when the init XDATALIST::init() metod was called. RETURN: Nothing */ PUBLIC int XDATALIST::restoretodefault() { int ret = 0; if (nameModel.cmp(defnameModel) != 0){ nameModel.setfrom(defnameModel); ret = 1; } if (nameLayout.cmp(defnameLayout) != 0){ nameLayout.setfrom(defnameLayout); ret = 1; } return ret; } /* DESCRIPTION: Verify if the display can be found RETURN: 1 if yes 0 if any ERROR */ PUBLIC int XDATALIST::cantouchdisplay() { int ret=0; POPEN pop (cmd,"--havedisplay"); if (pop.isok()){ while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } if (pop.readout (buf,sizeof(buf)-1)==0){ int d = strlen(buf); if (d>0 && buf[d-1]=='\n') buf[d-1]=0; if (strcmp(buf,"yes")==0) ret=1; break; } } } pop.close(); return ret; } /* DESCRIPTION: Update the keyboard buffers for X RETURN: 1 if success 0 if any ERROR */ PUBLIC int XDATALIST::updatekeyboard() { int ret=0; POPEN pop (cmd,"--updatekeyboard"); if (pop.isok()){ ret = 1; while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } } } pop.close(); return ret; } /* DESCRIPTION: Check the read and access able of XFree86 RETURN: 1 if ok 0 if any ERROR */ PUBLIC int XDATALIST::isXcfgaccessible() { int ret = 0; const char *arg = "--isaccessible"; POPEN pop (cmd,arg); if (pop.isok()){ ret = 1; while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } } } pop.close(); return ret; } /* DESCRIPTION: Set the model XFree86 configuration RETURN: 1 if can be set 0 if any error */ PUBLIC int XDATALIST::setXmodelconfig(const char *model) { int ret = 0; char arg[100]; sprintf (arg,"--setmodelconfig %s", model); POPEN pop (cmd,arg); if (pop.isok()){ ret = 1; while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } } } pop.close(); return ret; } PUBLIC int XDATALIST::setXmodelconfig() { return setXmodelconfig(nameModel.get()); } /* DESCRIPTION: Set the layout XFree86 configuration RETURN: 1 if can be set 0 if any error */ PUBLIC int XDATALIST::setXlayoutconfig(const char *layout) { int ret = 0; char arg[100]; sprintf (arg,"--setlayoutconfig %s", layout); POPEN pop (cmd,arg); if (pop.isok()){ ret = 1; while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } } } pop.close(); return ret; } /* DESCRIPTION: Chack if the XFree86 version is higher of 4.0 RETURN: 1 if yes 0 if any error */ PUBLIC int XDATALIST::version_compatible() { int ret = 0; POPEN pop (cmd, "--version"); if (pop.isok()){ while (pop.wait(1)>=0){ char buf[50]; if (pop.readerr (buf,sizeof(buf)-1)==0){ ret = 0; break; } if (pop.readout (buf,sizeof(buf)-1)==0){ int d = strlen(buf); if (d>0 && buf[d-1]=='\n') buf[d-1]=0; if (atoi(buf)>=4) ret = 1; break; } } } pop.close(); return ret; } PUBLIC int XDATALIST::setXlayoutconfig() { return setXmodelconfig(nameLayout.get()); } PUBLIC const char *XDATALIST::touch() { return "I can touch Xkbdconf. Gee"; } PUBLIC const char *XDATALIST::getlayout() { return nameLayout.get(); } /* DESCRIPTION: check if the binary file XFconfig is present RETURN: 1 if success 0 if no */ PUBLIC int XDATALIST::isXFconfigaccessible() { int ret = 0; FILE *f = fopen (USR_LIB_LINUXCONF "/lib/XFconfig", "r"); if (f!=NULL){ ret = 1; fclose (f); } return ret; } static int Xkbdconf_api_updateXkeyboard() { return loaded_xdatalist->updatekeyboard(); } static const char *Xkbdconf_api_touch() { return loaded_xdatalist->touch(); } static int Xkbdconf_api_isXcfgaccessible() { return loaded_xdatalist->isXcfgaccessible(); } static int Xkbdconf_api_init() { return loaded_xdatalist->init(); } static const char *Xkbdconf_api_getlayout() { return loaded_xdatalist->getlayout(); } static int Xkbdconf_api_setXlayoutconfig(const char *st) { if (st==NULL) return loaded_xdatalist->setXlayoutconfig(); else return loaded_xdatalist->setXlayoutconfig(st); } static int Xkbdconf_api_isXFconfigaccessible() { return loaded_xdatalist->isXFconfigaccessible(); } void *Xkbdconf_api_get() { XKBDCONF_API *api = new XKBDCONF_API; api->getlayout = Xkbdconf_api_getlayout; api->touch = Xkbdconf_api_touch; api->isXcfgaccessible = Xkbdconf_api_isXcfgaccessible; api->setXlayoutconfig = Xkbdconf_api_setXlayoutconfig; api->updateXkeyboard = Xkbdconf_api_updateXkeyboard; api->init = Xkbdconf_api_init; api->isXFconfigaccessible = Xkbdconf_api_isXFconfigaccessible; xdatalist_load(); return api; } void Xkbdconf_api_release(void *api) { delete (XKBDCONF_API*)api; xdatalist_unload(); } //* * * * ARQUIVO MORTO /* DESCRIPTION: Set the name of model by its description. Look in ARRAY for model descriptions that match with the received parameter. RETURN: Nothing PUBLIC int XDATALIST::setcurmodelbydesc(const char *s) { for (int i=0; itpo==MODEL && d->desc->cmp(s)==0){ nameModel.setfrom(*(d->name)); return 1; } } return 0; } DESCRIPTION: Set the name of layout by its description. Look in ARRAY for layout descriptions that match with the received parameter. RETURN: Nothing PUBLIC int XDATALIST::setcurlayoutbydesc(const char *s) { for (int i=0; itpo==LAYOUT && d->desc->cmp(s)==0){ nameLayout.setfrom(*(d->name)); return 1; } } return 0; } */