// vim: nowrap /* *********** Check comments starting with // ### and fill appropriate code there *********** */ #pragma implementation #include #include #include #include #include #include "Xkbdconf.h" #include "../../paths.h" static HELP_FILE help_Xkbdconf ("Xkbdconf","Xkbdconf"); MODULE_DEFINE_VERSION(Xkbdconf); PUBLIC MODULE_Xkbdconf::MODULE_Xkbdconf() : LINUXCONF_MODULE("Xkbdconf") { linuxconf_loadmsg ("Xkbdconf",PACKAGE_REV); module_register_api ("Xkbdconf",1,Xkbdconf_api_get,Xkbdconf_api_release); } static const char *keymenu=NULL; PUBLIC void MODULE_Xkbdconf::setmenu ( DIALOG &dia, MENU_CONTEXT context) { if (context == MENU_HARDWARE){ keymenu = MSG_U(M_Xkbdconf,"X(graphical) keyboard configuration"); dia.new_menuitem ("Xkbdconf","",keymenu); } } PUBLIC int MODULE_Xkbdconf::domenu ( MENU_CONTEXT context, const char *key) { if (context == MENU_HARDWARE){ if (key == keymenu){ // ### Place the call to the edit function here Xkbdconf(); } } return 0; } PUBLIC int MODULE_Xkbdconf::dohtml (const char *key) { int ret = LNCF_NOT_APPLICABLE; if (strcmp(key,"Xkbdconf")==0){ // ### Insert any menu and dialog here ret = 0; } return ret; } static void usage() { xconf_error (MSG_U(T_USAGE ,"linuxconf --modulemain Xkbdconf usage\n" "\n" " Xkbdconf --option ...\n") ); } PUBLIC void MODULE_Xkbdconf::usage (SSTRINGS &tb) { tb.add (new SSTRING (MSG_R(T_USAGE))); } PUBLIC int MODULE_Xkbdconf::execmain (int argc , char *argv[], bool standalone) { int ret = LNCF_NOT_APPLICABLE; const char *pt = strrchr(argv[0],'/'); if (pt != NULL){ pt++; }else{ pt = argv[0]; } if (strcmp(pt,"Xkbdconf")==0){ ret = -1; if (argc == 1){ // ### Place call to main menu of the module Xkbdconf(); }else{ // ### Add some option parsing for the module ::usage(); } } return ret; } static MODULE_Xkbdconf Xkbdconf; PUBLIC void MODULE_Xkbdconf::Xkbdconf() { XDATALIST data; // check if the binary file XFconfig is present if (!data.isXFconfigaccessible()){ xconf_error (MSG_R(E_XDATAINACCESSIBLE)); return; } bool havedisplay = 0; if (!data.cantouchdisplay()){ if (dialog_yesno (MSG_R(N_ALERT), MSG_U(N_DISPLAYNOTFOUND, "Unable to determine the XFree86 version.\n\n" "Keep in mind that the X(graphical) keyboard configurator " "needs XFree86 v4,\notherwise the XFree86 configurations may be " "garbled\n(and this would be very bad).\n\nNote: the keyboard " "configurator can only determine\nthe XFree86 version if if can " "access the display.\n" "Are you sure do you want continue ?"), help_Xkbdconf)==MENU_NO ){ return; } } else havedisplay = 1; // check if the display is accessible if (havedisplay){ if (!data.version_compatible()) { xconf_notice (MSG_U(N_INCORRECTVERSIONM, "XFree86 must be 4.01 or higher in order\n" "to get keyboard configuration to work properly")); return; } } if (!data.init()){ // initialization xconf_error (MSG_U(E_XDATAINACCESSIBLE, "Error while accessing X data\n" "X library can't be found")); return; } DEVICELIST devlist(USR_LIB_LINUXCONF "/device_lists/keyboard.list","keyboard"); // the keyboard device list if (!data.populateKeyboardConfig(devlist)){ // populate the list of layouts and models (name/description) of X xconf_error (MSG_R(E_XDATAINACCESSIBLE)); return; } int nof = 0; bool caccess = 0; DIALOG dia; SSTRING curmodeldesc, curlayoutdesc; //will contain the current model and layout description SSTRINGS descmodels, desclayouts; //will contain the list of models and layouts //SSTRING test; KBDCONF_API *api = kbdconf_api_init("kbdconf"); // get the api and try to if (api!=NULL && api->init()) caccess = 1; // initialize it for console access descmodels.neverdelete(); //don't delete because they only point to the desclayouts.neverdelete(); //model descriptions catched by XDATALIST //get model and layout descriptions for the current name model and layout curmodeldesc.setfrom(data.getmodeldescbyname(data.nameModel.get())); curlayoutdesc.setfrom(data.getlayoutdescbyname(data.nameLayout.get())); //point descmodels to list of models and sort them data.getlistmodels (descmodels); descmodels.sort(); //point desclayout to list of layouts and sort them data.getlistlayouts (desclayouts); desclayouts.sort(); FIELD_COMBO *comboModel = dia.newf_combo(MSG_U(F_MODEL,"Model"), curmodeldesc); comboModel->addopts (descmodels); FIELD_COMBO *comboLayout = dia.newf_combo(MSG_U(F_LAYOUT,"Layout"), curlayoutdesc); comboLayout->addopts (desclayouts); /* for (int i=0; iget(); DEVICE *dev = devlist.getitem_by_name (name); if (dev) descr = dev->get_option("clayout"); comboLayout->addopt(name, descr); } */ //dia.newf_str ("test",test); dia.setbutinfo (MENU_USR1, MSG_U(B_SETTODEFAULT,"Default"), MSG_R(B_SETTODEFAULT)); int menubut = MENUBUT_CANCEL|MENUBUT_ACCEPT|MENUBUT_USR1; if (havedisplay){ dia.setbutinfo (MENU_USR2, MSG_U(B_APPLY,"Apply"), MSG_R(B_APPLY)); menubut |= MENUBUT_USR2; } while (1){ MENU_STATUS code = dia.edit( MSG_U(T_BASIC,"XKeyboard Layout configuration") ,"" ,help_Xkbdconf ,nof ,menubut); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } else if (code == MENU_ACCEPT){ const char *model, *layout; if (curmodeldesc.is_empty() || curlayoutdesc.is_empty()){ xconf_notice (MSG_U(N_MUSTSELLAYOUTANDMODEL, "You must select model and layout!")); continue; } if ( (model = data.getmodelnamebydesc(curmodeldesc.get())) && (layout = data.getlayoutnamebydesc(curlayoutdesc.get())) ){ if (data.nameModel.cmp(model)!=0 || data.nameLayout.cmp(layout)!=0){ if (data.save(model, layout)){ xconf_notice (MSG_U(N_SAVED,"Configuration saved")); if (havedisplay) data.updatekeyboard(); if (caccess) checkCcomp (api, &devlist, &data); } else xconf_error (MSG_U(E_XFILECANTBESAVED, "Can't save configuration")); } } else xconf_notice (MSG_U(E_LAYOUTCANTBESAVED,"This configuration can't be saved")); break; } else if (code == MENU_USR1){ //restore to default values if (data.restoretodefault()){ if (data.save()){ xconf_notice (MSG_R(N_SAVED)); if (havedisplay) data.updatekeyboard(); if (caccess) checkCcomp (api, &devlist, &data); curmodeldesc.setfrom(data.getmodeldescbyname(data.nameModel.get())); curlayoutdesc.setfrom(data.getlayoutdescbyname(data.nameLayout.get())); dia.reload (); } else xconf_error (MSG_R(E_XFILECANTBESAVED)); } } else if (code == MENU_USR2){ dia.save(); if (curmodeldesc.is_empty() || curlayoutdesc.is_empty()){ xconf_notice (MSG_R(N_MUSTSELLAYOUTANDMODEL)); continue; } const char *model, *layout; if ( (model = data.getmodelnamebydesc(curmodeldesc.get())) && (layout = data.getlayoutnamebydesc(curlayoutdesc.get())) ){ if (data.nameModel.cmp(model)!=0 || data.nameLayout.cmp(layout)!=0){ if (data.save(model, layout)){ xconf_notice (MSG_R(N_SAVED)); if (havedisplay) data.updatekeyboard(); if (caccess) checkCcomp (api, &devlist, &data); } else xconf_error (MSG_R(E_XFILECANTBESAVED)); } } else xconf_notice (MSG_R(E_LAYOUTCANTBESAVED)); } } kbdconf_api_end (api); } /* DESCRIPTION: Check the Console keyboard compatibility. RETURN: Nothing */ void checkCcomp (KBDCONF_API *api, DEVICELIST *devlist, XDATALIST *data){ if (data->nameModel.cmp("abnt2")==0 && data->nameLayout.cmp("br")!=0){ return; } DEVICE *dev = devlist->getitem_by_name (data->nameLayout.get()); if (dev){ const char *xlayout = dev->get_option("xlayout"); const char *clayout = dev->get_option("clayout"); if (xlayout && clayout){ if (strcmp(clayout, api->getlayout()) != 0){ if (dialog_yesno (MSG_U(N_ALERT,"Alert!"), MSG_U(N_SAMELAYOUT, "The selected layout has the same\n" "configuration for console\n" "Do you want to switch the console layout too"), help_Xkbdconf)==MENU_YES ){ if (api->save(clayout)){ api->updatekeyboard(); } else xconf_error (MSG_U(E_CCFGCANTBESAVED, "Console configuration can't be saved")); } } } } }