mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Removed obsolete code
This commit is contained in:
parent
667ce4722f
commit
0e52d2b974
@ -1,889 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Config - library for configuration management
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
/*#include "fl_internal.h"
|
||||
|
||||
#include <efltk/vsnprintf.h>
|
||||
#include <efltk/Fl_String_List.h>
|
||||
#include <efltk/Fl_Exception.h>
|
||||
#include <efltk/Fl_Config.h>
|
||||
#include <efltk/filename.h>
|
||||
#include <efltk/fl_utf8.h>*/
|
||||
|
||||
#include "Config.h"
|
||||
#include <fltk/filename.h>
|
||||
|
||||
#include "NLS.h"
|
||||
#include "../edeconf.h"
|
||||
#include "Util.h"
|
||||
|
||||
/*#include <ctype.h>
|
||||
#include <locale.h>*/
|
||||
|
||||
#include <errno.h>
|
||||
/*#include <stdlib.h>
|
||||
#include <stdio.h>*/
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*#ifdef _WIN32_WCE
|
||||
#include <stdlibx.h>
|
||||
#endif
|
||||
//#include <config.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# define access(a,b) _access(a,b)
|
||||
# define mkdir(a,b) _mkdir(a)
|
||||
# define R_OK 4
|
||||
|
||||
#else
|
||||
|
||||
# include <unistd.h>
|
||||
|
||||
#endif *//* _WIN32 */
|
||||
|
||||
|
||||
#define LOCALE_TO_C() \
|
||||
char *locale = setlocale(LC_ALL, ""); \
|
||||
char *restore_locale = locale ? strdup(locale) : strdup("C"); \
|
||||
setlocale(LC_ALL, "C")
|
||||
|
||||
#define RESTORE_LOCALE() \
|
||||
setlocale(LC_ALL, restore_locale); \
|
||||
free(restore_locale)
|
||||
|
||||
// From Enumerations.h
|
||||
#ifdef _WIN32
|
||||
# undef slash
|
||||
# define slash '\\'
|
||||
#else
|
||||
# undef slash
|
||||
# define slash '/'
|
||||
#endif
|
||||
// End Enumerations.h
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
|
||||
// GLOBAL NOTE: asprintf() is a GNU extension - if it's unsupported on some
|
||||
// platforms, use our tasprintf() instead (in Util.h)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// vec_from_string() - similar to explode() in PHP or split() in Perl
|
||||
// adapted from Fl_String_List to use vector
|
||||
std::vector<char*> vec_from_string(const char *str, const char *separator)
|
||||
{
|
||||
if(!str) return std::vector<char*> ();
|
||||
|
||||
uint separator_len = strlen(separator);
|
||||
const char *ptr = str;
|
||||
const char *s = strstr(ptr, separator);
|
||||
std::vector<char*> retval;
|
||||
if(s) {
|
||||
do {
|
||||
uint len = s - ptr;
|
||||
if (len) {
|
||||
retval.push_back(strndup(ptr,len));
|
||||
} else {
|
||||
retval.push_back(NULL);
|
||||
}
|
||||
|
||||
ptr = s + separator_len;
|
||||
s = strstr(ptr, separator);
|
||||
}
|
||||
while(s);
|
||||
|
||||
if(*ptr) {
|
||||
retval.push_back(strdup(ptr));
|
||||
}
|
||||
} else {
|
||||
retval.push_back(strdup(ptr));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Get filename with full path of config file
|
||||
// TODO: mergeing of system and user config
|
||||
char* Config::find_file(const char *filename, bool create, int mode)
|
||||
{
|
||||
static char path[PATH_MAX];
|
||||
|
||||
if(is_path_rooted(filename)) {
|
||||
strncpy(path, filename, PATH_MAX);
|
||||
return (create || !access(path, R_OK)) ? path : 0;
|
||||
}
|
||||
if(mode==USER) {
|
||||
const char *cptr = getenv("HOME");
|
||||
char *ret=0;
|
||||
if(cptr) {
|
||||
snprintf(path, PATH_MAX-1, "%s%c%s%c%s", cptr, slash, ".ede", slash, filename);
|
||||
if(create || !access(path, R_OK)) {
|
||||
ret = path;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
snprintf(path, sizeof(path)-1, "%s%c%s", get_sys_dir(), slash, filename);
|
||||
return (create || !access(path, R_OK)) ? path : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define S(item) ((Config_Section*)item)
|
||||
|
||||
Config::Config(const char *vendor, const char *application, int mode)
|
||||
: Config_Section("","",0)
|
||||
{
|
||||
m_vendor=m_app=m_filename=NULL;
|
||||
m_cur_sec = 0;
|
||||
m_changed=false;
|
||||
m_error = 0;
|
||||
|
||||
if(vendor) m_vendor = strdup(vendor);
|
||||
if(application) m_app = strdup(application);
|
||||
|
||||
if(strlen(m_app) > 0)
|
||||
{
|
||||
const char *file=0;
|
||||
char tmp[PATH_MAX];
|
||||
#ifdef _WIN32
|
||||
if(mode==SYSTEM)
|
||||
snprintf(tmp, sizeof(tmp)-1, "%s%c%s.conf", m_app, slash, m_app);
|
||||
else
|
||||
#endif
|
||||
snprintf(tmp, sizeof(tmp)-1, "apps%c%s%c%s.conf", slash, m_app, slash, m_app);
|
||||
file = find_file(tmp, true, mode);
|
||||
if(file)
|
||||
{
|
||||
bool ret = make_path_for_file(file);
|
||||
if(ret)
|
||||
{
|
||||
m_filename = strdup(file);
|
||||
read_file(true);
|
||||
} else
|
||||
m_error = CONF_ERR_FILE;
|
||||
} else
|
||||
m_error = CONF_ERR_FILE;
|
||||
} else
|
||||
m_error = CONF_ERR_FILE;
|
||||
}
|
||||
|
||||
Config::Config(const char *filename, bool read, bool create)
|
||||
: Config_Section("","",0)
|
||||
{
|
||||
m_vendor=m_app=m_filename=NULL;
|
||||
|
||||
if(filename) m_filename = strdup(filename); else m_filename = strdup("");
|
||||
// TODO: shouldn't we just return false if there's no filename??
|
||||
// use case: creating a new file (nonexistant)
|
||||
|
||||
m_error = 0;
|
||||
m_cur_sec = 0;
|
||||
m_changed=false;
|
||||
|
||||
if(create && strlen(m_filename)>0) {
|
||||
make_path_for_file(m_filename);
|
||||
}
|
||||
|
||||
if(read) read_file(create);
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
flush();
|
||||
clear();
|
||||
if(m_filename) free(m_filename);
|
||||
if(m_vendor) free(m_vendor);
|
||||
if(m_app) free(m_app);
|
||||
}
|
||||
|
||||
/* get error string associated with error number */
|
||||
const char *Config::strerror(int error)
|
||||
{
|
||||
switch(error)
|
||||
{
|
||||
case CONF_SUCCESS: return _("Successful operation");
|
||||
case CONF_ERR_FILE: return _("Could not access config file");
|
||||
case CONF_ERR_SECTION: return _("Config file section not found");
|
||||
case CONF_ERR_KEY: return _("Key not found in section");
|
||||
case CONF_ERR_MEMORY: return _("Could not allocate memory");
|
||||
case CONF_ERR_NOVALUE: return _("Invalid value associated with key");
|
||||
default: return _("Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
bool Config::read_file(bool create)
|
||||
{
|
||||
bool error = false;
|
||||
if(m_filename && strlen(m_filename)<1) {
|
||||
m_error = CONF_ERR_FILE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(create && !(access(m_filename, F_OK)==0)) {
|
||||
FILE *f = fopen(m_filename, "w+");
|
||||
if(f) {
|
||||
fputs(" ", f);
|
||||
fclose(f);
|
||||
} else error=true;
|
||||
}
|
||||
|
||||
if(error) {
|
||||
m_error = CONF_ERR_FILE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If somebody calls this function two times, we
|
||||
// need to clean earlier section list...
|
||||
clear();
|
||||
|
||||
/////
|
||||
struct stat fileStat;
|
||||
stat(m_filename, &fileStat);
|
||||
uint size = fileStat.st_size;
|
||||
if(size == 0) {
|
||||
m_error = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(m_filename, "r");
|
||||
if(!fp) {
|
||||
//fprintf(stderr, "fp == 0: %s\n", m_filename);
|
||||
m_error = CONF_ERR_FILE;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint bsize = size*sizeof(char);
|
||||
char *buffer = (char*)malloc(bsize+1);
|
||||
buffer[bsize] = 0;
|
||||
if(!buffer) {
|
||||
m_error = CONF_ERR_MEMORY;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint readed = fread(buffer, 1, size, fp);
|
||||
if(readed <= 0) {
|
||||
free((char*)buffer);
|
||||
fclose(fp);
|
||||
m_error = CONF_ERR_FILE;
|
||||
return false;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* old parser
|
||||
String_List strings(buffer, "\n");
|
||||
|
||||
free((char*)buffer);
|
||||
|
||||
Config_Section *section = this;
|
||||
for(uint n=0; n<strings.size(); n++)
|
||||
{
|
||||
String line;
|
||||
int comment_pos = strings[n].rpos('#');
|
||||
if(comment_pos>=0) {
|
||||
line = strings[n].sub_str(comment_pos, strings[n].length()-comment_pos).trim();
|
||||
} else {
|
||||
line = strings[n].trim();
|
||||
}
|
||||
|
||||
if(line[0] == '[')
|
||||
{
|
||||
int pos = line.pos(']');
|
||||
if(pos>=0)
|
||||
{
|
||||
String sec(line.sub_str(1, pos-1));
|
||||
section = create_section(sec);
|
||||
}
|
||||
}
|
||||
else if(line[0] != '#')
|
||||
{
|
||||
int pos = line.pos('=');
|
||||
if(pos==-1) pos = line.pos(':');
|
||||
if(pos>=0) {
|
||||
String key(line.sub_str(0, pos));
|
||||
pos++;
|
||||
String value(line.sub_str(pos, line.length()-pos));
|
||||
section->add_entry(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// new parser by Vedran
|
||||
// I like writing parsers
|
||||
// too bad others don't like me writing parsers...
|
||||
// TODO: i did some stupid things here for debugging, need to check
|
||||
|
||||
int pos=0;
|
||||
bool comment, iskey, issection;
|
||||
const uint maxlen=4096;
|
||||
char key[maxlen], value[maxlen], sectionname[maxlen];
|
||||
key[0]='\0'; value[0]='\0'; sectionname[0]='\0';
|
||||
Config_Section *section = this;
|
||||
|
||||
do {
|
||||
int c=buffer[pos];
|
||||
if ((c == '\n') || (c == '\0')) {
|
||||
comment=false; iskey=true; issection=false;
|
||||
wstrim(sectionname);
|
||||
wstrim(key);
|
||||
wstrim(value);
|
||||
if (strlen(sectionname) > 0)
|
||||
section = create_section(sectionname);
|
||||
if (strlen(key) > 0)
|
||||
section->add_entry(key,value);
|
||||
key[0]='\0'; value[0]='\0'; sectionname[0]='\0';
|
||||
}
|
||||
else if (c == '#')
|
||||
comment = true;
|
||||
else if (comment == false) {
|
||||
if (c == '[')
|
||||
issection = true;
|
||||
else if (c == ']')
|
||||
issection = false;
|
||||
else if ((c == '=') || (c == ':'))
|
||||
iskey = false;
|
||||
else {
|
||||
if (issection) {
|
||||
if (maxlen>strlen(sectionname)+1)
|
||||
strcat(sectionname, (const char*) &c);
|
||||
} else if (iskey) {
|
||||
if (maxlen>strlen(key)+1)
|
||||
strcat(key, (const char*) &c);
|
||||
} else
|
||||
if (maxlen>strlen(value)+1)
|
||||
strcat(value, (const char*) &c);
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
} while (buffer[pos] != '\0');
|
||||
|
||||
m_error = 0;
|
||||
m_changed=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Config::flush()
|
||||
{
|
||||
if(!m_changed) return true;
|
||||
if(strlen(m_filename) < 1) return false;
|
||||
|
||||
FILE *file = fopen(m_filename, "w+");
|
||||
// if(!file)
|
||||
// fl_throw(::strerror(errno));
|
||||
|
||||
LOCALE_TO_C();
|
||||
|
||||
fprintf(file, "# EDE INI Version %s\n", PACKAGE_VERSION);
|
||||
if(m_vendor && strlen(m_vendor)>0) fprintf(file, "# Vendor: %s\n", m_vendor);
|
||||
if(m_app && strlen(m_app)>0) fprintf(file, "# Application: %s\n", m_app);
|
||||
|
||||
// Flush sections
|
||||
write_section(0, file);
|
||||
|
||||
RESTORE_LOCALE();
|
||||
|
||||
fclose(file);
|
||||
|
||||
m_error = 0;
|
||||
m_changed=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Config_Section *Config::create_section(const char* name)
|
||||
{
|
||||
if(strlen(name)<1) return 0;
|
||||
|
||||
Config_Section *section = find_section(name, true);
|
||||
if(section) return section;
|
||||
|
||||
char *lastptr = strrchr(name,'/'); // int pos = name.rpos('/')+1;
|
||||
int pos;
|
||||
if(lastptr) {
|
||||
pos = lastptr-name + 1;
|
||||
} else {
|
||||
section = new Config_Section(name, "", 0);
|
||||
sections().push_back(section);
|
||||
return section;
|
||||
}
|
||||
|
||||
//char* sec_name(name.sub_str(pos, name.length()-pos));
|
||||
char *sec_name = strndup(name+pos, strlen(name)-pos);
|
||||
//char* sec_path(name.sub_str(0, pos));
|
||||
char *sec_path = strndup(name, pos);
|
||||
|
||||
Config_Section *parent = find_section(sec_path, false);
|
||||
Config_Sections *list = §ions();
|
||||
|
||||
if(!parent) {
|
||||
// Fl_String_List sections;
|
||||
std::vector<char*> sections = vec_from_string(sec_path, "/");
|
||||
|
||||
char path[PATH_MAX];
|
||||
path[0]='\0';
|
||||
for(uint n=0; n<sections.size(); n++) {
|
||||
if(parent) list = &parent->sections();
|
||||
|
||||
parent = new Config_Section(sections.at(n), path, parent);
|
||||
list->push_back(parent);
|
||||
|
||||
if (PATH_MAX>strlen(path)+strlen(sections.at(n))+1) {
|
||||
strcat(path, sections.at(n));
|
||||
strcat(path, "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(parent) list = &parent->sections();
|
||||
|
||||
section = new Config_Section(sec_name, sec_path, parent);
|
||||
list->push_back(section);
|
||||
|
||||
free(sec_name); free(sec_path);
|
||||
m_error = 0;
|
||||
return section;
|
||||
}
|
||||
|
||||
Config_Section *Config::find_section(const char *path, bool perfect_match) const
|
||||
{
|
||||
if(!path || !*path) return 0;
|
||||
|
||||
std::vector<char*> sections = vec_from_string(path, "/");
|
||||
|
||||
if(sections.size()==0)
|
||||
return find(path, false);
|
||||
|
||||
Config_Section *section = (Config_Section *)this;
|
||||
for(uint n=0; n<sections.size(); n++) {
|
||||
Config_Section *tmp = section->find(sections.at(n), false);
|
||||
if(!tmp) {
|
||||
if(perfect_match)
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
section = tmp;
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
void Config::remove_key(const char *section, const char *key)
|
||||
{
|
||||
if(key) {
|
||||
Config_Section *sect = find_section(section, true);
|
||||
if(sect->remove_entry(key)) {
|
||||
m_error = 0;
|
||||
m_changed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_error = CONF_ERR_KEY;
|
||||
}
|
||||
|
||||
// finding and removing stuff from deque
|
||||
void sectremove(Config_Sections sects, Config_Section *sect)
|
||||
{
|
||||
for (uint n=0; n<sects.size(); n++) {
|
||||
Config_Section *current = (Config_Section *)sects.at(n);
|
||||
if (current == sect)
|
||||
sects.erase(sects.begin()+n);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Config::remove_sec(const char *section)
|
||||
{
|
||||
if(!section) return;
|
||||
|
||||
Config_Section *sect;
|
||||
if((sect = find_section(section, true)) != 0) {
|
||||
if(sect->parent()) {
|
||||
sectremove(sect->parent()->sections(),sect);
|
||||
} else {
|
||||
sectremove(sections(),sect);
|
||||
}
|
||||
delete sect;
|
||||
m_error = 0;
|
||||
m_changed = true;
|
||||
return;
|
||||
}
|
||||
m_error = CONF_ERR_SECTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read functions
|
||||
*/
|
||||
|
||||
int Config::_read_string(Config_Section *s, const char *key, char *ret, const char *def_value, int size)
|
||||
{
|
||||
if(!key || !s) {
|
||||
if(def_value) strncpy(ret, def_value, size);
|
||||
else ret[0] = '\0';
|
||||
m_error = (!key ? CONF_ERR_KEY : CONF_ERR_SECTION);
|
||||
return m_error;
|
||||
}
|
||||
|
||||
char *val = s->find_entry(key);
|
||||
if(val) {
|
||||
int len = strlen(val); // convert from unsigned... and now:
|
||||
len = (len<size) ? len+1 : size;
|
||||
memcpy(ret, val, len);
|
||||
return (m_error = CONF_SUCCESS);
|
||||
}
|
||||
free(val);
|
||||
|
||||
if(def_value) strncpy(ret, def_value, size);
|
||||
else ret[0] = '\0';
|
||||
|
||||
m_error = CONF_ERR_KEY;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_string(Config_Section *s, const char *key, char *&ret, const char *def_value)
|
||||
{
|
||||
if(!key || !s) {
|
||||
if (def_value) ret=strdup(def_value); else ret=0;
|
||||
if (!key) m_error = CONF_ERR_KEY; else m_error = CONF_ERR_SECTION;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
char *val = s->find_entry(key);
|
||||
if(val && strlen(val)>0)
|
||||
{
|
||||
ret = strdup(val);
|
||||
return (m_error = CONF_SUCCESS);
|
||||
}
|
||||
free(val);
|
||||
|
||||
if (def_value) ret = strdup(def_value); else ret=0;
|
||||
m_error = CONF_ERR_KEY;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
/*int Config::_read_string(Config_Section *s, const char *key, Fl_String &ret, const char *def_value)
|
||||
{
|
||||
if(!key || !s) {
|
||||
ret = def_value;
|
||||
m_error = !key ? CONF_ERR_KEY : CONF_ERR_SECTION;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
Fl_String *val = s->find_entry(key);
|
||||
if(val) {
|
||||
ret = (*val);
|
||||
return (m_error = CONF_SUCCESS);
|
||||
}
|
||||
|
||||
ret = def_value;
|
||||
return (m_error = CONF_ERR_KEY);
|
||||
}*/
|
||||
|
||||
int Config::_read_long(Config_Section *s, const char *key, long &ret, long def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(!_read_string(s, key, tmp, 0))
|
||||
if (tmp[0]) ret=strtol(tmp, NULL, 10); else ret=def_value;
|
||||
else
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_int(Config_Section *s, const char *key, int &ret, int def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(!_read_string(s, key, tmp, 0)) {
|
||||
ret = atoi(tmp);
|
||||
if ((errno == ERANGE) || (ret == 0 && strcmp(tmp,"0") != 0)) ret = def_value;
|
||||
} else
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_float (Config_Section *s, const char *key, float &ret, float def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(!_read_string(s, key, tmp, 0)) {
|
||||
LOCALE_TO_C();
|
||||
ret = (float)strtod(tmp, 0);
|
||||
RESTORE_LOCALE();
|
||||
} else
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_double(Config_Section *s, const char *key, double &ret, double def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(!_read_string(s, key, tmp, 0)) {
|
||||
LOCALE_TO_C();
|
||||
ret = strtod(tmp, 0);
|
||||
RESTORE_LOCALE();
|
||||
} else
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_bool(Config_Section *s, const char *key, bool &ret, bool def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(_read_string(s, key, tmp, 0)) {
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
if ((strncasecmp(tmp,"true",4)==0)
|
||||
|| (strncasecmp(tmp,"yes",3)==0)
|
||||
|| (strncasecmp(tmp,"on",2)==0)
|
||||
|| (strcasecmp(tmp,"1")==0)) {
|
||||
ret = true;
|
||||
} else if((strncasecmp(tmp,"false",5)==0)
|
||||
|| (strncasecmp(tmp,"no",2)==0)
|
||||
|| (strncasecmp(tmp,"off",3)==0)
|
||||
|| (strcasecmp(tmp,"0")==0)) {
|
||||
ret = false;
|
||||
} else {
|
||||
m_error = CONF_ERR_NOVALUE;
|
||||
ret = def_value;
|
||||
}
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int Config::_read_color(Config_Section *s, const char *key, Color &ret, Color def_value)
|
||||
{
|
||||
char* tmp;
|
||||
if(_read_string(s, key, tmp, 0)) {
|
||||
ret = def_value;
|
||||
return m_error;
|
||||
}
|
||||
|
||||
int r=0,g=0,b=0;
|
||||
if(sscanf(tmp, "RGB(%d,%d,%d)", &r, &g, &b)!=3) {
|
||||
ret = def_value;
|
||||
return (m_error = CONF_ERR_NOVALUE);
|
||||
}
|
||||
ret = color(r,g,b);
|
||||
return m_error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write functions
|
||||
*/
|
||||
|
||||
/*int Config::_write_string(Config_Section *s, const char *key, const char *value)
|
||||
{
|
||||
char* val(value);
|
||||
return _write_string(s, key, val);
|
||||
}*/
|
||||
|
||||
int Config::_write_string(Config_Section *s, const char *key, const char* value)
|
||||
{
|
||||
if(!s) return (m_error = CONF_ERR_SECTION);
|
||||
if(!key) return (m_error = CONF_ERR_KEY);
|
||||
|
||||
/* This logic is now in add_entry, cause we can't pass around pointers into structure
|
||||
|
||||
char *val = s->find_entry(key);
|
||||
if(val) {
|
||||
strncpy(val, value, strlen(value));
|
||||
} else */
|
||||
if (value) s->add_entry(key, value); else s->add_entry(key, "");
|
||||
|
||||
m_changed=true;
|
||||
return (m_error=CONF_SUCCESS);
|
||||
}
|
||||
|
||||
int Config::_write_long(Config_Section *s, const char *key, const long value)
|
||||
{
|
||||
return _write_string(s, key, tsprintf("%ld", value));
|
||||
}
|
||||
|
||||
int Config::_write_int(Config_Section *s, const char *key, const int value)
|
||||
{
|
||||
return _write_string(s, key, tsprintf("%d", value));
|
||||
}
|
||||
|
||||
int Config::_write_float(Config_Section *s, const char *key, const float value)
|
||||
{
|
||||
LOCALE_TO_C();
|
||||
char tmp[32]; snprintf(tmp, sizeof(tmp)-1, "%g", value);
|
||||
RESTORE_LOCALE();
|
||||
return _write_string(s, key, tmp);
|
||||
}
|
||||
|
||||
int Config::_write_double(Config_Section *s, const char *key, const double value)
|
||||
{
|
||||
LOCALE_TO_C();
|
||||
char tmp[32]; snprintf(tmp, sizeof(tmp)-1, "%g", value);
|
||||
RESTORE_LOCALE();
|
||||
return _write_string(s, key, tmp);
|
||||
}
|
||||
|
||||
int Config::_write_bool(Config_Section *s, const char *key, const bool value)
|
||||
{
|
||||
if(value) return _write_string(s, key, "1");
|
||||
return _write_string(s, key, "0");
|
||||
}
|
||||
|
||||
int Config::_write_color(Config_Section *s, const char *key, const Color value)
|
||||
{
|
||||
unsigned char r,g,b;
|
||||
split_color(value, r,g,b);
|
||||
return _write_string(s, key, tsprintf("RGB(%d,%d,%d)", r,g,b));
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
//////////////////////////////////////
|
||||
//////////////////////////////////////
|
||||
|
||||
Config_Section::Config_Section(const char* name, const char* path, Config_Section *par)
|
||||
: m_parent(par)
|
||||
{
|
||||
m_name=strdup(name);
|
||||
m_path=strdup(path);
|
||||
}
|
||||
|
||||
Config_Section::~Config_Section()
|
||||
{
|
||||
free(m_name);
|
||||
free(m_path);
|
||||
clear();
|
||||
}
|
||||
|
||||
void Config_Section::clear()
|
||||
{
|
||||
for(uint n=0; n<sections().size(); n++) {
|
||||
Config_Section *s = (Config_Section *)sections()[n];
|
||||
delete s;
|
||||
}
|
||||
m_lines.clear();
|
||||
m_sections.clear();
|
||||
}
|
||||
|
||||
void Config_Section::write_section(int indent, FILE *fp) const
|
||||
{
|
||||
for(int a=0; a<indent; a++) fprintf(fp, " ");
|
||||
|
||||
if(strlen(name())>0)
|
||||
fprintf(fp, "[%s%s]\n", path(), name());
|
||||
|
||||
for(uint n=0; n<m_lines.size(); n++) {
|
||||
if(strlen(m_lines.at(n)) > 0) {
|
||||
for(int a=0; a<indent; a++) fprintf(fp, " ");
|
||||
// fprintf(fp, " %s=%s\n", it.id().c_str(), it.value().c_str());
|
||||
fprintf(fp, " %s\n", m_lines.at(n));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
for(uint n=0; n<sections().size(); n++) {
|
||||
Config_Section *child = S(sections()[n]);
|
||||
child->write_section(indent+2, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Config_Section::add_entry(const char* key, const char* value)
|
||||
{
|
||||
if(!key || strlen(key)<1) return;
|
||||
if(!value) return;
|
||||
|
||||
char *kvpair;
|
||||
char *m_key = wstrim(strdup(key));
|
||||
char *m_value = wstrim(strdup(value));
|
||||
asprintf(&kvpair,"%s=%s",m_key,m_value);
|
||||
free (m_key); free (m_value);
|
||||
|
||||
// if key already exists, delete
|
||||
bool found = false;
|
||||
for (uint i=0; i<lines().size(); i++) {
|
||||
if (!found && strncmp(lines().at(i), kvpair, strlen(kvpair)) == 0) {
|
||||
lines().erase(lines().begin()+i);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
lines().push_back(kvpair);
|
||||
}
|
||||
|
||||
bool Config_Section::remove_entry(const char* key)
|
||||
{
|
||||
if (!key || strlen(key)<1) return false;
|
||||
bool found=false;
|
||||
|
||||
char *search;
|
||||
asprintf(&search,"%s=",twstrim(key));
|
||||
|
||||
for (uint i=0; i<lines().size(); i++) {
|
||||
if (strncmp(lines().at(i), search, strlen(search)) == 0) {
|
||||
lines().erase(lines().begin()+i);
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
free(search);
|
||||
return found;
|
||||
}
|
||||
|
||||
char* Config_Section::find_entry(const char *key) const
|
||||
{
|
||||
if (!key || strlen(key)<1) return 0;
|
||||
bool found=false;
|
||||
char *ret;
|
||||
|
||||
char *search;
|
||||
// asprintf(&search,"%s=",twstrim(key));
|
||||
char *m_key = wstrim(strdup(key));
|
||||
asprintf(&search,"%s=",m_key);
|
||||
free(m_key);
|
||||
|
||||
for (uint i=0; i<lines().size(); i++) {
|
||||
if (!found && strncmp(lines().at(i), search, strlen(search)) == 0) {
|
||||
ret = strdup(lines().at(i)+strlen(search));
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
free(search); // this sometimes fails, dunno why....
|
||||
if (found) { return ret; } else { return 0; }
|
||||
}
|
||||
|
||||
Config_Section *Config_Section::find(const char *name, bool recursive) const
|
||||
{
|
||||
const Config_Sections *list = §ions();
|
||||
if (!name) return 0;
|
||||
|
||||
for(uint n=0; n<list->size(); n++) {
|
||||
Config_Section *s = (Config_Section*) list->at(n);
|
||||
if(strncmp(s->name(), name, strlen(name)) == 0)
|
||||
return s;
|
||||
if(recursive) {
|
||||
s = s->find(name, recursive);
|
||||
if(s) return s;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
755
edelib2/Config.h
755
edelib2/Config.h
@ -1,755 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Config - library for configuration management
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _edelib_Config_h_
|
||||
#define _edelib_Config_h_
|
||||
|
||||
/*#include "Enumerations.h"
|
||||
#include "Fl_Util.h"
|
||||
#include "Fl_String.h"
|
||||
#include "Fl_Color.h"
|
||||
#include "Fl_Ptr_List.h"
|
||||
#include "Fl_Map.h"*/
|
||||
|
||||
#include <fltk/Color.h>
|
||||
#include <deque> // TODO: port everything to char**
|
||||
#include <vector> // TODO: port everything to char**
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#include <fltk/x.h>
|
||||
#endif
|
||||
|
||||
using namespace fltk;
|
||||
|
||||
|
||||
namespace edelib {
|
||||
|
||||
|
||||
/**
|
||||
* \defgroup edelib::Config edelib::Config globals
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* Error codes for edelib::Config
|
||||
*/
|
||||
enum ConfErrors {
|
||||
CONF_SUCCESS = 0, ///< successful operation
|
||||
CONF_ERR_FILE, ///< trouble accessing config file or directory
|
||||
CONF_ERR_SECTION, ///< requested section was not found
|
||||
CONF_ERR_KEY, ///< requested key was not found
|
||||
CONF_ERR_MEMORY, ///< memory allocation error
|
||||
CONF_ERR_NOVALUE, ///< key found, but invalid value associated with it
|
||||
};
|
||||
|
||||
/** List used for sections in Fl_Config_Section */
|
||||
//FIXME
|
||||
//typedef Fl_Ptr_List Fl_Config_Sections;
|
||||
typedef std::deque<void*> Config_Sections;
|
||||
|
||||
/** Map used for entries in Fl_Config_Section */
|
||||
//FIXME
|
||||
//typedef Fl_String_String_Map Fl_Config_Lines;
|
||||
//this is not exactly compatible, but that's the best we can do...
|
||||
typedef std::vector<char*> Config_Lines;
|
||||
|
||||
/*@}*/
|
||||
|
||||
class Config;
|
||||
|
||||
/**
|
||||
* The configuration section.
|
||||
* Represents one section in config (ini) file.
|
||||
* @see edelib::Config
|
||||
*/
|
||||
class Config_Section
|
||||
{
|
||||
friend class Config;
|
||||
public:
|
||||
Config_Section(const char* name, const char* path, Config_Section *par);
|
||||
virtual ~Config_Section();
|
||||
|
||||
/**
|
||||
* Destroys all sections and entries.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
/**
|
||||
* Returns pointer to parent section, NULL for Fl_Config (root)
|
||||
*/
|
||||
Config_Section *parent() const { return m_parent; }
|
||||
|
||||
/**
|
||||
* Returns name of section, without path.
|
||||
* @see path()
|
||||
*/
|
||||
const char* name() const { return m_name; }
|
||||
|
||||
/**
|
||||
* Returns path to section, without name.
|
||||
* @see name()
|
||||
*/
|
||||
const char* path() const { return m_path; }
|
||||
|
||||
/**
|
||||
* Returns const reference to entry map.
|
||||
*/
|
||||
const Config_Lines &lines() const { return m_lines; }
|
||||
|
||||
/**
|
||||
* Returns reference to entry map.
|
||||
*/
|
||||
Config_Lines &lines() { return m_lines; }
|
||||
|
||||
/**
|
||||
* Returns const reference to section list.
|
||||
*/
|
||||
const Config_Sections §ions() const { return m_sections; }
|
||||
|
||||
/**
|
||||
* Returns reference to section list.
|
||||
*/
|
||||
Config_Sections §ions() { return m_sections; }
|
||||
|
||||
/**
|
||||
* Find section named 'name'.
|
||||
* @param section_name name of section to find
|
||||
* @param recursive set true to perform recursive search.
|
||||
*/
|
||||
Config_Section *find(const char *section_name, bool recursive=false) const;
|
||||
|
||||
protected:
|
||||
Config_Section *m_parent;
|
||||
char *m_name, *m_path;
|
||||
|
||||
Config_Lines m_lines; //Line map
|
||||
Config_Sections m_sections; //Section list
|
||||
|
||||
void write_section(int indent, FILE *fp) const;
|
||||
|
||||
void add_entry(const char* key, const char* value);
|
||||
bool remove_entry(const char* key);
|
||||
char* find_entry(const char *key) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* The configuration holder. This class maybe used very easily to
|
||||
* store application settings to file. Either system wide or user specific,
|
||||
* depending on config type. edelib::Config is derived edelib::Config_Section, please
|
||||
* take look a look at functions it provides also.
|
||||
* @see edelib::Config_Section
|
||||
*/
|
||||
class Config : public Config_Section {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Config file modes
|
||||
*/
|
||||
enum ConfigType {
|
||||
USER=1, ///< User specific config file
|
||||
SYSTEM ///< System wide config file
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates/reads/writes app specific config file.
|
||||
*
|
||||
* LINUX:<br>
|
||||
* File is created in ($home)/.ede/apps/($application)/($application).conf
|
||||
* Or ($prefix)/share/ede/apps/($application)/($application).conf
|
||||
*
|
||||
* <br>WIN32:<br>
|
||||
* ($home)\Local Settings\.ede\apps\($application)/($application).conf
|
||||
* Or ($common files)\($application)\($application).conf
|
||||
*
|
||||
* Location depends on ConfigType 'mode', USER or SYSTEM
|
||||
*
|
||||
* @param vendor aplication vendor, written down to file
|
||||
* @param application name, written down to file
|
||||
* @param mode which mode to use
|
||||
*/
|
||||
Config(const char *vendor, const char *application, int mode=USER);
|
||||
|
||||
/**
|
||||
* Access custom file in filesystem.
|
||||
*
|
||||
* @param filename path to config (ini) file.
|
||||
* @param readfile if true, file is readed on constructor. I.e no need for read_file()
|
||||
* @param createfile if true, file is created if it doesn't exists.
|
||||
*/
|
||||
Config(const char *filename, bool readfile=true, bool createfile=true);
|
||||
|
||||
/**
|
||||
* Destroys config
|
||||
*/
|
||||
virtual ~Config();
|
||||
|
||||
/**
|
||||
* Finds config file, depending on mode.
|
||||
* NOTE: User MUST NOT free returned pointer!
|
||||
*
|
||||
* LINUX:<br>
|
||||
* File is created in ($home)/.ede/apps/($application)/($application).conf
|
||||
* Or ($prefix)/share/ede/apps/($application)/($application).conf
|
||||
*
|
||||
* <br>WIN32:<br>
|
||||
* ($home)\Local Settings\.ede\apps\($application)/($application).conf
|
||||
* Or ($common files)\($application)\($application).conf
|
||||
*
|
||||
* @param filename Relative filename, e.g. "myapp_config.ini"
|
||||
* @param create if true, path is returned even if file is not found. Otherwise NULL if path not found.
|
||||
* @param mode which mode to use
|
||||
*/
|
||||
static char *find_file(const char *filename, bool create=true, int mode=USER);
|
||||
|
||||
|
||||
/**
|
||||
* (re)read file. NOTE: Deletes current entries from this Fl_Config object.
|
||||
* @param create if true, file is created if it doesn't exists.
|
||||
* @see filename()
|
||||
*/
|
||||
bool read_file(bool create = true);
|
||||
|
||||
/**
|
||||
* Flush entries to file.
|
||||
* Returns true on success.
|
||||
* @see filename()
|
||||
*/
|
||||
bool flush();
|
||||
|
||||
/** Returns current filename. */
|
||||
const char* filename() const { return m_filename; }
|
||||
/** Set new filename. You need to call read_file() to get new entries. */
|
||||
void filename(const char *filename) { strncpy(m_filename, filename, strlen(filename)); }
|
||||
/** Set new filename. You need to call read_file() to get new entries. */
|
||||
// void filename(const Fl_String &filename) { m_filename = filename; }
|
||||
|
||||
/** Returns current vendor name. */
|
||||
const char* vendor() const { return m_vendor; }
|
||||
/** Set new vendor name. */
|
||||
void vendor(const char *vendor) { strncpy(m_vendor, vendor, strlen(vendor)); }
|
||||
/** Set new vendor name. */
|
||||
// void vendor(const Fl_String &vendor) { m_vendor = vendor; }
|
||||
|
||||
/** Returns current application name. */
|
||||
const char* application() const { return m_app; }
|
||||
/** Set new application name. */
|
||||
void application(const char *app) { strncpy(m_app, app, strlen(app)); }
|
||||
/** Set new application name. */
|
||||
// void application(const Fl_String &app) { m_app = app; }
|
||||
|
||||
/**
|
||||
* Returns true, if data changed.
|
||||
* call flush() to sync changes to file
|
||||
* @see flush()
|
||||
*/
|
||||
bool is_changed() const { return m_changed; }
|
||||
|
||||
/**
|
||||
* Set changed, forces flush() to write file.
|
||||
* Even if it is not changed.
|
||||
*/
|
||||
void set_changed() { m_changed = true; }
|
||||
|
||||
/**
|
||||
* Returns last error happened.
|
||||
*/
|
||||
int error() const { return m_error; }
|
||||
|
||||
/**
|
||||
* Reset error, normally you don't need to call this.
|
||||
*/
|
||||
void reset_error() { m_error = 0; }
|
||||
|
||||
/**
|
||||
* Return string presentation for last happened error.
|
||||
*/
|
||||
const char *strerror() const { return Config::strerror(m_error); }
|
||||
|
||||
/**
|
||||
* Return error string, associated with 'errnum'
|
||||
*/
|
||||
static const char *strerror(int errnum);
|
||||
|
||||
/**
|
||||
* Create new section. You can pass full path as section name.
|
||||
* For example: create_section("/path/to/my/section");
|
||||
* All nested sections are created automatically.
|
||||
*
|
||||
* Returns pointer to created section, NULL if failed.
|
||||
*/
|
||||
// Config_Section *create_section(const char *path) { char* tmp(path); return create_section(tmp); }
|
||||
|
||||
/**
|
||||
* Create new section. You can pass full path as section name.
|
||||
* For example: create_section("/path/to/my/section");
|
||||
* All nested sections are created automatically.
|
||||
*
|
||||
* Returns pointer to created section, NULL if failed.
|
||||
*/
|
||||
Config_Section *create_section(const char* path);
|
||||
|
||||
/**
|
||||
* Find section. You can pass full path as section name.
|
||||
* For example: find_section("/path/to/my/section");
|
||||
*
|
||||
* Returns pointer to found section, NULL if not found.
|
||||
*
|
||||
* @param perfect_match is true, it returns NULL if no exact section found. Otherwise it returns last found section in path.
|
||||
*/
|
||||
Config_Section *find_section(const char *path, bool perfect_match=true) const;
|
||||
|
||||
/**
|
||||
* Return child sections of section specified 'secpath'
|
||||
*/
|
||||
Config_Sections *section_list(const char *secpath) const { Config_Section *s=find_section(secpath); return s ? (&s->sections()) : 0; }
|
||||
|
||||
/**
|
||||
* Return entries of section specified 'secpath'
|
||||
*/
|
||||
Config_Lines *line_list(const char *secpath) const { Config_Section *s=find_section(secpath); return s ? (&s->lines()) : 0; }
|
||||
|
||||
/**
|
||||
* Set default section for read/write operations.
|
||||
* NOTE: section is created, if it's not found.<BR>
|
||||
* NOTE: You can pass path to section e.g "/path/to/my/section"
|
||||
*/
|
||||
void set_section(const char *secpath) { set_section(create_section(secpath)); }
|
||||
|
||||
/**
|
||||
* Set default section for read/write operations.
|
||||
*/
|
||||
void set_section(Config_Section *sec) { m_cur_sec = sec; }
|
||||
|
||||
/**
|
||||
* Remove entry associated with 'key' from section.
|
||||
* NOTE: You can pass path to section e.g "/path/to/my/section"
|
||||
*/
|
||||
void remove_key(const char *section, const char *key);
|
||||
|
||||
/**
|
||||
* Remove section specified by 'section'.
|
||||
* NOTE: You can pass path to section e.g "/path/to/my/section"
|
||||
*/
|
||||
void remove_sec(const char *section);
|
||||
|
||||
|
||||
/**
|
||||
* Read Fl_String entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
// int read(const char *key, char* ret, const char *def_value) { return _read_string(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read char* entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
* @param size of 'ret' char* array.
|
||||
*/
|
||||
int read(const char *key, char *ret, const char *def_value, int size) { return _read_string(m_cur_sec, key, ret, def_value, size); }
|
||||
|
||||
/**
|
||||
* Read char* entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: 'ret' is allocated by Fl_Confing, user MUST free 'ret' by calling free() function.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, char *&ret, const char *def_value=0) { return _read_string(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read long entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, long &ret, long def_value=0) { return _read_long(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read int entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, int &ret, int def_value=0) { return _read_int(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read float entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, float &ret, float def_value=0) { return _read_float(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read double entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, double &ret, double def_value=0) { return _read_double(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read bool entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, bool &ret, bool def_value=0) { return _read_bool(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read Fl_Color entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int read(const char *key, Color &ret, Color def_value=0) { return _read_color(m_cur_sec, key, ret, def_value); }
|
||||
|
||||
|
||||
/**
|
||||
* Write Fl_String entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
// int write(const char *key, const Fl_String &value) { return _write_string(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write const char* entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const char *value) { return _write_string(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write long entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const long value) { return _write_long(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write int entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const int value) { return _write_int(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write float entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const float value) { return _write_float(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write double entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const double value) { return _write_double(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write bool entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const bool value) { return _write_bool(m_cur_sec, key, value); }
|
||||
|
||||
/**
|
||||
* Write Fl_Color entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: This function assumes that current section is set with set_section().
|
||||
*
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int write(const char *key, const Color value) { return _write_color(m_cur_sec, key, value); }
|
||||
|
||||
|
||||
/**
|
||||
* Read Fl_String entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
// int get(const char *section, const char *key, Fl_String &ret, const char *def_value) { return _read_string(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read char* entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, char *ret, const char *def_value, int size) { return _read_string(find_section(section), key, ret, def_value, size); }
|
||||
|
||||
/**
|
||||
* Read char* entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: 'ret' is allocated by Fl_Confing, user MUST free 'ret' by calling free() function.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, char *&ret, const char *def_value=0) { return _read_string(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read long entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, long &ret, long def_value=0) { return _read_long(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read int entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, int &ret, int def_value=0) { return _read_int(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read float entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, float &ret, float def_value=0) { return _read_float(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read double entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, double &ret, double def_value=0) { return _read_double(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read bool entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, bool &ret, bool def_value=0) { return _read_bool(find_section(section), key, ret, def_value); }
|
||||
|
||||
/**
|
||||
* Read Fl_Color entry from config.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param ret Result is stored to this.
|
||||
* @param def_value Default value for ret, if not found.
|
||||
*/
|
||||
int get(const char *section, const char *key, Color &ret, Color def_value=0) { return _read_color(find_section(section), key, ret, def_value); }
|
||||
|
||||
|
||||
/**
|
||||
* Write Fl_String entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
// int set(const char *section, const char *key, const Fl_String &value) { return _write_string(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write const char *entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const char *value) { return _write_string(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write long entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const long value) { return _write_long(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write int entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const int value) { return _write_int(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write float entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const float value) { return _write_float(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write bool entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const bool value) { return _write_double(create_section(section), key, value); }
|
||||
|
||||
/**
|
||||
* Write Fl_Color entry to config. You must call flush() to sunc changes to file.
|
||||
* Returns CONF_SUCCESS on success, otherwise errorcode.
|
||||
* NOTE: section must be set as first parameter!
|
||||
*
|
||||
* @param section Section for entry
|
||||
* @param key Key to entry.
|
||||
* @param value value to set. if entry with 'key' exists, value is replaced.
|
||||
*/
|
||||
int set(const char *section, const char *key, const Color value) { return _write_color(create_section(section), key, value); }
|
||||
|
||||
private:
|
||||
int m_error;
|
||||
char* m_filename;
|
||||
char *m_vendor, *m_app;
|
||||
|
||||
Config_Section *m_cur_sec;
|
||||
bool m_changed;
|
||||
|
||||
//int _read_string(Fl_Config_Section *s, const char *key, Fl_String &ret, const char *def_value);
|
||||
int _read_string(Config_Section *s, const char *key, char *ret, const char *def_value, int size);
|
||||
int _read_string(Config_Section *s, const char *key, char *&ret, const char *def_value);
|
||||
int _read_long (Config_Section *s, const char *key, long &ret, long def_value);
|
||||
int _read_int (Config_Section *s, const char *key, int &ret, int def_value);
|
||||
int _read_float (Config_Section *s, const char *key, float &ret, float def_value);
|
||||
int _read_double(Config_Section *s, const char *key, double &ret, double def_value);
|
||||
int _read_bool (Config_Section *s, const char *key, bool &ret, bool def_value);
|
||||
int _read_color (Config_Section *s, const char *key, Color &ret, Color def_value);
|
||||
|
||||
//int _write_string(Fl_Config_Section *s, const char *key, const Fl_String &value);
|
||||
int _write_string(Config_Section *s, const char *key, const char *value);
|
||||
int _write_long (Config_Section *s, const char *key, const long value);
|
||||
int _write_int (Config_Section *s, const char *key, const int value);
|
||||
int _write_float (Config_Section *s, const char *key, const float value);
|
||||
int _write_double(Config_Section *s, const char *key, const double value);
|
||||
int _write_bool (Config_Section *s, const char *key, const bool value);
|
||||
int _write_color (Config_Section *s, const char *key, const Color value);
|
||||
};
|
||||
|
||||
// Backward compatibility...
|
||||
static inline const char* find_config_file(const char *filename, bool create=true) {
|
||||
return Config::find_file(filename, create, Config::USER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
141
edelib2/Icon.cpp
141
edelib2/Icon.cpp
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Icon - General icon library with support for Icon themes
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fltk/Group.h>
|
||||
#include <fltk/filename.h>
|
||||
|
||||
#include "Icon.h"
|
||||
#include "Config.h"
|
||||
#include "../edeconf.h"
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
// FIXME: use an EDE internal default theme
|
||||
const char* Icon::iconspath = PREFIX"/share/icons";
|
||||
const char* Icon::defaulttheme = "crystalsvg";
|
||||
char* Icon::theme = 0;
|
||||
|
||||
|
||||
|
||||
// Read configuration to detect currently active theme
|
||||
void Icon::read_theme_config()
|
||||
{
|
||||
char temp_value[PATH_MAX];
|
||||
if (theme) free(theme);
|
||||
|
||||
Config cfg(find_config_file("ede.conf", 0));
|
||||
cfg.set_section("Icons");
|
||||
if (!cfg.read("IconTheme", temp_value, 0, sizeof(temp_value)))
|
||||
theme = strdup(temp_value);
|
||||
|
||||
if (!theme || strlen(theme)<2)
|
||||
theme = strdup(defaulttheme);
|
||||
}
|
||||
|
||||
|
||||
// Change theme in configuration
|
||||
void Icon::set_theme(const char *t)
|
||||
{
|
||||
if (theme) free(theme);
|
||||
theme = strdup(t);
|
||||
|
||||
Config cfg(find_config_file("ede.conf", true));
|
||||
cfg.set_section("Icons");
|
||||
cfg.write("IconTheme", theme);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Search theme directory for icon file of given name
|
||||
|
||||
// Icon names are unique, regardless of subdirectories. The
|
||||
// "actions", "apps", "devices" etc. are just an idea that
|
||||
// never lived. So we simply flatten the KDE directory
|
||||
// structure.
|
||||
|
||||
// Alternatively, if there are different icons in subdirs with
|
||||
// same name, you can provide e.g. subdir/filename and it will
|
||||
// work.
|
||||
|
||||
const char *find_icon(const char *name, const char *directory)
|
||||
{
|
||||
dirent **files;
|
||||
static char filename[PATH_MAX];
|
||||
|
||||
snprintf (filename, PATH_MAX, "%s/%s", directory, name);
|
||||
if (filename_exist(filename)) return filename;
|
||||
snprintf (filename, PATH_MAX, "%s/%s.png", directory, name);
|
||||
if (filename_exist(filename)) return filename;
|
||||
snprintf (filename, PATH_MAX, "%s/%s.xpm", directory, name);
|
||||
if (filename_exist(filename)) return filename;
|
||||
|
||||
// Look in subdirectories
|
||||
const int num_files = filename_list(directory, &files);
|
||||
char dirname[PATH_MAX];
|
||||
for (int i=0; i<num_files; i++) {
|
||||
if ((strcmp(files[i]->d_name,"./") == 0) || strcmp(files[i]->d_name,"../") == 0) continue;
|
||||
snprintf (dirname, PATH_MAX, "%s/%s", directory, files[i]->d_name);
|
||||
if (filename_isdir(dirname)) {
|
||||
// Cut last slash
|
||||
if (dirname[strlen(dirname)-1] == '/')
|
||||
dirname[strlen(dirname)-1] = '\0';
|
||||
const char *tmp = find_icon(name, dirname);
|
||||
if (tmp) return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create icon with given "standard" name
|
||||
Icon* Icon::get(const char *name, int size)
|
||||
{
|
||||
char directory[PATH_MAX];
|
||||
|
||||
// FIXME: rescale icon from other sizes
|
||||
if (size!=TINY && size!=SMALL && size!=MEDIUM && size!=LARGE && size!=HUGE)
|
||||
{
|
||||
fprintf (stderr, "Edelib: ERROR: We don't support icon size %d... using %dx%d\n", size, MEDIUM, MEDIUM);
|
||||
size=MEDIUM;
|
||||
}
|
||||
|
||||
snprintf (directory, PATH_MAX, "%s/%s/%dx%d", iconspath, get_theme(), size, size);
|
||||
|
||||
const char *icon = find_icon(name, directory);
|
||||
|
||||
if (!icon) // Fallback to icon from default theme, if not found
|
||||
{
|
||||
snprintf (directory, sizeof(directory), "%s/%s/%dx%d", iconspath, defaulttheme, size, size);
|
||||
icon = find_icon(name, directory);
|
||||
}
|
||||
if (!icon && size!=TINY) // No default icon in this size
|
||||
{
|
||||
snprintf (directory, sizeof(directory), "%s/%s/%dx%d", iconspath, defaulttheme, TINY, TINY);
|
||||
icon = find_icon(name, directory);
|
||||
// TODO: scale icon from tiny to requested size
|
||||
}
|
||||
if (!icon)
|
||||
return 0; // sorry
|
||||
else
|
||||
{
|
||||
//fprintf(stderr,"Ikona: %s\n",icon);
|
||||
Icon* i = (Icon*)pngImage::get(icon);
|
||||
// free(icon); // no need to free icon
|
||||
//i->transp_index(255);
|
||||
//fprintf (stderr, "Name: %s Transp_index: %d Pixel type: %d\n", name, i->transp_index(), i->pixel_type());
|
||||
return i;
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Icon - General icon library with support for Icon themes
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/*! \class edelib::Icon
|
||||
|
||||
This class gives support for KDE-compatible icon themes.
|
||||
Icons are identified with their standard names, and the class
|
||||
will fetch corresponding image from its standard location.
|
||||
User can easily change all icons at once by setting the icon
|
||||
theme.
|
||||
|
||||
There should be a freedesktop.org standard for icon names,
|
||||
but I'm not aware of one so we will implement a sort of KDE
|
||||
compatibility. Please refer to Icon theme documentation for
|
||||
details.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _edelib_Icon_h_
|
||||
#define _edelib_Icon_h_
|
||||
|
||||
#include <fltk/SharedImage.h>
|
||||
|
||||
using namespace fltk;
|
||||
|
||||
namespace edelib {
|
||||
|
||||
// This class builds on pngImage, which is a subclass of SharedImage.
|
||||
// SharedImage.h code suggests that this will be dropped in favor of
|
||||
// Image class.
|
||||
|
||||
class Icon : public pngImage
|
||||
{
|
||||
public:
|
||||
/*! Icon sizes:
|
||||
TINY - 16x16
|
||||
SMALL - 32x32
|
||||
MEDIUM - 48x48
|
||||
LARGE - 64x64
|
||||
HUGE - 128x128
|
||||
At the moment we only support and use TINY and MEDIUM sizes.*/
|
||||
enum IconSize {
|
||||
TINY = 16,
|
||||
SMALL = 32,
|
||||
MEDIUM = 48,
|
||||
LARGE = 64,
|
||||
HUGE = 128,
|
||||
};
|
||||
|
||||
// Silence compiler warning
|
||||
virtual ~Icon();
|
||||
|
||||
/*! Return edelib::Icon with given standard name and size. Adding
|
||||
path or .png extension is not necessary - just name is fine.
|
||||
Example:
|
||||
o->image(edelib::Icon::get("fileopen", edelib::Icon::TINY)); */
|
||||
static Icon* get(const char *name, int size = MEDIUM);
|
||||
|
||||
/*! Give currently active theme and its directory. */
|
||||
static const char* get_theme() { if (!theme) read_theme_config(); return theme; }
|
||||
|
||||
/*! Set theme as currently active. */
|
||||
static void set_theme(const char *t);
|
||||
|
||||
int get_size() { return my_size; }
|
||||
|
||||
// In future, we might add methods for retrieving theme metadata
|
||||
// (name, author, URL, copyright and such)
|
||||
|
||||
private:
|
||||
static void read_theme_config();
|
||||
static const char* iconspath;
|
||||
static const char* defaulttheme;
|
||||
static char* theme;
|
||||
int my_size;
|
||||
char *my_theme;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
SubDir TOP edelib2 ;
|
||||
|
||||
MakeLibrary libedelib : about_dialog.cpp
|
||||
Config.cpp
|
||||
Icon.cpp
|
||||
MimeType.cpp
|
||||
process.cpp
|
||||
pty.cpp
|
||||
Run.cpp
|
||||
Util.cpp ;
|
@ -1,377 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::MimeType - Detection of file types and handling
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "MimeType.h"
|
||||
|
||||
#include <fltk/filename.h>
|
||||
|
||||
#include "Run.h"
|
||||
#include "Config.h"
|
||||
#include "Util.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <magic.h>
|
||||
|
||||
// I made this icon because on KDE there are stupidly two icons with same name
|
||||
#define DEFAULT_ICON "mimetypes/misc"
|
||||
#define FOLDER_ICON "folder"
|
||||
#define RECYCLED_ICON "recycled"
|
||||
#define LOCKED_ICON "lockoverlay"
|
||||
#define FOLDERLOCKED_ICON "folder_locked"
|
||||
// to be defined in separate file:
|
||||
#define FILE_MANAGER "efiler"
|
||||
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
// GLOBAL NOTE: asprintf() is a GNU extension - if it's unsupported on some
|
||||
// platforms, use our tasprintf() instead (in Util.h)
|
||||
|
||||
|
||||
|
||||
// File format:
|
||||
// id|description|handler program|icon|wildcard for filename (extension)|wildcard for file command output|classic mime type
|
||||
//
|
||||
// - id - short string; to setup subtypes, just use slash (/) as separator in ID
|
||||
// - description - what is shown in gui
|
||||
// - handler program - filename will be appended, specify any needed parameters for opening - THIS WILL BE MOVED INTO SEPARATE FILE (for handling multiple programs etc.)
|
||||
// - icon - just name, don't give extension or path
|
||||
// - extension - will be used only if multiple types have same file command match. You don't need to give asterisk (*) i.e. .png. If there are multiple extensions, separate them with slash (/). Actually, "extension" can be any part of filename, but I can't think of use for this
|
||||
// - file output - relevant part of output from `file -bLnNp $filename`
|
||||
// - classic mime type - what is used for interchange i.e. text/plain - may be used for matching if other methods fail
|
||||
//
|
||||
// This is how mimetype resolving is supposed to work: if there is exactly one match for `file`
|
||||
// output, this is what we use. If there are multiple, the largest match is used. If there are
|
||||
// no results or several results with same size we look at extension, then at classic mime type
|
||||
// (using -i parameter to `file`).
|
||||
// NOTE: not sure about this last thing, since -i parameter appears to just be alias
|
||||
|
||||
|
||||
|
||||
// queue/tree of mimetype data
|
||||
static struct MimeData {
|
||||
char *id, *typestr, *program, *iconname, *extension, *file_output, *classic_mime;
|
||||
MimeData *next;
|
||||
} *mime_first=0;
|
||||
|
||||
|
||||
// This is used instead of strstrmulti to check if filename ends with any of extensions
|
||||
char *test_extension(const char *file, const char *ext) {
|
||||
if (!file || !ext || (strlen(file)==0) || (strlen(ext)==0))
|
||||
return (char*)file; // this means that empty search returns true
|
||||
char *copy = strdup(ext);
|
||||
char *token = strtok(copy, "/");
|
||||
char *result = 0;
|
||||
do {
|
||||
int k = strlen(file)-strlen(token);
|
||||
if (strcmp(file+k,token) == 0) { return strdup(file+k); break; }
|
||||
} while ((token = strtok(NULL, "/"))); // double braces to silence compiler warnings :(
|
||||
free (copy);
|
||||
if (!result && (ext[strlen(ext)-1] == '/'))
|
||||
return (char*)file; // again
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Read mime data from file
|
||||
|
||||
void get_mimedata() {
|
||||
// TODO: currently all mimes are on the same level...
|
||||
mime_first = (MimeData*) malloc(sizeof(MimeData)+1);
|
||||
MimeData *m = mime_first;
|
||||
|
||||
char line[256];
|
||||
char* mime_filename = Config::find_file("mimetypes.conf");
|
||||
FILE *f = fopen(mime_filename,"r");
|
||||
bool first=true;
|
||||
while (!feof(f) && (fgets(line,255,f))) {
|
||||
if (feof(f)) break;
|
||||
|
||||
// delete comments
|
||||
if (char* p=strchr(line,'#')) { *p = '\0'; }
|
||||
// delete spaces
|
||||
wstrim(line);
|
||||
// if there's nothing left, skip
|
||||
if (strlen(line)<1) continue;
|
||||
char *p1,*p2;
|
||||
if (!(p1 = strchr(line,'|'))) continue; // likewise
|
||||
|
||||
// Allocate next element if this is not first pass
|
||||
if (!first) {
|
||||
m->next = (MimeData*) malloc(sizeof(MimeData)+1);
|
||||
m = m->next;
|
||||
}
|
||||
first=false;
|
||||
|
||||
// parse line
|
||||
m->id = wstrim(strndup(line,p1-line));
|
||||
if (p1 && (p2 = strchr(++p1,'|'))) m->typestr = wstrim(strndup(p1,p2-p1)); else m->typestr=0;
|
||||
if (p2 && (p1 = strchr(++p2,'|'))) m->program = wstrim(strndup(p2,p1-p2)); else m->program=0;
|
||||
if (p1 && (p2 = strchr(++p1,'|'))) m->iconname = wstrim(strndup(p1,p2-p1)); else m->iconname=0;
|
||||
if (p2 && (p1 = strchr(++p2,'|'))) m->extension = wstrim(strndup(p2,p1-p2)); else m->extension=0;
|
||||
if (p1 && (p2 = strchr(++p1,'|'))) m->file_output = wstrim(strndup(p1,p2-p1)); else m->file_output=0;
|
||||
if (p2 && (p1 = strchr(++p2,'|'))) m->classic_mime = wstrim(strndup(p2,p1-p2)); else m->classic_mime=0;
|
||||
}
|
||||
m->next = 0;
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
void free_mimedata() {
|
||||
MimeData *m, *n;
|
||||
m = mime_first;
|
||||
while ((n = m->next)) { free(m); m=n; }
|
||||
mime_first=0;
|
||||
}
|
||||
|
||||
|
||||
void print_mimedata() { // for debugging
|
||||
MimeData *m = mime_first;
|
||||
while (m != 0) {
|
||||
fprintf(stderr, "ID: '%s' Name: '%s' Prog: '%s' Icon: '%s' Ext: '%s' File: '%s' MIME: '%s'\n", m->id, m->typestr, m->program, m->iconname, m->extension, m->file_output, m->classic_mime);
|
||||
m = m->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// declare given MimeData as current
|
||||
void MimeType::set_found(char *id) {
|
||||
if (!id) return;
|
||||
|
||||
// find id
|
||||
MimeData *m = mime_first;
|
||||
while (m && strcmp(m->id,id)!=0) m = m->next;
|
||||
|
||||
// copy data to cur_*
|
||||
cur_id = strdup(id);
|
||||
if (m->typestr) cur_typestr = strdup(m->typestr);
|
||||
if (m->program && (strlen(twstrim(m->program))>0)) {
|
||||
asprintf (&cur_command, "%s \"%s\"", m->program, cur_filename);
|
||||
}
|
||||
if (m->iconname) cur_iconname = strdup(m->iconname);
|
||||
else cur_iconname = strdup(DEFAULT_ICON);
|
||||
}
|
||||
|
||||
|
||||
void MimeType::set(const char* filename, bool usefind) {
|
||||
// Drop any previous data from memory
|
||||
if (cur_id) free(cur_id);
|
||||
if (cur_typestr) free(cur_typestr);
|
||||
if (cur_command) free(cur_command);
|
||||
if (cur_iconname) free(cur_iconname);
|
||||
if (cur_filename) free(cur_filename);
|
||||
cur_id=cur_typestr=cur_command=cur_iconname=cur_filename=0;
|
||||
|
||||
if (filename && filename_exist(filename)) {
|
||||
cur_filename=strdup(filename);
|
||||
|
||||
// Directory
|
||||
if (filename_isdir(filename)) {
|
||||
if (access(filename, R_OK || X_OK)) {
|
||||
// Not readable
|
||||
cur_id = strdup("directory/locked");
|
||||
cur_typestr = strdup("Directory (not accessible)");
|
||||
cur_iconname = strdup(FOLDERLOCKED_ICON);
|
||||
} else {
|
||||
cur_id = strdup("directory");
|
||||
cur_typestr = strdup("Directory");
|
||||
asprintf(&cur_command, "%s \"%s\"", FILE_MANAGER, filename);
|
||||
cur_iconname = strdup(FOLDER_ICON);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// File not readable
|
||||
if (access(filename, R_OK)) {
|
||||
if (errno == EACCES) {
|
||||
cur_id = strdup("locked");
|
||||
cur_typestr = strdup("Can't read file");
|
||||
cur_iconname = strdup(LOCKED_ICON);
|
||||
}
|
||||
// we don't handle other errors specially
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup file
|
||||
if (filename[strlen(filename)-1] == '~') {
|
||||
cur_id = strdup("backup");
|
||||
cur_typestr = strdup("Backup file");
|
||||
cur_iconname = strdup(RECYCLED_ICON);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mime_first) get_mimedata();
|
||||
|
||||
// Stuff we need to declare before goto for visibility reasons
|
||||
MimeData *m = mime_first;
|
||||
//char buffer[256];
|
||||
char* buffer;
|
||||
int found=0, foundext = 0;
|
||||
MimeData *file_matches[50], *ext_matches[50] = {0}; // this is for if(!ext_matches[0])
|
||||
|
||||
if (!usefind) goto nofind; // using goto here makes less indentation ;)
|
||||
|
||||
// execute file command through libmagic
|
||||
buffer = strdup(magic_file(magic_cookie, filename));
|
||||
|
||||
fprintf (stderr,"(%s) File said: %s (Error: %s)\n",filename,buffer,magic_error(magic_cookie));
|
||||
|
||||
// find matches for 'file' command output
|
||||
// TODO: add wildcard matching
|
||||
while (m != 0) {
|
||||
if (m->file_output && (strstr(buffer,m->file_output)))
|
||||
file_matches[found++]=m;
|
||||
m=m->next;
|
||||
}
|
||||
|
||||
if (found == 1) { // one result found
|
||||
this->set_found(file_matches[0]->id);
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (found > 1) { // multiple results - find best match
|
||||
// We look for longest file match
|
||||
uint max=0;
|
||||
for (int i=0; i<found; i++)
|
||||
if (strlen(file_matches[i]->file_output)>max)
|
||||
max = strlen(file_matches[i]->file_output);
|
||||
fprintf(stderr, "Max: %d\n",max);
|
||||
// If all matches are empty, this is probably bogus
|
||||
if (max == 0) goto nofind;
|
||||
|
||||
// Test to see if there are multiple best choices
|
||||
int j=0;
|
||||
for (int i=0; i<found; i++)
|
||||
if (strlen(file_matches[i]->file_output) == max) {
|
||||
fprintf (stderr, "Lokalni maximum '%s'\n", file_matches[i]->id);
|
||||
file_matches[j++] = file_matches[i];
|
||||
}
|
||||
// Now **file_matches should contain only maximums
|
||||
if (j==1) {
|
||||
this->set_found(file_matches[0]->id);
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compare maximums on extension
|
||||
for (int i=0; i<j; i++)
|
||||
if (test_extension(filename,file_matches[i]->extension))
|
||||
ext_matches[foundext++] = file_matches[i];
|
||||
|
||||
// No extension matches - accept first result (FIXME)
|
||||
if (foundext == 0) {
|
||||
this->set_found(file_matches[0]->id);
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
// From here we jump to comment " // continue extension matching"
|
||||
}
|
||||
|
||||
nofind:
|
||||
free(buffer);
|
||||
if (!ext_matches[0]) {
|
||||
// Try extension matching on all mimetypes
|
||||
// This code will be executed if:
|
||||
// a) find command is disabled
|
||||
// b) find command returned zero matches (not likely,
|
||||
// because some mimetypes have empty 'find' field)
|
||||
// c) all of find results have equal length and no extensions
|
||||
// match (this is probably a misconfiguration, but its possible)
|
||||
m = mime_first;
|
||||
do {
|
||||
// take care not to match empty extension
|
||||
if (m->extension
|
||||
&& (strlen(m->extension)>0)
|
||||
&&
|
||||
(m->extension[strlen(m->extension)-1] != '/')
|
||||
&& (test_extension(filename,m->extension))) {
|
||||
fprintf (stderr, "Extenzija '%s'\n", m->id);
|
||||
ext_matches[foundext++]=m;
|
||||
}
|
||||
} while ((m=m->next));
|
||||
}
|
||||
|
||||
fprintf(stderr, "Foundext: %d\n", foundext);
|
||||
// continue extension matching
|
||||
if (foundext == 1) { // one result found
|
||||
this->set_found(ext_matches[0]->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (foundext > 1) { // multiple results - find best match
|
||||
// Code is almost the same as above
|
||||
// We look for longest extension match
|
||||
uint max=0;
|
||||
for (int i=0; i<foundext; i++)
|
||||
if (strlen(ext_matches[i]->extension)>max &&
|
||||
(ext_matches[i]->extension[strlen(ext_matches[i]->extension)-1] != '/'))
|
||||
max = strlen(ext_matches[i]->extension);
|
||||
|
||||
// Test to see if there are multiple best choices
|
||||
int j=0;
|
||||
for (int i=0; i<foundext; i++)
|
||||
if (strlen(ext_matches[i]->extension) == max)
|
||||
ext_matches[j++] = ext_matches[i];
|
||||
// Now **ext_matches should contain only maximums
|
||||
if (j==1) { this->set_found(ext_matches[0]->id); return; }
|
||||
|
||||
// Now what??? we return first one whether it be the only or not!
|
||||
// FIXME
|
||||
this->set_found(file_matches[0]->id);
|
||||
return;
|
||||
}
|
||||
|
||||
// No extension results found - this is unknown file type
|
||||
cur_id = strdup("unknown");
|
||||
cur_typestr = strdup("Unknown");
|
||||
cur_iconname = strdup(DEFAULT_ICON);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
MimeType::MimeType(const char* filename, bool usefind) {
|
||||
cur_id=cur_typestr=cur_command=cur_iconname=cur_filename=0;
|
||||
|
||||
// Load mime settings file
|
||||
if (!mime_first) get_mimedata();
|
||||
|
||||
// Have libmagic read its configuration data
|
||||
magic_cookie = magic_open(MAGIC_NONE);
|
||||
magic_load(magic_cookie, NULL);
|
||||
|
||||
if (filename) set(filename,usefind);
|
||||
}
|
||||
|
||||
|
||||
MimeType::~MimeType() {
|
||||
if (cur_id) free(cur_id);
|
||||
if (cur_typestr) free(cur_typestr);
|
||||
if (cur_command) free(cur_command);
|
||||
if (cur_iconname) free(cur_iconname);
|
||||
if (cur_filename) free(cur_filename);
|
||||
|
||||
// Free memory used by mimetype configuration
|
||||
free_mimedata(); //- should we? mimedata is static for a reason...
|
||||
|
||||
// Free memory used by libmagic
|
||||
magic_close(magic_cookie);
|
||||
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::MimeType - Detection of file types and handling
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/*! \class edelib::MimeType
|
||||
|
||||
This detects the type of file using "magic" (fingerprint
|
||||
usualy found in the first several bytes) and, if that fails,
|
||||
"extension" (part of filename after last dot). To avoid code
|
||||
duplication, GNU file is used.
|
||||
|
||||
Also this class suggests the command to be used for opening.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _edelib_MimeType_h_
|
||||
#define _edelib_MimeType_h_
|
||||
|
||||
// TODO: have configure script detect libmagic and don't use
|
||||
// it if its not present
|
||||
#include <magic.h>
|
||||
|
||||
#include "Icon.h"
|
||||
|
||||
namespace edelib {
|
||||
|
||||
class MimeType
|
||||
{
|
||||
public:
|
||||
|
||||
/*! Constructor takes filename and all interesting data is
|
||||
returned with methods listed below. filename must contain
|
||||
full path. Set usefind to false to avoid using GNU/find
|
||||
command.
|
||||
|
||||
Note: We advise using empty constructor and set method in loops.*/
|
||||
|
||||
MimeType(const char* filename=0, bool usefind=true);
|
||||
|
||||
// Silence compiler warning
|
||||
virtual ~MimeType();
|
||||
|
||||
/*! Scan file with given full path and store the results until
|
||||
next call of set() */
|
||||
void set(const char* filename, bool usefind=true);
|
||||
|
||||
/*! Returns a string describing file type i.e. "PNG Image" */
|
||||
const char* type_string() { if (cur_typestr) return cur_typestr; else return 0;}
|
||||
|
||||
/*! String that can be executed to open the given file
|
||||
or perform some default action (e.g. for .desktop files,
|
||||
the program that will be launched) */
|
||||
const char* command() { if (cur_command) return cur_command; else return 0; }
|
||||
|
||||
/*! Returns edelib::Icon for files of this type. Parameter is
|
||||
edelib::Icon::IconSize */
|
||||
Icon* icon(int size) { if(cur_iconname) return Icon::get(cur_iconname,size); else return 0; }
|
||||
|
||||
const char* id() { if(cur_id) return cur_id; else return 0; }
|
||||
|
||||
private:
|
||||
char *cur_id, *cur_typestr, *cur_command, *cur_iconname, *cur_filename;
|
||||
void set_found(char *id);
|
||||
magic_t magic_cookie; //handle for libmagic
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::NLS - Native language support
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
// Native language support - under construction
|
||||
// Based on code from efltk (Fl_Locale)
|
||||
|
||||
#ifndef _NLS_H_
|
||||
#define _NLS_H_
|
||||
|
||||
#define _(s) s
|
||||
|
||||
#endif
|
236
edelib2/Run.cpp
236
edelib2/Run.cpp
@ -1,236 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Run - Library for executing external programs
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
#define PREFIX "/usr"
|
||||
|
||||
#include "Run.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include <fltk/ask.h>
|
||||
#include "NLS.h"
|
||||
#include "process.h"
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
// GLOBAL NOTE: asprintf() is a GNU extension which is also available under *BSD
|
||||
// If this is considered a problem, use our tasprintf() instead (in Util.h)
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
// Start a process using exec(3)
|
||||
// This means that there is no handling or control over process,
|
||||
// it's just forked into background. If you need to chat with
|
||||
// program or use its output, see edelib::PtyProcess
|
||||
// --------------------------------------------
|
||||
|
||||
int run_fork(const char *cmd, bool wait)
|
||||
{
|
||||
int pid, status;
|
||||
int nulldev;
|
||||
extern char **environ;
|
||||
|
||||
status=0;
|
||||
if (cmd == NULL)
|
||||
return (EDERUN_EMPTY);
|
||||
|
||||
pid = fork ();
|
||||
if (pid == -1)
|
||||
return (EDERUN_FORK_FAILED);
|
||||
if (pid == 0)
|
||||
{
|
||||
char *argv[4];
|
||||
// child
|
||||
argv[0] = "sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = (char*)cmd;
|
||||
argv[3] = NULL;
|
||||
|
||||
// The following is to avoid X locking when executing
|
||||
// terminal based application that requires user input
|
||||
if ((nulldev = open ("/dev/null", O_RDWR)))
|
||||
{
|
||||
close (0); dup (nulldev);
|
||||
close (1); dup (nulldev);
|
||||
close (2); dup (nulldev);
|
||||
}
|
||||
|
||||
if (execve ("/bin/sh", argv, environ) == -1)
|
||||
perror ("/bin/sh");
|
||||
_exit (EDERUN_EXECVE_FAILED);
|
||||
}
|
||||
do
|
||||
{
|
||||
if ((wait) && (waitpid (pid, &status, 0) == -1))
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return (EDERUN_WAITPID_FAILED);
|
||||
}
|
||||
else {
|
||||
if (status==127) status=EDERUN_NOT_FOUND;
|
||||
if (status==126) status=EDERUN_NOT_EXEC;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
// Start a process as root user
|
||||
// We use edelib::PtyProcess to chat with su/sudo. Afterwards
|
||||
// the program continues undisturbed
|
||||
// --------------------------------------------
|
||||
|
||||
// this is our internal message:
|
||||
#define CONTMSG "elauncher_ok_to_continue"
|
||||
// these are part of sudo/su chat:
|
||||
#define PWDQ "Password:"
|
||||
#define BADPWD "/bin/su: incorrect password"
|
||||
#define SUDOBADPWD "Sorry, try again."
|
||||
|
||||
int run_as_root(const char *cmd, bool wait)
|
||||
{
|
||||
// -- we could check for availibility of sudo, but there's no point
|
||||
bool use_sudo = false;
|
||||
Config pGlobalConfig(find_config_file("ede.conf", 0));
|
||||
pGlobalConfig.set_section("System");
|
||||
pGlobalConfig.read("UseSudo", use_sudo, false);
|
||||
|
||||
// Prepare array as needed by exec()
|
||||
char *parts[4];
|
||||
if (use_sudo) {
|
||||
parts[0] = "/bin/sudo";
|
||||
parts[1] = "";
|
||||
// This "continue message" prevents accidentally exposing password
|
||||
asprintf(&parts[2], "echo %s; %s", CONTMSG, cmd);
|
||||
parts[3] = NULL;
|
||||
} else {
|
||||
parts[0] = "/bin/su";
|
||||
parts[1] = "-c";
|
||||
// This "continue message" prevents accidentally exposing password
|
||||
asprintf(&parts[2], "echo %s; %s", CONTMSG, cmd);
|
||||
parts[3] = NULL;
|
||||
}
|
||||
// the actual command is this:
|
||||
// cmd_ = strtok(cmd," ");
|
||||
|
||||
tryagain:
|
||||
PtyProcess *child = new PtyProcess();
|
||||
child->setEnvironment((const char**)environ);
|
||||
if (child->exec(parts[0], (const char**)parts) < 0) {
|
||||
return EDERUN_PTY_FAILED;
|
||||
}
|
||||
|
||||
// Wait for process to actually start. Shouldn't last long
|
||||
while (1) {
|
||||
int p = child->pid();
|
||||
if (p != 0 && child->checkPid(p))
|
||||
break;
|
||||
int exit = child->checkPidExited(p);
|
||||
if (exit != -2) {
|
||||
// Process is DOA
|
||||
fprintf (stderr, "Edelib: Process has died unexpectedly! Exit status: %d\n",exit);
|
||||
delete child;
|
||||
goto tryagain;
|
||||
}
|
||||
fprintf (stderr, "Edelib: Process not started yet...\n");
|
||||
}
|
||||
|
||||
// Run program as root using su or sudo
|
||||
char *line;
|
||||
|
||||
const char *pwd = password(_("This program requires administrator privileges.\nPlease enter your password below:"));
|
||||
if (pwd == 0) return EDERUN_USER_CANCELED;
|
||||
|
||||
// Chat routine
|
||||
while (1) {
|
||||
line = child->readLine();
|
||||
|
||||
// This covers other cases of failed process startup
|
||||
// Our su command should at least produce CONTMSG
|
||||
if (line == 0 && child->checkPidExited(child->pid()) != PtyProcess::NotExited) {
|
||||
// TODO: capture stdout? as in sudo error?
|
||||
fprintf (stderr, "Edelib: su process has died unexpectedly in chat stage!\n");
|
||||
delete child;
|
||||
|
||||
if (choice_alert (_("Failed to start authentication. Try again"), 0, _("Yes"), _("No")) == 2) return 0;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
if (strncasecmp(line,PWDQ,strlen(PWDQ))== 0)
|
||||
child->writeLine(pwd,true);
|
||||
|
||||
if (strncasecmp(line,CONTMSG,strlen(CONTMSG)) == 0)
|
||||
break; // program starts...
|
||||
|
||||
if ((strncasecmp(line,BADPWD,strlen(BADPWD)) == 0) || (strncasecmp(line,SUDOBADPWD,strlen(SUDOBADPWD)) == 0)) {
|
||||
// end process
|
||||
child->waitForChild();
|
||||
delete child;
|
||||
|
||||
if (choice_alert (_("The password is wrong. Try again?"), 0, _("Yes"), _("No")) == 2) return 0;
|
||||
|
||||
goto tryagain;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for program to end, discarding output
|
||||
int child_val = child->waitForChild();
|
||||
if (child_val==127) child_val=EDERUN_NOT_FOUND;
|
||||
if (child_val==126) child_val=EDERUN_NOT_EXEC;
|
||||
|
||||
// deallocate one string we allocated
|
||||
free(parts[2]);
|
||||
delete child;
|
||||
|
||||
return child_val;
|
||||
}
|
||||
|
||||
|
||||
static bool done_checks=false;
|
||||
static bool elauncher_found=false;
|
||||
|
||||
// Check availability of various necessary components
|
||||
// For the moment just elauncher :)
|
||||
void do_checks()
|
||||
{
|
||||
struct stat *buf = (struct stat*)malloc(sizeof(struct stat));
|
||||
if (stat (PREFIX"/bin/elauncher", buf) == 0)
|
||||
elauncher_found = true;
|
||||
else
|
||||
elauncher_found = false;
|
||||
}
|
||||
|
||||
|
||||
int edelib::run_program(const char *path, bool wait, bool root, bool use_elauncher)
|
||||
{
|
||||
char *execstr;
|
||||
if (!done_checks) do_checks();
|
||||
if (use_elauncher && elauncher_found) {
|
||||
if (root)
|
||||
asprintf(&execstr,"elauncher --root \"%s\"", path);
|
||||
else
|
||||
asprintf(&execstr,"elauncher \"%s\"", path);
|
||||
run_fork (execstr, false); // elauncher can't wait
|
||||
} else {
|
||||
if (root)
|
||||
return run_as_root(path, wait);
|
||||
else
|
||||
return run_fork(path, wait);
|
||||
}
|
||||
return 0; // shutup compiler!
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::Run - Library for executing external programs
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef _edelib_Run_h_
|
||||
#define _edelib_Run_h_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace edelib {
|
||||
|
||||
/** \fn run_program(char *path, bool wait=true, bool root=false, bool use_elauncher=false)
|
||||
Standard EDE function for running external tasks. This function is time tested
|
||||
and provides a number of neat facilities.
|
||||
|
||||
Parameters:
|
||||
\a path - Full path to executable. If path is ommited, function will search PATH
|
||||
environment variable.
|
||||
\a wait - If true, parent process will be frozen until program ends. If false,
|
||||
it will fork into background and parent has no way to know what happened with it.
|
||||
default = true
|
||||
\a root - If true, sudo will be used to run program as root, with a nice facility
|
||||
to enter your root password. If sudo is not available, "su -c" will be tried.
|
||||
default = false
|
||||
\a use_elauncher - Program will be launched through elauncher which provides busy
|
||||
cursor, information about missing executable, standard output, backtrace in case
|
||||
of segfault etc. However, use of elauncher may cause some minimal overhead.
|
||||
Also, since there is no way to wait with elauncher, \a wait value will be
|
||||
ignored. default = false
|
||||
|
||||
Return value of the function is program "exit value". Usually exit value of 0
|
||||
means successful execution, and values 1-255 have certain special meanings
|
||||
per program documentation. Several special values above 255 are:
|
||||
EDERUN_NOT_FOUND - \a cmd doesn't exist
|
||||
EDERUN_EMPTY - \a cmd is empty
|
||||
EDERUN_NOT_EXEC - \a cmd doesn't have execute permission
|
||||
EDERUN_FORK_FAILED - fork() function returned a PID of -1 (see fork(2))
|
||||
EDERUN_WAITPID_FAILED - waitpid() function resulted with error (see waitpid(2))
|
||||
EDERUN_EXECVE_FAILED - execve() function returned -1 (see execve(2))
|
||||
EDERUN_PTY_FAILED - could not create pseudo-terminal (see getpt(3) and grantpt(3))
|
||||
*/
|
||||
|
||||
enum{
|
||||
EDERUN_NOT_FOUND = 65535,
|
||||
EDERUN_EMPTY = 65534,
|
||||
EDERUN_NOT_EXEC = 65533,
|
||||
EDERUN_FORK_FAILED = 65532,
|
||||
EDERUN_WAITPID_FAILED = 65531,
|
||||
EDERUN_EXECVE_FAILED = 65530,
|
||||
EDERUN_PTY_FAILED = 65529,
|
||||
EDERUN_USER_CANCELED = 65528
|
||||
};
|
||||
|
||||
|
||||
int run_program(const char *path, bool wait=true, bool root=false, bool use_elauncher=false);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
360
edelib2/Util.cpp
360
edelib2/Util.cpp
@ -1,360 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Library of useful functions
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <fltk/filename.h>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# define access(a,b) _access(a,b)
|
||||
# define mkdir(a,b) _mkdir(a)
|
||||
# define R_OK 4
|
||||
|
||||
#else
|
||||
|
||||
# include <unistd.h>
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
// From Enumerations.h
|
||||
#ifdef _WIN32
|
||||
# undef slash
|
||||
# define slash '\\'
|
||||
#else
|
||||
# undef slash
|
||||
# define slash '/'
|
||||
#endif
|
||||
// End Enumerations.h
|
||||
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
// Test if path is absolute or relative
|
||||
int edelib::is_path_rooted(const char *fn)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (fn[0] == '/' || fn[0] == '.' || fn[0] == '\\' || fn[1]==':')
|
||||
#else
|
||||
if (fn[0] == '/' || fn[0] == '.')
|
||||
#endif
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// recursively create a path in the file system
|
||||
bool edelib::make_path( const char *path )
|
||||
{
|
||||
if(access(path, 0))
|
||||
{
|
||||
const char *s = strrchr( path, slash );
|
||||
if ( !s ) return 0;
|
||||
int len = s-path;
|
||||
char *p = (char*)malloc( len+1 );
|
||||
memcpy( p, path, len );
|
||||
p[len] = 0;
|
||||
make_path( (const char*)p );
|
||||
free( p );
|
||||
return ( mkdir( path, 0777 ) == 0 );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// create the path needed for file using make_path
|
||||
bool edelib::make_path_for_file( const char *path )
|
||||
{
|
||||
const char *s = strrchr( path, slash );
|
||||
if ( !s ) return false;
|
||||
int len = s-path;
|
||||
char *p = (char*)malloc( len+1 );
|
||||
memcpy( p, path, len );
|
||||
p[len] = 0;
|
||||
bool ret=make_path( (const char*)p );
|
||||
free( p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Cross-platform function for system path
|
||||
char* edelib::get_sys_dir()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return SYSTEM_PATH;
|
||||
#else
|
||||
static char path[PATH_MAX];
|
||||
HKEY hKey;
|
||||
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &hKey)==ERROR_SUCCESS)
|
||||
{
|
||||
DWORD size=4096;
|
||||
RegQueryValueExW(hKey, L"CommonFilesDir", NULL, NULL, (LPBYTE)path, &size);
|
||||
RegCloseKey(hKey);
|
||||
return path;
|
||||
}
|
||||
return "C:\\EDE\\";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Cross-platform function for home directory...
|
||||
// I don't see the purpose since getenv("HOME") works just fine
|
||||
/*char* edelib::get_homedir() {
|
||||
char *path = new char[PATH_MAX];
|
||||
const char *str1;
|
||||
|
||||
str1=getenv("HOME");
|
||||
if (str1) {
|
||||
memcpy(path, str1, strlen(str1)+1);
|
||||
return path;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
// strdupcat() - it's cool to strcat with implied realloc
|
||||
// -- NOTE: due to use of realloc *always* use strdupcat return value:
|
||||
// dest = strdupcat(dest,src);
|
||||
// and *never* use it like:
|
||||
// strdupcat(dest,src);
|
||||
char* edelib::strdupcat(char *dest, const char *src)
|
||||
{
|
||||
if (!dest) {
|
||||
dest=(char*)malloc(strlen(src));
|
||||
} else {
|
||||
dest=(char*)realloc (dest, strlen(dest)+strlen(src)+1);
|
||||
}
|
||||
strcat(dest,src);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
// wstrim() - for trimming characters (used in parser)
|
||||
// parts of former fl_trimleft and fl_trimright from Fl_Util.cpp
|
||||
char* edelib::wstrim(char *string)
|
||||
{
|
||||
if(!string)
|
||||
return NULL;
|
||||
|
||||
char *start;
|
||||
int len = strlen(string);
|
||||
|
||||
if (len) {
|
||||
char *p = string + len;
|
||||
do {
|
||||
p--;
|
||||
if ( !isspace(*p) ) break;
|
||||
} while ( p != string );
|
||||
|
||||
if ( !isspace(*p) ) p++;
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
for(start = string; *start && isspace (*start); start++);
|
||||
memmove(string, start, strlen(start) + 1);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
const char* edelib::twstrim(const char* string)
|
||||
{
|
||||
static char buffer[4096];
|
||||
if (strlen(string)>4095) {
|
||||
strncpy(buffer,string,4095);
|
||||
buffer[4095]='\0';
|
||||
} else
|
||||
strcpy(buffer,string);
|
||||
wstrim((char*)buffer);
|
||||
return (const char*)buffer;
|
||||
}
|
||||
|
||||
// hmmmh?
|
||||
/*
|
||||
char* wstrim(const char *string)
|
||||
{
|
||||
char *newstring = strdup(string);
|
||||
return wstrim(newstring);
|
||||
}*/
|
||||
|
||||
// Returns nicely formatted string for byte sizes
|
||||
const char* edelib::nice_size(double size) {
|
||||
static char buffer[256];
|
||||
if (size<1024) {
|
||||
snprintf(buffer,255,"%d B",(int)size);
|
||||
} else if (size<1024*10) {
|
||||
snprintf(buffer,255,"%.1f kB",(float)size/1024);
|
||||
} else if (size<1024*1024) {
|
||||
snprintf(buffer,255,"%d kB",(int)size/1024);
|
||||
} else if (size<1024*1024*10) {
|
||||
snprintf(buffer,255,"%.1f MB",(float)size/(1024*1024));
|
||||
} else if (size<1024*1024*1024) {
|
||||
snprintf(buffer,255,"%d MB",(int)size/(1024*1024));
|
||||
} else if (size<1024*1024*1024*10) {
|
||||
snprintf(buffer,255,"%.1f GB",(float)size/(1024*1024*1024));
|
||||
} else {
|
||||
snprintf(buffer,255,"%d GB",(int)size/(1024*1024*1024));
|
||||
}
|
||||
return (const char*) buffer;
|
||||
}
|
||||
|
||||
|
||||
const char* edelib::nice_time(long int epoch) {
|
||||
static char buffer[256];
|
||||
|
||||
const time_t k = (const time_t)epoch;
|
||||
const struct tm *timeptr = localtime(&k);
|
||||
// Date/time format should be moved to configuration
|
||||
snprintf(buffer,255,"%.2d.%.2d.%.4d. %.2d:%.2d", timeptr->tm_mday, timeptr->tm_mon, 1900+timeptr->tm_year, timeptr->tm_hour, timeptr->tm_min);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Find in haystack any of needles (divided with separator)
|
||||
char* edelib::strstrmulti(const char *haystack, const char *needles, const char *separator) {
|
||||
if (!haystack || !needles || (strlen(haystack)==0) || (strlen(needles)==0))
|
||||
return (char*)haystack; // this means that empty search returns true
|
||||
char *copy = strdup(needles);
|
||||
char *token = strtok(copy, separator);
|
||||
char *result = 0;
|
||||
do {
|
||||
if ((result = strstr(haystack,token))) break;
|
||||
} while ((token = strtok(NULL, separator)));
|
||||
free (copy);
|
||||
if (!result && (strcmp(separator,needles+strlen(needles)-strlen(separator))==0))
|
||||
return (char*)haystack; // again
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// vec_from_string() - similar to explode() in PHP or split() in Perl
|
||||
// adapted from Fl_String_List to use vector
|
||||
/*std::vector<char*> vec_from_string(const char *str, const char *separator)
|
||||
{
|
||||
if(!str) return std::vector<char*> ();
|
||||
|
||||
const char *ptr = str;
|
||||
const char *s = strstr(ptr, separator);
|
||||
std::vector<char*> retval;
|
||||
if(s) {
|
||||
unsigned separator_len = strlen(separator);
|
||||
do {
|
||||
unsigned len = s - ptr;
|
||||
if (len) {
|
||||
retval.push_back(strndup(ptr,len));
|
||||
} else {
|
||||
retval.push_back(NULL);
|
||||
}
|
||||
|
||||
ptr = s + separator_len;
|
||||
s = strstr(ptr, separator);
|
||||
}
|
||||
while(s);
|
||||
|
||||
if(*ptr) {
|
||||
retval.push_back(strdup(ptr));
|
||||
}
|
||||
} else {
|
||||
retval.push_back(strdup(ptr));
|
||||
}
|
||||
return retval;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
// Print to a static char[] and return pointer
|
||||
const char* edelib::tsprintf(char *format, ...)
|
||||
{
|
||||
static char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer, 4095, format, args);
|
||||
va_end(args);
|
||||
return (const char*)buffer;
|
||||
}
|
||||
|
||||
char* edelib::tasprintf(char *format, ...)
|
||||
{
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer, 4095, format, args);
|
||||
va_end(args);
|
||||
return strdup(buffer);
|
||||
}
|
||||
|
||||
|
||||
// This function exists on some OSes and is mentioned in C textbooks
|
||||
// However, we can just use sprintf instead
|
||||
|
||||
/*
|
||||
char *
|
||||
itoa(int value, char *string, int radix)
|
||||
{
|
||||
char tmp[33];
|
||||
char *tp = tmp;
|
||||
int i;
|
||||
unsigned v;
|
||||
int sign;
|
||||
char *sp;
|
||||
|
||||
if (radix > 36 || radix <= 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sign = (radix == 10 && value < 0);
|
||||
if (sign)
|
||||
v = -value;
|
||||
else
|
||||
v = (unsigned)value;
|
||||
while (v || tp == tmp)
|
||||
{
|
||||
i = v % radix;
|
||||
v = v / radix;
|
||||
if (i < 10)
|
||||
*tp++ = i+'0';
|
||||
else
|
||||
*tp++ = i + 'a' - 10;
|
||||
}
|
||||
|
||||
if (string == 0)
|
||||
string = (char *)malloc((tp-tmp)+sign+1);
|
||||
sp = string;
|
||||
|
||||
if (sign)
|
||||
*sp++ = '-';
|
||||
while (tp > tmp)
|
||||
*sp++ = *--tp;
|
||||
*sp = 0;
|
||||
return string;
|
||||
}*/
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Library of useful functions
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef edelib_Util_h
|
||||
#define edelib_Util_h
|
||||
|
||||
#include "../edeconf.h"
|
||||
|
||||
|
||||
namespace edelib {
|
||||
|
||||
|
||||
// Constants
|
||||
#define SYSTEM_PATH PREFIX"/share/ede"
|
||||
#define DOC_PATH SYSTEM_PATH"/doc"
|
||||
|
||||
|
||||
// Cross-platform test if path is absolute or relative
|
||||
int is_path_rooted(const char *fn);
|
||||
|
||||
// Recursively create a path in the file system
|
||||
bool make_path( const char *path );
|
||||
|
||||
// Create the path needed for file using make_path
|
||||
bool make_path_for_file( const char *path );
|
||||
|
||||
// Cross-platform function for system files location
|
||||
char* get_sys_dir();
|
||||
|
||||
// strcat() that also does realloc if needed. Useful if
|
||||
// e.g. you have a loop which grows string in each pass
|
||||
// -- Note: due to use of realloc *always* use strdupcat return value:
|
||||
// dest = strdupcat(dest,src);
|
||||
// and *never* use it like:
|
||||
// strdupcat(dest,src);
|
||||
|
||||
// NOTE this function is not used! Its use is not recommended
|
||||
|
||||
char* strdupcat(char *dest, const char *src);
|
||||
|
||||
// Whitespace trim (both left and right)
|
||||
char* wstrim(char *string);
|
||||
|
||||
// Version with temporary results (static char[])
|
||||
const char* twstrim(const char *string);
|
||||
|
||||
// Finds in haystack any of strings contained in string "needles". The substrings
|
||||
// are divided with separator.
|
||||
// Not actually used...
|
||||
char* strstrmulti(const char *haystack, const char *needles, const char *separator);
|
||||
|
||||
// Returns nicely formatted string for byte sizes e.g. "1.2 kB" for size=1284
|
||||
const char* nice_size(double size);
|
||||
|
||||
// Returns nicely formatted string for date and time given in seconds since
|
||||
// Epoch. This should be in config
|
||||
const char* nice_time(long int epoch);
|
||||
|
||||
// Create vector from string using separator
|
||||
//std::vector<char*> vec_from_string(const char *str, const char *separator);
|
||||
|
||||
|
||||
/*! \fn const char* edelib::tsprintf(char* format, ...)
|
||||
|
||||
A useful function which executes sprintf() on a static char[] variable big enough to
|
||||
hold short temporary strings. The variable remains valid until next call.
|
||||
|
||||
Use:
|
||||
run_program(tsprintf(PREFIX"/bin/eiconsconf %s",param));
|
||||
|
||||
When setting text values of fltk objects, instead use tasprintf which executes a strdup.
|
||||
Example:
|
||||
window->label(tasprintf("%s, version %s",appname,appversion));
|
||||
*/
|
||||
|
||||
const char* tsprintf(char* format, ...);
|
||||
|
||||
char* tasprintf(char* format, ...);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* About dialog
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "about_dialog.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../edeconf.h"
|
||||
#include "NLS.h"
|
||||
#include "Run.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
const char* copying_file = "copying.html";
|
||||
|
||||
|
||||
static Window *aboutWindow;
|
||||
|
||||
void showCopyingInfo()
|
||||
{
|
||||
run_program(tsprintf("file:%s/%s", DOC_PATH, copying_file),false,false,true);
|
||||
}
|
||||
|
||||
void cb_Click(Button* b, void*)
|
||||
{
|
||||
showCopyingInfo();
|
||||
}
|
||||
|
||||
void cb_Close(Button*, void*)
|
||||
{
|
||||
aboutWindow->hide();
|
||||
}
|
||||
|
||||
void edelib::about_dialog(const char *progname, const char *progversion, const char *addcomment)
|
||||
{
|
||||
aboutWindow = new Window(275, 190);
|
||||
aboutWindow->begin();
|
||||
{InvisibleBox* o = new InvisibleBox(5, 5, 265, 44);
|
||||
o->labelsize(18);
|
||||
o->label(tasprintf("%s %s",progname,progversion)); // tmp will be deallocated by InvisibleBox destructor
|
||||
o->box(FLAT_BOX);
|
||||
}
|
||||
{InvisibleBox* o = new InvisibleBox(5, 50, 265, 20);
|
||||
o->label(tasprintf(_("Part of Equinox Desktop Environment %s"),PACKAGE_VERSION)); // tmp will be deallocated by InvisibleBox destructor
|
||||
o->box(FLAT_BOX);
|
||||
}
|
||||
new InvisibleBox(5, 70, 265, 20, _("(C) Copyright 2000-2005 EDE Authors"));
|
||||
{InvisibleBox* o = new InvisibleBox(5, 90, 265, 40, _("This program is licenced under terms of the GNU General Public License version 2 or newer."));
|
||||
o->labelsize(10);
|
||||
o->align(ALIGN_INSIDE|ALIGN_WRAP);
|
||||
}
|
||||
{Button* o = new Button(65, 124, 145, 20, _("Click here for details."));
|
||||
o->box(NO_BOX);
|
||||
o->buttonbox(NO_BOX);
|
||||
o->labelcolor(BLUE);
|
||||
o->highlight_textcolor(RED);
|
||||
o->labelsize(10);
|
||||
o->callback((Callback*)cb_Click);
|
||||
((Window*)(o->parent()))->hotspot(o);
|
||||
}
|
||||
{Button* o = new Button(95, 152, 80, 25, "&Close");
|
||||
o->callback((Callback*)cb_Close);
|
||||
}
|
||||
aboutWindow->end();
|
||||
|
||||
aboutWindow->label(tasprintf(_("About %s"), progname)); // tmp will be deallocated by Window destructor
|
||||
aboutWindow->set_modal();
|
||||
aboutWindow->resizable(aboutWindow);
|
||||
|
||||
aboutWindow->end();
|
||||
aboutWindow->show();
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* About dialog
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef _edelib_aboutdialog_h_
|
||||
#define _edelib_aboutdialog_h_
|
||||
|
||||
#include <fltk/Window.h>
|
||||
#include <fltk/InvisibleBox.h>
|
||||
#include <fltk/Button.h>
|
||||
|
||||
|
||||
namespace edelib {
|
||||
|
||||
void about_dialog(const char *progname, const char *progversion, const char *addcomment = 0);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
# data file for the eFLTK User Interface Designer (eFLUID)
|
||||
version 2,0003
|
||||
images_dir ./
|
||||
i18n
|
||||
header_name {.h}
|
||||
code_name {.cpp}
|
||||
gridx 5
|
||||
gridy 5
|
||||
snap 3
|
||||
decl {// The EDE control center.} {}
|
||||
|
||||
decl {// Copyright (c) 2000. - 2005. EDE Authors} {}
|
||||
|
||||
decl {// This program is licenced under terms of the} {}
|
||||
|
||||
decl {// GNU General Public Licence version 2 or newer.} {}
|
||||
|
||||
decl {// See COPYING for details} {}
|
||||
|
||||
decl {//} {}
|
||||
|
||||
decl {\#include <efltk/Fl_Util.h>} {}
|
||||
|
||||
decl {\#include <edeconf.h>} {}
|
||||
|
||||
decl {Fl_Window *aboutWindow;} {}
|
||||
|
||||
class AboutDialog {open
|
||||
} {
|
||||
Function {AboutDialog(const char *progname, const char *progversion, const char *addcomment = 0)} {open return_type void
|
||||
} {
|
||||
Fl_Window aboutWindow {open
|
||||
xywh {652 341 275 190} resizable
|
||||
extra_code {aboutWindow->label(Fl_String(_("About"))+Fl_String(" ")+Fl_String(progname));} modal visible
|
||||
} {
|
||||
Fl_Box {} {
|
||||
xywh {5 5 265 44} align FL_ALIGN_INSIDE|FL_ALIGN_WRAP label_size 18
|
||||
extra_code {o->label(Fl_String(progname)+Fl_String(" ")+Fl_String(progversion));}
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Part of Equinox Desktop Environment}
|
||||
xywh {5 49 265 20} align FL_ALIGN_INSIDE|FL_ALIGN_WRAP
|
||||
extra_code {o->label(o->label() + Fl_String(" "PACKAGE_VERSION));}
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {(C) Copyright 2000-2005 EDE Authors}
|
||||
xywh {5 74 265 20} align FL_ALIGN_INSIDE|FL_ALIGN_WRAP
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {This program is licenced under terms of the GNU General Public License version 2 or newer.}
|
||||
xywh {5 98 265 30} align FL_ALIGN_TOP|FL_ALIGN_INSIDE|FL_ALIGN_WRAP label_size 10
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {Click here for details.}
|
||||
callback {showCopyingInfo();}
|
||||
xywh {65 124 145 20} hotspot box NO_BOX button_box NO_BOX label_color 4 highlight_label_color 1 label_size 10
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {&Close}
|
||||
callback {aboutWindow->hide();} selected
|
||||
xywh {95 152 80 25}
|
||||
}
|
||||
}
|
||||
code {aboutWindow->end();
|
||||
aboutWindow->show();} {}
|
||||
}
|
||||
Function {showCopyingInfo()} {open private
|
||||
} {
|
||||
code {fl_start_child_process("elauncher file:/usr/share/ede/doc/copying.html",false);} {}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:39+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: aboutdialog.cpp:27
|
||||
msgid "About "
|
||||
msgstr ""
|
||||
|
||||
#: aboutdialog.cpp:36
|
||||
msgid "Part of Equinox Desktop Environment "
|
||||
msgstr ""
|
||||
|
||||
#: aboutdialog.cpp:40
|
||||
msgid "(C) Copyright 2000-2005 EDE Authors"
|
||||
msgstr ""
|
||||
|
||||
#: aboutdialog.cpp:44
|
||||
msgid ""
|
||||
"This program is licenced under terms of the GNU General Public License "
|
||||
"version 2 or newer."
|
||||
msgstr ""
|
||||
|
||||
#: aboutdialog.cpp:49
|
||||
msgid "Click here for details."
|
||||
msgstr ""
|
||||
|
||||
#: aboutdialog.cpp:58
|
||||
msgid "&Close"
|
||||
msgstr ""
|
@ -1,693 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::PtyProcess - This class enables us to "chat" with terminal programs synchronously
|
||||
* Adapted from KDE (kdelibs/kdesu/process.cpp) - original copyright message below
|
||||
*
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/* vi: ts=8 sts=4 sw=4
|
||||
*
|
||||
* Id: process.cpp 439322 2005-07-27 18:49:23Z coolo
|
||||
*
|
||||
* This file is part of the KDE project, module kdesu.
|
||||
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
|
||||
*
|
||||
* This file contains code from TEShell.C of the KDE konsole.
|
||||
* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||
*
|
||||
* This is free software; you can use this library under the GNU Library
|
||||
* General Public License, version 2. See the file "COPYING.LIB" for the
|
||||
* exact licensing terms.
|
||||
*
|
||||
* process.cpp: Functionality to build a front end to password asking
|
||||
* terminal programs.
|
||||
*/
|
||||
|
||||
//#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if defined(__SVR4) && defined(sun)
|
||||
#include <stropts.h>
|
||||
#include <sys/stream.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> // Needed on some systems.
|
||||
#endif
|
||||
|
||||
//#include <qglobal.h>
|
||||
//#include <qfile.h>
|
||||
|
||||
//#include <kdebug.h>
|
||||
//#include <kstandarddirs.h>
|
||||
|
||||
#include "process.h"
|
||||
#include "pty.h"
|
||||
//#include "kcookie.h"
|
||||
#include "NLS.h"
|
||||
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
int strpos(const char *string, char c)
|
||||
{
|
||||
for (uint i=0;i<strlen(string);i++)
|
||||
if (string[i] == c) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PtyProcess::waitMS(int fd,int ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000*ms;
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd,&fds);
|
||||
return select(fd+1, &fds, 0L, 0L, &tv);
|
||||
}
|
||||
|
||||
/*
|
||||
** Basic check for the existence of @p pid.
|
||||
** Returns true iff @p pid is an extant process.
|
||||
*/
|
||||
bool PtyProcess::checkPid(pid_t pid)
|
||||
{
|
||||
return kill(pid,0) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check process exit status for process @p pid.
|
||||
** On error (no child, no exit), return Error (-1).
|
||||
** If child @p pid has exited, return its exit status,
|
||||
** (which may be zero).
|
||||
** If child @p has not exited, return NotExited (-2).
|
||||
*/
|
||||
|
||||
int PtyProcess::checkPidExited(pid_t pid)
|
||||
{
|
||||
int state, ret;
|
||||
ret = waitpid(pid, &state, WNOHANG);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "waitpid(): " << perror << "\n";
|
||||
return Error;
|
||||
}
|
||||
if (ret == pid)
|
||||
{
|
||||
if (WIFEXITED(state))
|
||||
return WEXITSTATUS(state);
|
||||
if (WIFSIGNALED(state) && WTERMSIG(state)==SIGSEGV)
|
||||
return Crashed;
|
||||
return Killed;
|
||||
}
|
||||
|
||||
return NotExited;
|
||||
}
|
||||
|
||||
|
||||
class PtyProcess::PtyProcessPrivate
|
||||
{
|
||||
public:
|
||||
char **env;
|
||||
~PtyProcessPrivate() {
|
||||
int i=0;
|
||||
if (env)
|
||||
while (env[i] != NULL)
|
||||
free(env[i++]);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
PtyProcess::PtyProcess()
|
||||
{
|
||||
m_bTerminal = false;
|
||||
m_bErase = false;
|
||||
m_pPTY = 0L;
|
||||
d = new PtyProcessPrivate;
|
||||
d->env = 0;
|
||||
m_Pid = 0;
|
||||
m_Inbuf = m_TTY = m_Exit = m_Command = 0;
|
||||
}
|
||||
|
||||
|
||||
int PtyProcess::init()
|
||||
{
|
||||
delete m_pPTY;
|
||||
m_pPTY = new PTY();
|
||||
m_Fd = m_pPTY->getpt();
|
||||
if (m_Fd < 0)
|
||||
return -1;
|
||||
if ((m_pPTY->grantpt() < 0) || (m_pPTY->unlockpt() < 0))
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: Master setup failed.\n");
|
||||
m_Fd = -1;
|
||||
return -1;
|
||||
}
|
||||
if (m_TTY) free(m_TTY);
|
||||
m_TTY = strdup(m_pPTY->ptsname());
|
||||
// m_Inbuf.resize(0);
|
||||
if (m_Inbuf) free(m_Inbuf);
|
||||
m_Inbuf = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PtyProcess::~PtyProcess()
|
||||
{
|
||||
if (m_TTY) free(m_TTY);
|
||||
if (m_Inbuf) free(m_Inbuf);
|
||||
delete m_pPTY;
|
||||
delete d;
|
||||
}
|
||||
|
||||
/** Set additinal environment variables. */
|
||||
void PtyProcess::setEnvironment( const char **env )
|
||||
{
|
||||
// deallocate old environment store
|
||||
int i=0;
|
||||
if (d->env)
|
||||
while (d->env[i] != NULL)
|
||||
free(d->env[i++]);
|
||||
|
||||
// count number of environment variables
|
||||
int n_env=0;
|
||||
while (env[n_env++] != NULL);
|
||||
d->env = (char**)malloc((n_env+2)*sizeof(char *));
|
||||
|
||||
// copy env to d->env
|
||||
i=0;
|
||||
while (env[i] != NULL) {
|
||||
d->env[i] = strdup(env[i]);
|
||||
i++; // gcc insists that strdup(env[i++]) above would be ambiguous...
|
||||
}
|
||||
d->env[i] = NULL;
|
||||
}
|
||||
|
||||
char **PtyProcess::environment() const
|
||||
{
|
||||
return d->env;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one line of input. The terminal is in canonical mode, so you always
|
||||
* read a line at at time
|
||||
*/
|
||||
|
||||
char *PtyProcess::readLine(bool block)
|
||||
{
|
||||
int pos;
|
||||
char *ret = 0;
|
||||
|
||||
if (m_Inbuf && strlen(m_Inbuf)>0)
|
||||
{
|
||||
pos = strpos(m_Inbuf,'\n');
|
||||
if (pos == -1)
|
||||
{
|
||||
ret = strdup(m_Inbuf);
|
||||
free(m_Inbuf);
|
||||
m_Inbuf = 0;
|
||||
} else
|
||||
{
|
||||
// ret = part of m_Inbuf before \n
|
||||
// m_Inbuf = part of m_Inbuf after \n
|
||||
ret = strdup(m_Inbuf);
|
||||
free(m_Inbuf);
|
||||
m_Inbuf = strdup(ret + pos + 1);
|
||||
ret[pos+1] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int flags = fcntl(m_Fd, F_GETFL);
|
||||
if (flags < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "fcntl(F_GETFL): " << perror << "\n";
|
||||
fprintf (stderr, "Edelib: PtyProcess: fcntl not working - %d\n", errno);
|
||||
return ret;
|
||||
}
|
||||
int oflags = flags;
|
||||
if (block)
|
||||
flags &= ~O_NONBLOCK;
|
||||
else
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
if ((flags != oflags) && (fcntl(m_Fd, F_SETFL, flags) < 0))
|
||||
{
|
||||
// We get an error here when the child process has closed
|
||||
// the file descriptor already.
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nbytes;
|
||||
char buf[256];
|
||||
while (1)
|
||||
{
|
||||
nbytes = read(m_Fd, buf, 255);
|
||||
if (nbytes == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else break;
|
||||
}
|
||||
if (nbytes == 0)
|
||||
break; // eof
|
||||
|
||||
buf[nbytes] = '\000';
|
||||
if (m_Inbuf)
|
||||
m_Inbuf = (char*)realloc(m_Inbuf, strlen(m_Inbuf)+nbytes+1);
|
||||
else {
|
||||
m_Inbuf = (char*)malloc(nbytes+1);
|
||||
m_Inbuf[0] = 0;
|
||||
}
|
||||
strcat(m_Inbuf, buf);
|
||||
|
||||
ret = strdup(m_Inbuf);
|
||||
// only one line...
|
||||
pos = strpos(ret,'\n');
|
||||
if (pos != -1) {
|
||||
free (m_Inbuf);
|
||||
m_Inbuf = strdup(ret + pos + 1);
|
||||
ret[pos+1] = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PtyProcess::writeLine(const char *line, bool addnl)
|
||||
{
|
||||
if (line && strlen(line)>0)
|
||||
write(m_Fd, line, strlen(line));
|
||||
if (addnl)
|
||||
write(m_Fd, "\n", 1);
|
||||
}
|
||||
|
||||
|
||||
void PtyProcess::unreadLine(const char *line, bool addnl)
|
||||
{
|
||||
char *tmp = (char*) malloc(strlen(line)+1);
|
||||
strcpy(tmp,line);
|
||||
if (addnl)
|
||||
strcat(tmp, "\n");
|
||||
|
||||
if (m_Inbuf) {
|
||||
char *tmp2 = (char*)malloc(strlen(m_Inbuf)+strlen(tmp)+1);
|
||||
strcpy(tmp2,tmp);
|
||||
strcat(tmp2,m_Inbuf);
|
||||
free(m_Inbuf);
|
||||
m_Inbuf=tmp2;
|
||||
free(tmp);
|
||||
} else
|
||||
m_Inbuf = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork and execute the command. This returns in the parent.
|
||||
*/
|
||||
|
||||
int PtyProcess::exec(const char *command, const char **args)
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: Running `%s'\n", command);
|
||||
int i;
|
||||
|
||||
if (init() < 0)
|
||||
return -1;
|
||||
|
||||
// Open the pty slave before forking. See SetupTTY()
|
||||
fprintf (stderr, "pty: %s\n", m_TTY);
|
||||
int slave = open(m_TTY, O_RDWR);
|
||||
if (slave < 0)
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: Could not open slave pty.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((m_Pid = fork()) == -1)
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: fork(): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parent
|
||||
if (m_Pid)
|
||||
{
|
||||
close(slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Child
|
||||
if (SetupTTY(slave) < 0) {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
i=0;
|
||||
while (d->env[i] != NULL)
|
||||
putenv(d->env[i++]);
|
||||
// unsetenv("KDE_FULL_SESSION");
|
||||
|
||||
// From now on, terminal output goes through the tty.
|
||||
|
||||
const char *path;
|
||||
// if (strchr(command,'/'))
|
||||
path = command;
|
||||
/* VEDRAN: This is now handled elsewhere - fully qualified path
|
||||
*must* be provided*/
|
||||
// else
|
||||
// {
|
||||
// QString file = KStandardDirs::findExe(command);
|
||||
// if (file.isEmpty())
|
||||
// {
|
||||
// kdError(900) << k_lineinfo << command << " not found\n";
|
||||
// _exit(1);
|
||||
// }
|
||||
// path = QFile::encodeName(file);
|
||||
// }
|
||||
|
||||
// const char **argp = (const char **)malloc((args.count()+2)*sizeof(char *));
|
||||
/* const char **cptr = args;
|
||||
int count=0;
|
||||
while (cptr++)
|
||||
count++;
|
||||
fprintf(stderr, "G\n");
|
||||
const char **argp = (const char **)malloc((count+2)*sizeof(char *));
|
||||
fprintf(stderr, "H\n");
|
||||
|
||||
i = 0;
|
||||
// argp[i++] = strdup(path);
|
||||
cptr = args;
|
||||
int j=0;
|
||||
while (cptr[j])
|
||||
argp[i++] = strdup(cptr[j++]);
|
||||
// for (QList<QByteArray>::ConstIterator it=args.begin(); it!=args.end(); ++it)
|
||||
// argp[i++] = *it;
|
||||
|
||||
argp[i + 2] = 0;*/
|
||||
|
||||
execv(path, const_cast<char **>(args));
|
||||
_exit(1);
|
||||
return -1; // Shut up compiler. Never reached.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait until the terminal is set into no echo mode. At least one su
|
||||
* (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password:
|
||||
* prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly
|
||||
* taking the password with it. So we wait until no echo mode is set
|
||||
* before writing the password.
|
||||
* Note that this is done on the slave fd. While Linux allows tcgetattr() on
|
||||
* the master side, Solaris doesn't.
|
||||
*/
|
||||
|
||||
int PtyProcess::WaitSlave()
|
||||
{
|
||||
int slave = open(m_TTY, O_RDWR);
|
||||
if (slave < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "Could not open slave tty.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// kdDebug(900) << k_lineinfo << "Child pid " << m_Pid << endl;
|
||||
|
||||
struct termios tio;
|
||||
while (1)
|
||||
{
|
||||
if (!checkPid(m_Pid))
|
||||
{
|
||||
close(slave);
|
||||
return -1;
|
||||
}
|
||||
if (tcgetattr(slave, &tio) < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "tcgetattr(): " << perror << "\n";
|
||||
close(slave);
|
||||
return -1;
|
||||
}
|
||||
if (tio.c_lflag & ECHO)
|
||||
{
|
||||
// kdDebug(900) << k_lineinfo << "Echo mode still on.\n";
|
||||
waitMS(slave,100);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
close(slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PtyProcess::enableLocalEcho(bool enable)
|
||||
{
|
||||
int slave = open(m_TTY, O_RDWR);
|
||||
if (slave < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "Could not open slave tty.\n";
|
||||
return -1;
|
||||
}
|
||||
struct termios tio;
|
||||
if (tcgetattr(slave, &tio) < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "tcgetattr(): " << perror << "\n";
|
||||
close(slave); return -1;
|
||||
}
|
||||
if (enable)
|
||||
tio.c_lflag |= ECHO;
|
||||
else
|
||||
tio.c_lflag &= ~ECHO;
|
||||
if (tcsetattr(slave, TCSANOW, &tio) < 0)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "tcsetattr(): " << perror << "\n";
|
||||
close(slave); return -1;
|
||||
}
|
||||
close(slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// runChild() -- added by Vedran
|
||||
// This routine will execute child process capturing all output
|
||||
//
|
||||
// Rationale:
|
||||
// Even though most users today use window managers to run programs and not
|
||||
// xterms, many XWindow programs will not display any kind of error dialog
|
||||
// if there is some error that prevents them to run, but instead produce
|
||||
// some sort of error message on stdout or stderr and set the exit code to
|
||||
// nonzero. While this makes them easier for scripting purposes, this will
|
||||
// leave a user unfamiliar with UNIX a bit baffled - they will click the
|
||||
// shiny icon and nothing will happen. This function should help a window
|
||||
// manager or program launcher to do something smart about it.
|
||||
|
||||
#define MAXBUF 10000
|
||||
|
||||
int PtyProcess::runChild()
|
||||
{
|
||||
int ret = NotExited;
|
||||
int nbytes;
|
||||
char buf[256];
|
||||
|
||||
const char *message = _("\n *** Further output ommitted by Edelib ***\n");
|
||||
|
||||
while (ret == NotExited) {
|
||||
while (1) {
|
||||
nbytes = read(m_Fd, buf, 255);
|
||||
if (nbytes == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else break;
|
||||
}
|
||||
if (nbytes == 0)
|
||||
break; // eof
|
||||
|
||||
buf[nbytes] = '\0';
|
||||
|
||||
// We don't want m_Inbuf to grow too big
|
||||
if (m_Inbuf && strlen(m_Inbuf)<=MAXBUF) {
|
||||
m_Inbuf = (char*)realloc(m_Inbuf, strlen(m_Inbuf)+nbytes+1);
|
||||
strcat(m_Inbuf, buf);
|
||||
|
||||
} else if (m_Inbuf == 0)
|
||||
m_Inbuf = strdup(buf);
|
||||
}
|
||||
ret = checkPidExited(m_Pid);
|
||||
}
|
||||
|
||||
if (m_Inbuf && strlen(m_Inbuf)>MAXBUF) {
|
||||
// Attach message about cutting out the rest
|
||||
m_Inbuf = (char*)realloc(m_Inbuf, strlen(m_Inbuf)+strlen(message));
|
||||
strcat(m_Inbuf, message);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy output to stdout until the child process exists, or a line of output
|
||||
* matches `m_Exit'.
|
||||
* We have to use waitpid() to test for exit. Merely waiting for EOF on the
|
||||
* pty does not work, because the target process may have children still
|
||||
* attached to the terminal.
|
||||
*/
|
||||
|
||||
int PtyProcess::waitForChild()
|
||||
{
|
||||
int retval = 1;
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
FD_SET(m_Fd, &fds);
|
||||
int ret = select(m_Fd+1, &fds, 0L, 0L, 0L);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "select(): " << perror << "\n";
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
char *line = readLine(false);
|
||||
while (line && strlen(line)>0)
|
||||
{
|
||||
if (m_Exit && strlen(m_Exit)>0 && !strncasecmp(line, m_Exit, strlen(m_Exit)))
|
||||
kill(m_Pid, SIGTERM);
|
||||
if (m_bTerminal)
|
||||
{
|
||||
fputs(line, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
line = readLine(false);
|
||||
}
|
||||
}
|
||||
|
||||
ret = checkPidExited(m_Pid);
|
||||
if (ret == Error)
|
||||
{
|
||||
if (errno == ECHILD) retval = 0;
|
||||
else retval = 1;
|
||||
break;
|
||||
}
|
||||
else if (ret == Killed || ret == Crashed)
|
||||
{
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
else if (ret == NotExited)
|
||||
{
|
||||
// keep checking
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = ret;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* SetupTTY: Creates a new session. The filedescriptor "fd" should be
|
||||
* connected to the tty. It is closed after the tty is reopened to make it
|
||||
* our controlling terminal. This way the tty is always opened at least once
|
||||
* so we'll never get EIO when reading from it.
|
||||
*/
|
||||
|
||||
int PtyProcess::SetupTTY(int fd)
|
||||
{
|
||||
// Reset signal handlers
|
||||
for (int sig = 1; sig < NSIG; sig++)
|
||||
signal(sig, SIG_DFL);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
// Close all file handles
|
||||
struct rlimit rlp;
|
||||
getrlimit(RLIMIT_NOFILE, &rlp);
|
||||
for (int i = 0; i < (int)rlp.rlim_cur; i++)
|
||||
if (i != fd) close(i);
|
||||
|
||||
// Create a new session.
|
||||
setsid();
|
||||
|
||||
// Open slave. This will make it our controlling terminal
|
||||
int slave = open(m_TTY, O_RDWR);
|
||||
if (slave < 0)
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: Could not open slave side: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
#if defined(__SVR4) && defined(sun)
|
||||
|
||||
// Solaris STREAMS environment.
|
||||
// Push these modules to make the stream look like a terminal.
|
||||
ioctl(slave, I_PUSH, "ptem");
|
||||
ioctl(slave, I_PUSH, "ldterm");
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TIOCSCTTY
|
||||
ioctl(slave, TIOCSCTTY, NULL);
|
||||
#endif
|
||||
|
||||
// Connect stdin, stdout and stderr
|
||||
dup2(slave, 0); dup2(slave, 1); dup2(slave, 2);
|
||||
if (slave > 2)
|
||||
close(slave);
|
||||
|
||||
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
|
||||
// translated to '\r\n'.
|
||||
struct termios tio;
|
||||
if (tcgetattr(0, &tio) < 0)
|
||||
{
|
||||
fprintf (stderr, "Edelib: PtyProcess: tcgetattr(): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
tio.c_oflag &= ~OPOST;
|
||||
if (tcsetattr(0, TCSANOW, &tio) < 0)
|
||||
{
|
||||
fprintf(stderr, "Edelib: PtyProcess: tcsetattr(): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PtyProcess::virtual_hook( int, void* )
|
||||
{ /*BASE::virtual_hook( id, data );*/ }
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::PtyProcess - This class enables us to "chat" with terminal programs synchronously
|
||||
* Adapted from KDE (kdelibs/kdesu/process.h) - original copyright message below
|
||||
*
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/* vi: ts=8 sts=4 sw=4
|
||||
*
|
||||
* Id: process.h 439322 2005-07-27 18:49:23Z coolo
|
||||
*
|
||||
* This file is part of the KDE project, module kdesu.
|
||||
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
|
||||
*
|
||||
* This is free software; you can use this library under the GNU Library
|
||||
* General Public License, version 2. See the file "COPYING.LIB" for the
|
||||
* exact licensing terms.
|
||||
*/
|
||||
|
||||
#ifndef _edelib_Process_h_
|
||||
#define _edelib_Process_h_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
//#include <qbytearray.h>
|
||||
//#include <qstring.h>
|
||||
//#include <qstringlist.h>
|
||||
//#include <qlist.h>
|
||||
|
||||
//#include <kdelibs_export.h>
|
||||
|
||||
namespace edelib {
|
||||
|
||||
class PTY;
|
||||
|
||||
/**
|
||||
* Synchronous communication with tty programs.
|
||||
*
|
||||
* PtyProcess provides synchronous communication with tty based programs.
|
||||
* The communications channel used is a pseudo tty (as opposed to a pipe)
|
||||
* This means that programs which require a terminal will work.
|
||||
*/
|
||||
|
||||
class PtyProcess
|
||||
{
|
||||
public:
|
||||
PtyProcess();
|
||||
virtual ~PtyProcess();
|
||||
|
||||
/**
|
||||
* Forks off and execute a command. The command's standard in and output
|
||||
* are connected to the pseudo tty. They are accessible with readLine
|
||||
* and writeLine.
|
||||
* @param command The command to execute.
|
||||
* @param args The arguments to the command.
|
||||
*/
|
||||
int exec(const char *command, const char **args);
|
||||
|
||||
/**
|
||||
* Reads a line from the program's standard out. Depending on the @em block
|
||||
* parameter, this call blocks until a single, full line is read.
|
||||
* @param block Block until a full line is read?
|
||||
* @return The output string.
|
||||
*/
|
||||
char *readLine(bool block=true);
|
||||
|
||||
/**
|
||||
* Writes a line of text to the program's standard in.
|
||||
* @param line The text to write.
|
||||
* @param addNewline Adds a '\n' to the line.
|
||||
*/
|
||||
void writeLine(const char *line, bool addNewline=true);
|
||||
|
||||
/**
|
||||
* Puts back a line of input.
|
||||
* @param line The line to put back.
|
||||
* @param addNewline Adds a '\n' to the line.
|
||||
*/
|
||||
void unreadLine(const char *line, bool addNewline=true);
|
||||
|
||||
/**
|
||||
* Sets the exit string. If a line of program output matches this,
|
||||
* waitForChild() will terminate the program and return.
|
||||
*/
|
||||
void setExitString(char *exit) { m_Exit = exit; }
|
||||
|
||||
/**
|
||||
* Waits for the child to exit, capturing all output.
|
||||
*/
|
||||
int runChild();
|
||||
|
||||
/**
|
||||
* Waits for the child to exit. See also setExitString.
|
||||
*/
|
||||
int waitForChild();
|
||||
|
||||
/**
|
||||
* Waits until the pty has cleared the ECHO flag. This is useful
|
||||
* when programs write a password prompt before they disable ECHO.
|
||||
* Disabling it might flush any input that was written.
|
||||
*/
|
||||
int WaitSlave();
|
||||
|
||||
/**
|
||||
* Enables/disables local echo on the pseudo tty.
|
||||
*/
|
||||
int enableLocalEcho(bool enable=true);
|
||||
|
||||
/**
|
||||
* Enables/disables terminal output. Relevant only to some subclasses.
|
||||
*/
|
||||
void setTerminal(bool terminal) { m_bTerminal = terminal; }
|
||||
|
||||
/**
|
||||
* Overwrites the password as soon as it is used. Relevant only to
|
||||
* some subclasses.
|
||||
*/
|
||||
void setErase(bool erase) { m_bErase = erase; }
|
||||
|
||||
/**
|
||||
* Set additinal environment variables.
|
||||
*/
|
||||
void setEnvironment( const char **env );
|
||||
|
||||
/**
|
||||
* Returns the filedescriptor of the process.
|
||||
*/
|
||||
inline int fd() const {return m_Fd;};
|
||||
|
||||
/**
|
||||
* Returns the pid of the process.
|
||||
*/
|
||||
inline int pid() const {return m_Pid;};
|
||||
|
||||
public /* static */:
|
||||
/*
|
||||
** This is a collection of static functions that can be
|
||||
** used for process control inside kdesu. I'd suggest
|
||||
** against using this publicly. There are probably
|
||||
** nicer Qt based ways to do what you want.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Wait @p ms miliseconds (ie. 1/10th of a second is 100ms),
|
||||
** using @p fd as a filedescriptor to wait on. Returns
|
||||
** select(2)'s result, which is -1 on error, 0 on timeout,
|
||||
** or positive if there is data on one of the selected fd's.
|
||||
**
|
||||
** @p ms must be in the range 0..999 (ie. the maximum wait
|
||||
** duration is 999ms, almost one second).
|
||||
*/
|
||||
static int waitMS(int fd,int ms);
|
||||
|
||||
|
||||
/*
|
||||
** Basic check for the existence of @p pid.
|
||||
** Returns true iff @p pid is an extant process,
|
||||
** (one you could kill - see man kill(2) for signal 0).
|
||||
*/
|
||||
static bool checkPid(pid_t pid);
|
||||
|
||||
/*
|
||||
** Check process exit status for process @p pid.
|
||||
** On error (no child, no exit), return -1.
|
||||
** If child @p pid has exited, return its exit status,
|
||||
** (which may be zero).
|
||||
** If child @p has not exited, return -2.
|
||||
*/
|
||||
enum checkPidStatus { Error=-1, NotExited=-2, Killed=-3, Crashed=-4 } ;
|
||||
static int checkPidExited(pid_t pid);
|
||||
|
||||
|
||||
protected:
|
||||
char **environment() const;
|
||||
|
||||
bool m_bErase, m_bTerminal;
|
||||
int m_Pid, m_Fd;
|
||||
char *m_Command, *m_Exit;
|
||||
|
||||
private:
|
||||
int init();
|
||||
int SetupTTY(int fd);
|
||||
|
||||
PTY *m_pPTY;
|
||||
char *m_Inbuf, *m_TTY;
|
||||
|
||||
protected:
|
||||
virtual void virtual_hook( int id, void* data );
|
||||
private:
|
||||
class PtyProcessPrivate;
|
||||
PtyProcessPrivate *d;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
353
edelib2/pty.cpp
353
edelib2/pty.cpp
@ -1,353 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::PTY - A class for handling pseudoterminals (PTYs)
|
||||
* Adapted from KDE (kdelibs/kdesu/kdesu_pty.cpp) - original copyright message below
|
||||
*
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/* vi: ts=8 sts=4 sw=4
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This file is part of the KDE project, module kdesu.
|
||||
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
|
||||
*
|
||||
* This file contains code from TEShell.C of the KDE konsole.
|
||||
* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||
*
|
||||
* This is free software; you can use this library under the GNU Library
|
||||
* General Public License, version 2. See the file "COPYING.LIB" for the
|
||||
* exact licensing terms.
|
||||
*
|
||||
* pty.cpp: Access to PTY's on different systems a la UNIX98.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* Needed for getpt, ptsname in glibc 2.1.x systems */
|
||||
#endif
|
||||
|
||||
//#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(__osf__) || defined(__CYGWIN__)
|
||||
#include <pty.h>
|
||||
#endif
|
||||
|
||||
//#include <qglobal.h>
|
||||
|
||||
//#include <kdebug.h>
|
||||
//#include <kstandarddirs.h>
|
||||
#include "pty.h"
|
||||
|
||||
// FIXME: Blah defines
|
||||
#define HAVE_GETPT
|
||||
#define HAVE_PTSNAME
|
||||
#define HAVE_GRANTPT
|
||||
#define HAVE_UNLOCKPT
|
||||
|
||||
// stdlib.h is meant to declare the prototypes but doesn't :(
|
||||
#ifndef __THROW
|
||||
#define __THROW
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GRANTPT
|
||||
extern "C" int grantpt(int fd) __THROW;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTSNAME
|
||||
extern "C" char * ptsname(int fd) __THROW;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNLOCKPT
|
||||
extern "C" int unlockpt(int fd) __THROW;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE__GETPTY
|
||||
extern "C" char *_getpty(int *, int, mode_t, int);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE__PTY_H
|
||||
#include <pty.h>
|
||||
#endif
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#elif defined(HAVE_UTIL_H)
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
void *qalloc(void *ptr, size_t size)
|
||||
{
|
||||
if (ptr)
|
||||
return realloc (ptr, size);
|
||||
else
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
|
||||
PTY::PTY()
|
||||
{
|
||||
ptyfd = -1;
|
||||
ptyname = ttyname = 0;
|
||||
}
|
||||
|
||||
PTY::~PTY()
|
||||
{
|
||||
if (ptyfd >= 0)
|
||||
close(ptyfd);
|
||||
if (ptyname) free (ptyname);
|
||||
if (ttyname) free (ttyname);
|
||||
}
|
||||
|
||||
|
||||
// Opens a pty master and returns its filedescriptor.
|
||||
|
||||
int PTY::getpt()
|
||||
{
|
||||
|
||||
#if defined(HAVE_GETPT) && defined(HAVE_PTSNAME)
|
||||
|
||||
// 1: UNIX98: preferred way
|
||||
ptyfd = ::getpt();
|
||||
ttyname = strdup(::ptsname(ptyfd));
|
||||
return ptyfd;
|
||||
|
||||
#elif defined(HAVE_OPENPTY)
|
||||
|
||||
#define MAXNAME 30
|
||||
|
||||
// 2: BSD interface
|
||||
// More preferred than the linux hacks
|
||||
char name[MAXNAME];
|
||||
int master_fd, slave_fd;
|
||||
if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1) {
|
||||
ttyname = (char*)qalloc(ttyname,MAXNAME);
|
||||
strncpy(ttyname, name, MAXNAME);
|
||||
name[5]='p';
|
||||
ptyname = (char*)qalloc(ptyname,MAXNAME);
|
||||
strncpy(ptyname, name, MAXNAME);
|
||||
close(slave_fd); // We don't need this yet // Yes, we do.
|
||||
ptyfd = master_fd;
|
||||
return ptyfd;
|
||||
}
|
||||
ptyfd = -1;
|
||||
// kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
|
||||
return -1;
|
||||
|
||||
#elif defined(HAVE__GETPTY)
|
||||
|
||||
// 3: Irix interface
|
||||
int master_fd;
|
||||
char *tmp = _getpty(&master_fd,O_RDWR,0600,0);
|
||||
if (tmp) {
|
||||
ttyname = strdup(tmp);
|
||||
ptyfd = master_fd;
|
||||
} else {
|
||||
ptyfd = -1;
|
||||
// kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
|
||||
}
|
||||
return ptyfd;
|
||||
|
||||
#else
|
||||
|
||||
// 4: Open terminal device directly
|
||||
// 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)
|
||||
|
||||
ptyfd = open("/dev/ptmx", O_RDWR);
|
||||
if (ptyfd >= 0) {
|
||||
ptyname = strdup("/dev/ptmx");
|
||||
#ifdef HAVE_PTSNAME
|
||||
ttyname = strdup(::ptsname(ptyfd));
|
||||
return ptyfd;
|
||||
#elif defined (TIOCGPTN)
|
||||
int ptyno;
|
||||
if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
|
||||
ttyname = (char*)qalloc(ttyname,MAXNAME);
|
||||
snprintf(ttyname,MAXNAME-1,"/dev/pts/%d", ptyno);
|
||||
return ptyfd;
|
||||
}
|
||||
#endif
|
||||
close(ptyfd);
|
||||
}
|
||||
|
||||
// 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)
|
||||
|
||||
for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
|
||||
{
|
||||
for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
|
||||
{
|
||||
ptyname = (char*)qalloc(ptyname,strlen("/dev/pty12"));
|
||||
ttyname = (char*)qalloc(ttyname,strlen("/dev/tty12"));
|
||||
sprintf(ptyname, "/dev/pty%c%c", *c1, *c2);
|
||||
sprintf(ttyname, "/dev/tty%c%c", *c1, *c2);
|
||||
if (access(ptyname, F_OK) < 0)
|
||||
goto linux_out;
|
||||
ptyfd = open(ptyname, O_RDWR);
|
||||
if (ptyfd >= 0)
|
||||
return ptyfd;
|
||||
}
|
||||
}
|
||||
linux_out:
|
||||
|
||||
// 4.3: Try /dev/pty%d (SCO, Unixware)
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
ptyname = (char*)qalloc(ptyname,MAXNAME);
|
||||
ttyname = (char*)qalloc(ttyname,MAXNAME);
|
||||
snprintf(ptyname, MAXNAME-1, "/dev/ptyp%d", i);
|
||||
snprintf(ttyname, MAXNAME-1, "/dev/ttyp%d", i);
|
||||
if (access(ptyname, F_OK) < 0)
|
||||
break;
|
||||
ptyfd = open(ptyname, O_RDWR);
|
||||
if (ptyfd >= 0)
|
||||
return ptyfd;
|
||||
}
|
||||
|
||||
|
||||
// Other systems ??
|
||||
ptyfd = -1;
|
||||
// kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
|
||||
return -1;
|
||||
|
||||
#endif // HAVE_GETPT && HAVE_PTSNAME
|
||||
|
||||
}
|
||||
|
||||
|
||||
int PTY::grantpt()
|
||||
{
|
||||
if (ptyfd < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_GRANTPT
|
||||
|
||||
return ::grantpt(ptyfd);
|
||||
|
||||
#elif defined(HAVE_OPENPTY)
|
||||
|
||||
// the BSD openpty() interface chowns the devices properly for us,
|
||||
// no need to do this at all
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
// konsole_grantpty only does /dev/pty??
|
||||
if (strncmp(ptyname, "/dev/pty", 8) != 0)
|
||||
return 0;
|
||||
|
||||
fprintf (stderr, "Edelib: Pty: Your system doesn't have capabilities for PTYs and we don't implement them.");
|
||||
return -1;
|
||||
|
||||
// Use konsole_grantpty:
|
||||
// if (KStandardDirs::findExe("konsole_grantpty").isEmpty())
|
||||
// {
|
||||
// kdError(900) << k_lineinfo << "konsole_grantpty not found.\n";
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// As defined in konsole_grantpty.c
|
||||
const int pty_fileno = 3;
|
||||
|
||||
pid_t pid;
|
||||
if ((pid = fork()) == -1)
|
||||
{
|
||||
// kdError(900) << k_lineinfo << "fork(): " << perror << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid)
|
||||
{
|
||||
// Parent: wait for child
|
||||
int ret;
|
||||
waitpid(pid, &ret, 0);
|
||||
if (WIFEXITED(ret) && !WEXITSTATUS(ret))
|
||||
return 0;
|
||||
// kdError(900) << k_lineinfo << "konsole_grantpty returned with error: "
|
||||
// << WEXITSTATUS(ret) << "\n";
|
||||
return -1;
|
||||
} else
|
||||
{
|
||||
// Child: exec konsole_grantpty
|
||||
if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0)
|
||||
_exit(1);
|
||||
execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0);
|
||||
// kdError(900) << k_lineinfo << "exec(): " << perror << "\n";
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
// shut up, gcc
|
||||
return 0;
|
||||
|
||||
#endif // HAVE_GRANTPT
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unlock the pty. This allows connections on the slave side.
|
||||
*/
|
||||
|
||||
int PTY::unlockpt()
|
||||
{
|
||||
if (ptyfd < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_UNLOCKPT
|
||||
|
||||
// (Linux w/ glibc 2.1, Solaris, ...)
|
||||
|
||||
return ::unlockpt(ptyfd);
|
||||
|
||||
#elif defined(TIOCSPTLCK)
|
||||
|
||||
// Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0)
|
||||
int flag = 0;
|
||||
return ioctl(ptyfd, TIOCSPTLCK, &flag);
|
||||
|
||||
#else
|
||||
|
||||
// Other systems (Linux w/o UNIX98 PTY's, ...)
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the slave side name.
|
||||
*/
|
||||
|
||||
const char *PTY::ptsname()
|
||||
{
|
||||
if (ptyfd < 0)
|
||||
return 0;
|
||||
|
||||
return ttyname;
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* edelib::PTY - A class for handling pseudoterminals (PTYs)
|
||||
* Adapted from KDE (kdelibs/kdesu/kdesu_pty.h) - original copyright message below
|
||||
*
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
/* vi: ts=8 sts=4 sw=4
|
||||
*
|
||||
* Id: kdesu_pty.h 439322 2005-07-27 18:49:23Z coolo
|
||||
*
|
||||
* This file is part of the KDE project, module kdesu.
|
||||
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
|
||||
*
|
||||
* This is free software; you can use this library under the GNU Library
|
||||
* General Public License, version 2. See the file "COPYING.LIB" for the
|
||||
* exact licensing terms.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PTY compatibility routines. This class tries to emulate a UNIX98 PTY API
|
||||
* on various platforms.
|
||||
*/
|
||||
#ifndef _edelib_PTY_h_
|
||||
#define _edelib_PTY_h_
|
||||
|
||||
//#include <qbytearray.h>
|
||||
|
||||
//#include <kdelibs_export.h>
|
||||
|
||||
namespace edelib {
|
||||
|
||||
class PTY {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a PTY object.
|
||||
*/
|
||||
PTY();
|
||||
|
||||
/**
|
||||
* Destructs the object. The PTY is closed if it is still open.
|
||||
*/
|
||||
~PTY();
|
||||
|
||||
/**
|
||||
* Allocate a pty.
|
||||
* @return A filedescriptor to the master side.
|
||||
*/
|
||||
int getpt();
|
||||
|
||||
/**
|
||||
* Grant access to the slave side.
|
||||
* @return Zero if succesfull, < 0 otherwise.
|
||||
*/
|
||||
int grantpt();
|
||||
|
||||
/**
|
||||
* Unlock the slave side.
|
||||
* @return Zero if successful, < 0 otherwise.
|
||||
*/
|
||||
int unlockpt();
|
||||
|
||||
/**
|
||||
* Get the slave name.
|
||||
* @return The slave name.
|
||||
*/
|
||||
const char *ptsname();
|
||||
|
||||
private:
|
||||
|
||||
int ptyfd;
|
||||
char *ptyname, *ttyname;
|
||||
|
||||
class PTYPrivate;
|
||||
PTYPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _edelib_PTY_h_
|
@ -1,16 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Part of Equinox Desktop Environment (EDE).
|
||||
# Copyright (c) 2000-2007 EDE Authors.
|
||||
#
|
||||
# This program is licenced under terms of the
|
||||
# GNU General Public Licence version 2 or newer.
|
||||
# See COPYING for details.
|
||||
|
||||
SubDir TOP eiconsconf ;
|
||||
|
||||
SOURCE = eiconsconf.cpp eicon.cpp ;
|
||||
|
||||
MakeProgram eiconsconf : $(SOURCE) ;
|
||||
ExtractStrings locale : $(SOURCE) ;
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Icon properties (for eiconman - the EDE desktop)
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "eicon.h"
|
||||
|
||||
using namespace fltk;
|
||||
using namespace edelib;
|
||||
|
||||
|
||||
int label_background = 46848
|
||||
;
|
||||
int label_foreground = WHITE;
|
||||
int label_fontsize = 12;
|
||||
int label_maxwidth = 75;
|
||||
int label_gridspacing = 16
|
||||
;
|
||||
bool label_trans = true;
|
||||
bool label_engage_1click = false;
|
||||
bool auto_arr = false;
|
||||
|
||||
static void sendClientMessage(XWindow w, Atom a, long x)
|
||||
{
|
||||
/* XEvent ev;
|
||||
long mask;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.window = w;
|
||||
ev.xclient.message_type = a;
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = x;
|
||||
ev.xclient.data.l[1] = CurrentTime;
|
||||
mask = 0L;
|
||||
if (w == RootWindow(fl_display, fl_screen))
|
||||
mask = SubstructureRedirectMask;
|
||||
XSendEvent(fl_display, w, False, mask, &ev);*/
|
||||
}
|
||||
|
||||
void sendUpdateInfo()
|
||||
{
|
||||
// no worky
|
||||
/* unsigned int i, nrootwins;
|
||||
Window dw1, dw2, *rootwins = 0;
|
||||
int screen_count = ScreenCount(fl_display);
|
||||
extern Atom FLTKChangeSettings;
|
||||
for (int s = 0; s < screen_count; s++) {
|
||||
Window root = RootWindow(fl_display, s);
|
||||
XQueryTree(fl_display, root, &dw1, &dw2, &rootwins, &nrootwins);
|
||||
for (i = 0; i < nrootwins; i++) {
|
||||
if (rootwins[i]!=RootWindow(fl_display, fl_screen)) {
|
||||
sendClientMessage(rootwins[i], FLTKChangeSettings, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
XFlush(fl_display);*/
|
||||
}
|
||||
|
||||
void
|
||||
readIconsConfiguration()
|
||||
{
|
||||
Config globalConfig(Config::find_file("ede.conf", 0), true, false);
|
||||
globalConfig.set_section("IconManager");
|
||||
|
||||
globalConfig.read("Label Background", label_background, 46848);
|
||||
globalConfig.read("Label Transparent", label_trans, false);
|
||||
globalConfig.read("Label Foreground", label_foreground, WHITE);
|
||||
globalConfig.read("Label Fontsize", label_fontsize, 12);
|
||||
globalConfig.read("Label Maxwidth", label_maxwidth, 75);
|
||||
globalConfig.read("Gridspacing", label_gridspacing, 16);
|
||||
globalConfig.read("OneClickExec", label_engage_1click, false);
|
||||
globalConfig.read("AutoArrange", auto_arr, false);
|
||||
}
|
||||
|
||||
void writeIconsConfiguration()
|
||||
{
|
||||
Config globalConfig(Config::find_file("ede.conf", true));
|
||||
globalConfig.set_section("IconManager");
|
||||
|
||||
globalConfig.write("Label Background", label_background);
|
||||
globalConfig.write("Label Transparent", label_trans);
|
||||
globalConfig.write("Label Foreground", label_foreground);
|
||||
globalConfig.write("Label Fontsize", label_fontsize);
|
||||
globalConfig.write("Label Maxwidth", label_maxwidth);
|
||||
globalConfig.write("Gridspacing", label_gridspacing);
|
||||
globalConfig.write("OneClickExec", label_engage_1click);
|
||||
globalConfig.write("AutoArrange", auto_arr);
|
||||
}
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Icon properties (for eiconman - the EDE desktop)
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EICON_H
|
||||
#define EICON_H
|
||||
|
||||
#include <stdlib.h>
|
||||
//#include <efltk/Fl.h>
|
||||
#include <fltk/ask.h> //#include <efltk/fl_ask.h>
|
||||
//#include <efltk/Fl_Color_Chooser.h>
|
||||
#include <fltk/x.h> //#include <efltk/x.h>
|
||||
#include "../edelib2/Config.h"
|
||||
#include "../edelib2/NLS.h"
|
||||
|
||||
extern int label_background;
|
||||
extern int label_foreground;
|
||||
extern int label_fontsize;
|
||||
extern int label_maxwidth;
|
||||
extern int label_gridspacing;
|
||||
extern bool label_trans;
|
||||
extern bool label_engage_1click;
|
||||
extern bool auto_arr;
|
||||
|
||||
void
|
||||
readIconsConfiguration()
|
||||
;
|
||||
void
|
||||
writeIconsConfiguration()
|
||||
;
|
||||
void sendUpdateInfo();
|
||||
|
||||
#endif
|
||||
|
@ -1,191 +0,0 @@
|
||||
// generated by Fast Light User Interface Designer (fluid) version 2.0100
|
||||
|
||||
#include "eiconsconf.h"
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Icon properties (for eiconman - the EDE desktop)
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
#include <fltk/ColorChooser.h>
|
||||
#include "../edelib2/NLS.h"
|
||||
#include "../edeconf.h"
|
||||
#include "eicon.h"
|
||||
|
||||
fltk::Window *iconsConfWindow=(fltk::Window *)0;
|
||||
|
||||
static void cb_OK(fltk::Button*, void*) {
|
||||
writeIconsConfiguration();
|
||||
sendUpdateInfo();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void cb_Cancel(fltk::Button*, void*) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void cb_Apply(fltk::Button*, void*) {
|
||||
writeIconsConfiguration();
|
||||
sendUpdateInfo();
|
||||
}
|
||||
|
||||
fltk::Button *colorButton=(fltk::Button *)0;
|
||||
|
||||
static void cb_colorButton(fltk::Button*, void*) {
|
||||
changeBoxColor(colorButton);
|
||||
label_background = (int) colorButton->color();
|
||||
}
|
||||
|
||||
fltk::Button *colorButton1=(fltk::Button *)0;
|
||||
|
||||
static void cb_colorButton1(fltk::Button*, void*) {
|
||||
changeBoxColor(colorButton1);
|
||||
label_foreground = (int) colorButton1->color();
|
||||
}
|
||||
|
||||
fltk::ValueSlider *maxWidthSlider=(fltk::ValueSlider *)0;
|
||||
|
||||
static void cb_maxWidthSlider(fltk::ValueSlider*, void*) {
|
||||
label_maxwidth = (int) maxWidthSlider->value();
|
||||
}
|
||||
|
||||
fltk::ValueSlider *fontsizeSlider=(fltk::ValueSlider *)0;
|
||||
|
||||
static void cb_fontsizeSlider(fltk::ValueSlider*, void*) {
|
||||
label_fontsize = (int) fontsizeSlider->value();
|
||||
}
|
||||
|
||||
fltk::ValueSlider *gridspaceSlider=(fltk::ValueSlider *)0;
|
||||
|
||||
static void cb_gridspaceSlider(fltk::ValueSlider*, void*) {
|
||||
label_gridspacing = (int) gridspaceSlider->value();
|
||||
}
|
||||
|
||||
fltk::CheckButton *autoArrButton=(fltk::CheckButton *)0;
|
||||
|
||||
static void cb_autoArrButton(fltk::CheckButton* o, void*) {
|
||||
auto_arr = (o->value()>0);
|
||||
}
|
||||
|
||||
fltk::CheckButton *engageButton=(fltk::CheckButton *)0;
|
||||
|
||||
static void cb_engageButton(fltk::CheckButton*, void*) {
|
||||
label_engage_1click = (int) engageButton->value();
|
||||
}
|
||||
|
||||
fltk::CheckButton *bg_color_check=(fltk::CheckButton *)0;
|
||||
|
||||
static void cb_bg_color_check(fltk::CheckButton* o, void*) {
|
||||
if(o->value()) colorButton->activate();
|
||||
else colorButton->deactivate();
|
||||
label_trans = (o->value()==0);
|
||||
}
|
||||
|
||||
#include <fltk/run.h>
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
fltk::Window* w;
|
||||
//fl_init_locale_support("eiconsconf", PREFIX"/share/locale");
|
||||
readIconsConfiguration();
|
||||
{fltk::Window* o = iconsConfWindow = new fltk::Window(265, 310, "Icons settings");
|
||||
w = o;
|
||||
o->set_vertical();
|
||||
o->begin();
|
||||
{fltk::Button* o = new fltk::Button(25, 277, 75, 25, "&OK");
|
||||
o->callback((fltk::Callback*)cb_OK);
|
||||
}
|
||||
{fltk::Button* o = new fltk::Button(185, 277, 75, 25, "&Cancel");
|
||||
o->callback((fltk::Callback*)cb_Cancel);
|
||||
}
|
||||
{fltk::Button* o = new fltk::Button(105, 277, 75, 25, "&Apply");
|
||||
o->callback((fltk::Callback*)cb_Apply);
|
||||
}
|
||||
{fltk::TabGroup* o = new fltk::TabGroup(1, 5, 259, 262);
|
||||
o->set_vertical();
|
||||
o->color((fltk::Color)0xfffffffe);
|
||||
o->begin();
|
||||
{fltk::Group* o = new fltk::Group(0, 20, 255, 239, "Look&&feel");
|
||||
o->begin();
|
||||
{fltk::Button* o = colorButton = new fltk::Button(164, 20, 60, 18, "Background color: ");
|
||||
o->callback((fltk::Callback*)cb_colorButton);
|
||||
o->align(fltk::ALIGN_LEFT);
|
||||
o->color((fltk::Color)label_background);
|
||||
if(label_trans) o->deactivate();
|
||||
}
|
||||
{fltk::Button* o = colorButton1 = new fltk::Button(164, 45, 60, 18, "Label color: ");
|
||||
o->callback((fltk::Callback*)cb_colorButton1);
|
||||
o->align(fltk::ALIGN_LEFT);
|
||||
o->color((fltk::Color) label_foreground);
|
||||
}
|
||||
{fltk::ValueSlider* o = maxWidthSlider = new fltk::ValueSlider(114, 78, 125, 20, "Maximum width: ");
|
||||
o->minimum(48);
|
||||
o->maximum(200);
|
||||
o->step(1);
|
||||
o->value(50);
|
||||
o->slider_size(10);
|
||||
o->callback((fltk::Callback*)cb_maxWidthSlider);
|
||||
o->align(fltk::ALIGN_LEFT);
|
||||
o->value(label_maxwidth);
|
||||
}
|
||||
{fltk::ValueSlider* o = fontsizeSlider = new fltk::ValueSlider(114, 108, 125, 20, "Font height: ");
|
||||
o->type(fltk::ValueSlider::TICK_ABOVE);
|
||||
o->minimum(8);
|
||||
o->maximum(48);
|
||||
o->step(1);
|
||||
o->value(10);
|
||||
o->slider_size(10);
|
||||
o->callback((fltk::Callback*)cb_fontsizeSlider);
|
||||
o->align(fltk::ALIGN_LEFT);
|
||||
o->value(label_fontsize);
|
||||
}
|
||||
{fltk::ValueSlider* o = gridspaceSlider = new fltk::ValueSlider(114, 138, 125, 20, "Grid spacing: ");
|
||||
o->type(fltk::ValueSlider::TICK_ABOVE);
|
||||
o->minimum(1);
|
||||
o->maximum(50);
|
||||
o->step(1);
|
||||
o->value(10);
|
||||
o->slider_size(10);
|
||||
o->callback((fltk::Callback*)cb_gridspaceSlider);
|
||||
o->align(fltk::ALIGN_LEFT);
|
||||
o->value(label_gridspacing);
|
||||
}
|
||||
{fltk::CheckButton* o = autoArrButton = new fltk::CheckButton(24, 198, 222, 20, "Auto arrange icons");
|
||||
o->callback((fltk::Callback*)cb_autoArrButton);
|
||||
o->value(auto_arr);
|
||||
}
|
||||
{fltk::CheckButton* o = engageButton = new fltk::CheckButton(24, 173, 222, 20, "Engage with just one click");
|
||||
o->callback((fltk::Callback*)cb_engageButton);
|
||||
o->value(label_engage_1click);
|
||||
}
|
||||
{fltk::CheckButton* o = bg_color_check = new fltk::CheckButton(226, 20, 20, 18);
|
||||
o->callback((fltk::Callback*)cb_bg_color_check);
|
||||
o->tooltip("Clear this, to get transparent background.");
|
||||
if(!label_trans) o->set();
|
||||
}
|
||||
o->end();
|
||||
}
|
||||
o->end();
|
||||
}
|
||||
o->end();
|
||||
o->resizable(o);
|
||||
}
|
||||
w->show(argc, argv);
|
||||
return fltk::run();
|
||||
}
|
||||
|
||||
void changeBoxColor(fltk::Button *box) {
|
||||
//Fl_Button *colorBox = box;
|
||||
fltk::Color oldColor = box->color();
|
||||
fltk::Color defColor = oldColor;
|
||||
fltk::color_chooser(_("Choose color"), defColor);
|
||||
if ( defColor != oldColor ) {
|
||||
box->color(defColor);
|
||||
box->redraw();
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
# data file for the FLTK User Interface Designer (FLUID)
|
||||
version 2.0100
|
||||
images_dir ./icons
|
||||
header_name {.h}
|
||||
code_name {.cpp}
|
||||
gridx 5
|
||||
gridy 5
|
||||
snap 3
|
||||
decl {/*
|
||||
* $Id$
|
||||
*
|
||||
* Icon properties (for eiconman - the EDE desktop)
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2000-2006 EDE Authors.
|
||||
*
|
||||
* This program is licenced under terms of the
|
||||
* GNU General Public Licence version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/} {}
|
||||
|
||||
decl {\#include <fltk/ColorChooser.h>} {}
|
||||
|
||||
decl {\#include "../edelib2/NLS.h"} {}
|
||||
|
||||
decl {\#include "../edeconf.h"} {}
|
||||
|
||||
decl {\#include "eicon.h"} {}
|
||||
|
||||
Function {} {open
|
||||
} {
|
||||
code {//fl_init_locale_support("eiconsconf", PREFIX"/share/locale");
|
||||
readIconsConfiguration();} {}
|
||||
{fltk::Window} iconsConfWindow {
|
||||
label {Icons settings} open
|
||||
xywh {386 204 265 310} resizable visible
|
||||
} {
|
||||
{fltk::Button} {} {
|
||||
label {&OK}
|
||||
callback {writeIconsConfiguration();
|
||||
sendUpdateInfo();
|
||||
exit(0);}
|
||||
xywh {25 277 75 25}
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
label {&Cancel}
|
||||
callback {exit(0);}
|
||||
xywh {185 277 75 25}
|
||||
}
|
||||
{fltk::Button} {} {
|
||||
label {&Apply}
|
||||
callback {writeIconsConfiguration();
|
||||
sendUpdateInfo();}
|
||||
xywh {105 277 75 25}
|
||||
}
|
||||
{fltk::TabGroup} {} {open
|
||||
xywh {1 5 259 262} color 0xfffffffe
|
||||
} {
|
||||
{fltk::Group} {} {
|
||||
label {Look&&feel} open
|
||||
xywh {0 20 255 239}
|
||||
} {
|
||||
{fltk::Button} colorButton {
|
||||
label {Background color: }
|
||||
callback {changeBoxColor(colorButton);
|
||||
label_background = (int) colorButton->color();}
|
||||
xywh {164 20 60 18} align 4
|
||||
extra_code {o->color((fltk::Color)label_background);
|
||||
if(label_trans) o->deactivate();}
|
||||
}
|
||||
{fltk::Button} colorButton1 {
|
||||
label {Label color: }
|
||||
callback {changeBoxColor(colorButton1);
|
||||
label_foreground = (int) colorButton1->color();}
|
||||
xywh {164 45 60 18} align 4
|
||||
extra_code {o->color((fltk::Color) label_foreground);}
|
||||
}
|
||||
{fltk::ValueSlider} maxWidthSlider {
|
||||
label {Maximum width: }
|
||||
callback {label_maxwidth = (int) maxWidthSlider->value();}
|
||||
xywh {114 78 125 20} align 4 minimum 48 maximum 200 step 1 value 50 slider_size 10
|
||||
extra_code {o->value(label_maxwidth);}
|
||||
}
|
||||
{fltk::ValueSlider} fontsizeSlider {
|
||||
label {Font height: }
|
||||
callback {label_fontsize = (int) fontsizeSlider->value();}
|
||||
xywh {114 108 125 20} type TICK_ABOVE align 4 minimum 8 maximum 48 step 1 value 10 slider_size 10
|
||||
extra_code {o->value(label_fontsize);}
|
||||
}
|
||||
{fltk::ValueSlider} gridspaceSlider {
|
||||
label {Grid spacing: }
|
||||
callback {label_gridspacing = (int) gridspaceSlider->value();}
|
||||
xywh {114 138 125 20} type TICK_ABOVE align 4 minimum 1 maximum 50 step 1 value 10 slider_size 10
|
||||
extra_code {o->value(label_gridspacing);}
|
||||
}
|
||||
{fltk::CheckButton} autoArrButton {
|
||||
label {Auto arrange icons}
|
||||
callback {auto_arr = (o->value()>0);}
|
||||
xywh {24 198 222 20}
|
||||
extra_code {o->value(auto_arr);}
|
||||
}
|
||||
{fltk::CheckButton} engageButton {
|
||||
label {Engage with just one click}
|
||||
callback {label_engage_1click = (int) engageButton->value();}
|
||||
xywh {24 173 222 20}
|
||||
extra_code {o->value(label_engage_1click);}
|
||||
}
|
||||
{fltk::CheckButton} bg_color_check {
|
||||
callback {if(o->value()) colorButton->activate();
|
||||
else colorButton->deactivate();
|
||||
label_trans = (o->value()==0);}
|
||||
tooltip {Clear this, to get transparent background.}
|
||||
xywh {226 20 20 18}
|
||||
extra_code {if(!label_trans) o->set();}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function {changeBoxColor(fltk::Button *box)} {open return_type void
|
||||
} {
|
||||
code {//Fl_Button *colorBox = box;
|
||||
fltk::Color oldColor = box->color();
|
||||
fltk::Color defColor = oldColor;
|
||||
fltk::color_chooser(_("Choose color"), defColor);
|
||||
if ( defColor != oldColor ) {
|
||||
box->color(defColor);
|
||||
box->redraw();
|
||||
}} {selected
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// generated by Fast Light User Interface Designer (fluid) version 2.0100
|
||||
|
||||
#ifndef eiconsconf_h
|
||||
#define eiconsconf_h
|
||||
#include <fltk/Window.h>
|
||||
extern fltk::Window* iconsConfWindow;
|
||||
#include <fltk/Button.h>
|
||||
#include <fltk/TabGroup.h>
|
||||
#include <fltk/Group.h>
|
||||
extern fltk::Button* colorButton;
|
||||
extern fltk::Button* colorButton1;
|
||||
#include <fltk/ValueSlider.h>
|
||||
extern fltk::ValueSlider* maxWidthSlider;
|
||||
extern fltk::ValueSlider* fontsizeSlider;
|
||||
extern fltk::ValueSlider* gridspaceSlider;
|
||||
#include <fltk/CheckButton.h>
|
||||
extern fltk::CheckButton* autoArrButton;
|
||||
extern fltk::CheckButton* engageButton;
|
||||
extern fltk::CheckButton* bg_color_check;
|
||||
void changeBoxColor(fltk::Button *box);
|
||||
#endif
|
@ -1,67 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: 2005-02-09 11:22+0100\n"
|
||||
"Last-Translator: Nemeth Otto <otto_nemeth@freemail.hu>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr "Ikon beállítások"
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr "Mégs&em"
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr "&Alkalmaz"
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr "Megjelenés"
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr "Háttér szín:"
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr "Szöveg szín:"
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr "Maximális szélesség:"
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr "Font magasság:"
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr "Rácshoz igazítás:"
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr "Ikonok automatikus rendezése"
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr "Egy kattintással aktivál"
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr "Töröld a kijelölést a szövegháttér eltűnéséhez"
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr "Szín kiválasztása"
|
||||
|
@ -1,71 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: eiconsconf 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:25+0100\n"
|
||||
"PO-Revision-Date: 202-11-29 14:58+0700\n"
|
||||
"Last-Translator: Bambang Purnomosidi D. P. <i-am-the-boss@bpdp.org>\n"
|
||||
"Language-Team: id <i-am-the-boss@bpdp.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-2\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr "Seting ikon"
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr "&Batal"
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr "&Terapkan"
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr "Look&&feel"
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr "Warna latar belakang"
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr "Warna label"
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr "Lebar maximum: "
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr "Tinggi font: "
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr "Spasi grid: "
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr "Ikon tersusun otomatis"
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr "Bekerja hanya dengan satu klik"
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr "Bersihkan ini, untuk mendapatkan latar belakang transparan."
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr "Pilih warna"
|
@ -1,73 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:25+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr ""
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr ""
|
@ -1,72 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:25+0100\n"
|
||||
"PO-Revision-Date: 2002-11-28 HO:MI+ZONE\n"
|
||||
"Last-Translator: aabbvv <null@list.ru>\n"
|
||||
"Language-Team: RUSSIAN <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr "îÁÓÔÒÏÊËÉ ÐÉËÔÏÇÒÁÍÍ"
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr "ïÔÍÅÎÁ"
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr "ðÒÉÍÅÎÉÔØ"
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr "÷ÎÅÛÎÉÊ ×ÉÄ"
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr "ã×ÅÔ ÆÏÎÁ: "
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr "ã×ÅÔ ÛÒÉÆÔÁ: "
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr "íÁËÓÉÍÁÌØÎÁÑ ÄÌÉÎÁ: "
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr "÷ÙÓÏÔÁ ÛÒÉÆÔÁ: "
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr "ûÁÇ ÓÅÔËÉ: "
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr "õÐÏÒÑÄÏÞÉÔØ Á×ÔÏÍÁÔÉÞÅÓËÉ"
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr "úÁÐÕÓË ÏÄÎÉÍ ÝÅÌÞËÏÍ"
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr "þÔÏÂÙ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÒÏÚÒÁÞÎÙÊ ÆÏÎ ÓÎÉÍÉÔÅ ÆÌÁÖÏË"
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr "÷ÙÂÏÒ Ã×ÅÔÁ"
|
@ -1,71 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: eiconsconf 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:25+0100\n"
|
||||
"PO-Revision-Date: 2002-04-21 14:50+0200\n"
|
||||
"Last-Translator: Martin Pekar <cortex@nextra.sk>\n"
|
||||
"Language-Team: Slovak <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr "Nastavenie ikon"
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr "&OK"
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr "&Zrušiť"
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr "&Použiť"
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr "Look&&feel"
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr "Farba pozadia:"
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr "Farba menovky:"
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr "Maximálna šírka:"
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr "Veľkosť fontu:"
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr "Odstup mriežky:"
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr "Automaticky usporiadavať ikony"
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr "Potvrdiť iba jedným kliknutím"
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr "Ak je tlačidlo odškrtnuté, budú sa zobrazovať transparentné ikony."
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr "Voľba farby"
|
@ -1,71 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: eiconsconf 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-02-04 12:25+0100\n"
|
||||
"PO-Revision-Date: 2002-11-30 01:46+0100\n"
|
||||
"Last-Translator: Dejan Lekic <dejan@nu6.org>\n"
|
||||
"Language-Team: LINUKS.org T.T. <i18n@linuks.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: eiconsconf.cpp:85
|
||||
msgid "Icons settings"
|
||||
msgstr "Подешавања икона"
|
||||
|
||||
#: eiconsconf.cpp:87
|
||||
msgid "&OK"
|
||||
msgstr "&У реду"
|
||||
|
||||
#: eiconsconf.cpp:90
|
||||
msgid "&Cancel"
|
||||
msgstr "&Одустани"
|
||||
|
||||
#: eiconsconf.cpp:93
|
||||
msgid "&Apply"
|
||||
msgstr "&Примени"
|
||||
|
||||
#: eiconsconf.cpp:97
|
||||
msgid "Look&&feel"
|
||||
msgstr "Изглед и особине"
|
||||
|
||||
#: eiconsconf.cpp:99
|
||||
msgid "Background color: "
|
||||
msgstr "Боја позадине:"
|
||||
|
||||
#: eiconsconf.cpp:106
|
||||
msgid "Label color: "
|
||||
msgstr "Боја наслова:"
|
||||
|
||||
#: eiconsconf.cpp:112
|
||||
msgid "Maximum width: "
|
||||
msgstr "Максимална ширина:"
|
||||
|
||||
#: eiconsconf.cpp:123
|
||||
msgid "Font height: "
|
||||
msgstr "Висина фонта:"
|
||||
|
||||
#: eiconsconf.cpp:134
|
||||
msgid "Grid spacing: "
|
||||
msgstr "Размак међу линијама:"
|
||||
|
||||
#: eiconsconf.cpp:145
|
||||
msgid "Auto arrange icons"
|
||||
msgstr "Аутоматско ређање икона"
|
||||
|
||||
#: eiconsconf.cpp:151
|
||||
msgid "Engage with just one click"
|
||||
msgstr "Стартуј једним кликом:"
|
||||
|
||||
#: eiconsconf.cpp:159
|
||||
msgid "Clear this, to get transparent background."
|
||||
msgstr "Искључити ово, да би се добила провидна позадина."
|
||||
|
||||
#: eiconsconf.cpp:176
|
||||
msgid "Choose color"
|
||||
msgstr "Изаберите боју"
|
Loading…
x
Reference in New Issue
Block a user