all repos — openbox @ 35fcb62ddd4861f857d93941407e3d87d444b2cc

openbox fork - make it a bit more like ryudo

added style class, moved util and config to otk
Marius Nita marius@cs.pdx.edu
commit

35fcb62ddd4861f857d93941407e3d87d444b2cc

parent

0cf6e32e1cd1659adc6f0a95649302758256207a

M otk/Makefile.amotk/Makefile.am

@@ -6,7 +6,7 @@ noinst_LIBRARIES=libotk.a

libotk_a_SOURCES= color.cc display.cc font.cc gccache.cc image.cc property.cc \ imagecontrol.cc rect.cc screeninfo.cc texture.cc timer.cc \ - timerqueuemanager.cc + timerqueuemanager.cc style.cc configuration.cc util.cc MAINTAINERCLEANFILES= Makefile.in

@@ -18,3 +18,6 @@ color.o: color.cc color.hh display.hh screeninfo.hh rect.hh

gccache.o: gccache.cc gccache.hh display.hh color.hh assassin.hh \ screeninfo.hh rect.hh rect.o: rect.cc rect.hh +configuration.o: configuration.cc configuration.hh +style.o: style.cc style.hh +util.o: util.cc util.hh
A otk/configuration.cc

@@ -0,0 +1,236 @@

+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif // HAVE_CONFIG_H + +extern "C" { +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif // HAVE_STDLIB_H +} + +#include "configuration.hh" +#include "util.hh" + +#include <algorithm> + +namespace otk { + +bool Configuration::_initialized = False; + +Configuration::Configuration(const std::string &file, bool autosave) { + setFile(file); + _modified = False; + _database = NULL; + _autosave = autosave; + if (! _initialized) { + XrmInitialize(); + _initialized = True; + } +} + +Configuration::Configuration(bool autosave) { + _modified = False; + _database = NULL; + _autosave = autosave; + if (! _initialized) { + XrmInitialize(); + _initialized = True; + } +} + +Configuration::~Configuration() { + if (_database != NULL) + XrmDestroyDatabase(_database); +} + +void Configuration::setFile(const std::string &file) { + _file = file; +} + +void Configuration::setAutoSave(bool autosave) { + _autosave = autosave; +} + +void Configuration::save() { + assert(_database != NULL); + XrmPutFileDatabase(_database, _file.c_str()); + _modified = False; +} + +bool Configuration::load() { + if (_database != NULL) + XrmDestroyDatabase(_database); + _modified = False; + if (NULL == (_database = XrmGetFileDatabase(_file.c_str()))) + return False; + return True; +} + +bool Configuration::merge(const std::string &file, bool overwrite) { + if (XrmCombineFileDatabase(file.c_str(), &_database, overwrite) == 0) + return False; + _modified = True; + if (_autosave) + save(); + return True; +} + +void Configuration::create() { + if (_database != NULL) + XrmDestroyDatabase(_database); + _modified = False; + assert(NULL != (_database = XrmGetStringDatabase(""))); +} + +void Configuration::setValue(const std::string &rname, bool value) { + assert(_database != NULL); + + const char *val = (value ? "True" : "False"); + std::string rc_string = rname + ": " + val; + XrmPutLineResource(&_database, rc_string.c_str()); + + _modified = True; + if (_autosave) + save(); +} + +void Configuration::setValue(const std::string &rname, unsigned long value) { + assert(_database != NULL); + + std::string rc_string = rname + ": " + itostring(value); + XrmPutLineResource(&_database, rc_string.c_str()); + + _modified = True; + if (_autosave) + save(); +} + +void Configuration::setValue(const std::string &rname, long value) { + assert(_database != NULL); + + std::string rc_string = rname + ": " + itostring(value); + XrmPutLineResource(&_database, rc_string.c_str()); + + _modified = True; + if (_autosave) + save(); +} + +void Configuration::setValue(const std::string &rname, const char *value) { + assert(_database != NULL); + assert(value != NULL); + + std::string rc_string = rname + ": " + value; + XrmPutLineResource(&_database, rc_string.c_str()); + + _modified = True; + if (_autosave) + save(); +} + +void Configuration::setValue(const std::string &rname, + const std::string &value) { + assert(_database != NULL); + + std::string rc_string = rname + ": " + value; + XrmPutLineResource(&_database, rc_string.c_str()); + + _modified = True; + if (_autosave) + save(); +} + +bool Configuration::getValue(const std::string &rname, bool &value) const { + assert(_database != NULL); + + std::string rclass = createClassName(rname); + + char *rettype; + XrmValue retvalue; + if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), + &rettype, &retvalue) || retvalue.addr == NULL) + return False; + std::string val = retvalue.addr; + if (val == "True" || val == "True") + value = True; + else + value = False; + return True; +} + +bool Configuration::getValue(const std::string &rname, long &value) const { + assert(_database != NULL); + + std::string rclass = createClassName(rname); + + char *rettype; + XrmValue retvalue; + if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), + &rettype, &retvalue) || retvalue.addr == NULL) + return False; + char *end; + value = strtol(retvalue.addr, &end, 10); + if (end == retvalue.addr) + return False; + return True; +} + +bool Configuration::getValue(const std::string &rname, unsigned long &value) const { + assert(_database != NULL); + + std::string rclass = createClassName(rname); + + char *rettype; + XrmValue retvalue; + if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), + &rettype, &retvalue) || retvalue.addr == NULL) + return False; + char *end; + value = strtoul(retvalue.addr, &end, 10); + if (end == retvalue.addr) + return False; + return True; +} + +bool Configuration::getValue(const std::string &rname, + std::string &value) const { + assert(_database != NULL); + + std::string rclass = createClassName(rname); + + char *rettype; + XrmValue retvalue; + if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), + &rettype, &retvalue) || retvalue.addr == NULL) + return False; + value = retvalue.addr; + return True; +} + + +std::string Configuration::createClassName(const std::string &rname) const { + std::string rclass(rname); + + std::string::iterator it = rclass.begin(), end = rclass.end(); + while (True) { + *it = toUpper(*it); + ++it; + if (it == end) break; + it = std::find(it, rclass.end(), '.'); + if (it == end) break; + ++it; + if (it == end) break; + } + return rclass; +} + + +char Configuration::toUpper(char c) const { + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; +} + +}
A otk/configuration.hh

@@ -0,0 +1,89 @@

+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +#ifndef __configuration_hh +#define __configuration_hh + +/*! @file configuration.hh + @brief Loads, saves, and provides configuration options for the window + manager +*/ + +extern "C" { +#include <X11/Xlib.h> +#include <X11/Xresource.h> +} + +#include <string> + +namespace otk { + +/* + * The Configuration class is a generic wrapper for configuration settings. + * + * This class is used for the global rc/config file, and for styles. + * + * This implementation of the Configuration class wraps an X resource database + * file. + */ +class Configuration { +public: + explicit Configuration(const std::string &file, bool autosave = True); + Configuration(bool autosave = True); + virtual ~Configuration(); + + inline const std::string &file() const { + return static_cast<const std::string &>(_file); + } + void setFile(const std::string &file); + + // defaults to true! + inline bool autoSave() const { + return _autosave; + } + void setAutoSave(bool); + + inline bool isModified() const { + return _modified; + } + + void save(); + bool load(); + bool merge(const std::string &file, bool overwrite = False); + void create(); + + void setValue(const std::string &rname, bool value); + inline void setValue(const std::string &rname, int value) { + setValue(rname, (long) value); + } + inline void setValue(const std::string &rname, unsigned int value) { + setValue(rname, (unsigned long) value); + } + void setValue(const std::string &rname, long value); + void setValue(const std::string &rname, unsigned long value); + void setValue(const std::string &rname, const std::string &value); + void setValue(const std::string &rname, const char *value); + + bool getValue(const std::string &rname, bool &value) const; + inline bool getValue(const std::string &rname, int &value) const { + return getValue(rname, (long) value); + } + inline bool getValue(const std::string &rname, unsigned int &value) const { + return getValue(rname, (unsigned long) value); + } + bool getValue(const std::string &rname, long &value) const; + bool getValue(const std::string &rname, unsigned long &value) const; + bool getValue(const std::string &rname, std::string &value) const; + +private: + std::string createClassName(const std::string &rname) const; + char toUpper(char) const; + + static bool _initialized; + std::string _file; + bool _modified; + bool _autosave; + XrmDatabase _database; +}; + +} + +#endif // __configuration_hh
M otk/screeninfo.ccotk/screeninfo.cc

@@ -11,7 +11,7 @@ }

#include "screeninfo.hh" #include "display.hh" -#include "src/util.hh" +#include "util.hh" using std::string;

@@ -79,7 +79,7 @@ if (pos != string::npos)

default_string.resize(pos); display_string = string("DISPLAY=") + default_string + '.' + - ob::itostring(static_cast<unsigned long>(screen_number)); + otk::itostring(static_cast<unsigned long>(screen_number)); #ifdef XINERAMA xinerama_active = False;
A otk/style.cc

@@ -0,0 +1,309 @@

+#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif // HAVE_CONFIG_H + +#include <assert.h> +#include "display.hh" + +#include "util.hh" +#include "style.hh" + +namespace otk { + +Style::Style() +{ + fprintf(stderr, "new font class used"); +} + +Style::Style(unsigned int screen) : screen_number(screen) +{ +} + +Style::Style(unsigned int screen, otk::BImageControl *ctrl) + : image_control(ctrl), screen_number(screen) +{ +} + +Style::~Style() { + if (font) + delete font; + + if (close_button.mask != None) + XFreePixmap(otk::OBDisplay::display, close_button.mask); + if (max_button.mask != None) + XFreePixmap(otk::OBDisplay::display, max_button.mask); + if (icon_button.mask != None) + XFreePixmap(otk::OBDisplay::display, icon_button.mask); + if (stick_button.mask != None) + XFreePixmap(otk::OBDisplay::display, stick_button.mask); + + max_button.mask = None; + close_button.mask = None; + icon_button.mask = None; + stick_button.mask = None; +} + +void Style::load(otk::Configuration &style) { + std::string s; + + // load fonts/fontsets + if (font) + delete font; + + font = readDatabaseFont("window.", style); + + // load window config + t_focus = readDatabaseTexture("window.title.focus", "white", style); + t_unfocus = readDatabaseTexture("window.title.unfocus", "black", style); + + l_focus = readDatabaseTexture("window.label.focus", "white", style); + l_unfocus = readDatabaseTexture("window.label.unfocus", "black", style); + + h_focus = readDatabaseTexture("window.handle.focus", "white", style); + h_unfocus = readDatabaseTexture("window.handle.unfocus", "black", style); + + g_focus = readDatabaseTexture("window.grip.focus", "white", style); + g_unfocus = readDatabaseTexture("window.grip.unfocus", "black", style); + + b_focus = readDatabaseTexture("window.button.focus", "white", style); + b_unfocus = readDatabaseTexture("window.button.unfocus", "black", style); + b_pressed = readDatabaseTexture("window.button.pressed", "black", style); + + //if neither of these can be found, we will use the previous resource + b_pressed_focus = readDatabaseTexture("window.button.pressed.focus", + "black", style, true); + b_pressed_unfocus = readDatabaseTexture("window.button.pressed.unfocus", + "black", style, true); + + if (close_button.mask != None) + XFreePixmap(otk::OBDisplay::display, close_button.mask); + if (max_button.mask != None) + XFreePixmap(otk::OBDisplay::display, max_button.mask); + if (icon_button.mask != None) + XFreePixmap(otk::OBDisplay::display, icon_button.mask); + if (stick_button.mask != None) + XFreePixmap(otk::OBDisplay::display, stick_button.mask); + + close_button.mask = max_button.mask = icon_button.mask + = icon_button.mask = None; + + readDatabaseMask("window.button.close.mask", close_button, style); + readDatabaseMask("window.button.max.mask", max_button, style); + readDatabaseMask("window.button.icon.mask", icon_button, style); + readDatabaseMask("window.button.stick.mask", stick_button, style); + + // we create the window.frame texture by hand because it exists only to + // make the code cleaner and is not actually used for display + otk::BColor color = readDatabaseColor("window.frame.focusColor", "white", + style); + f_focus = otk::BTexture("solid flat", screen_number, image_control); + f_focus.setColor(color); + + color = readDatabaseColor("window.frame.unfocusColor", "white", style); + f_unfocus = otk::BTexture("solid flat", screen_number, image_control); + f_unfocus.setColor(color); + + l_text_focus = readDatabaseColor("window.label.focus.textColor", + "black", style); + l_text_unfocus = readDatabaseColor("window.label.unfocus.textColor", + "white", style); + + b_pic_focus = readDatabaseColor("window.button.focus.picColor", + "black", style); + b_pic_unfocus = readDatabaseColor("window.button.unfocus.picColor", + "white", style); + + justify = LeftJustify; + + if (style.getValue("window.justify", s)) { + if (s == "right" || s == "Right") + justify = RightJustify; + else if (s == "center" || s == "Center") + justify = CenterJustify; + } + + // sanity checks + if (t_focus.texture() == otk::BTexture::Parent_Relative) + t_focus = f_focus; + if (t_unfocus.texture() == otk::BTexture::Parent_Relative) + t_unfocus = f_unfocus; + if (h_focus.texture() == otk::BTexture::Parent_Relative) + h_focus = f_focus; + if (h_unfocus.texture() == otk::BTexture::Parent_Relative) + h_unfocus = f_unfocus; + + border_color = readDatabaseColor("borderColor", "black", style); + + // load bevel, border and handle widths + + const otk::ScreenInfo *s_info = otk::OBDisplay::screenInfo(screen_number); + unsigned int width = s_info->getRect().width(); + + if (! style.getValue("handleWidth", handle_width) || + handle_width > width/2 || handle_width == 0) + handle_width = 6; + + if (! style.getValue("borderWidth", border_width)) + border_width = 1; + + if (! style.getValue("bevelWidth", bevel_width) + || bevel_width > width/2 || bevel_width == 0) + bevel_width = 3; + + if (! style.getValue("frameWidth", frame_width) + || frame_width > width/2) + frame_width = bevel_width; + + if (style.getValue("rootCommand", s)) + bexec(s, s_info->displayString()); +} + + +void Style::doJustify(const std::string &text, int &start_pos, + unsigned int max_length, + unsigned int modifier) const { + size_t text_len = text.size(); + unsigned int length; + + do { + length = font->measureString(std::string(text, 0, text_len)) + modifier; + } while (length > max_length && text_len-- > 0); + + switch (justify) { + case RightJustify: + start_pos += max_length - length; + break; + + case CenterJustify: + start_pos += (max_length - length) / 2; + break; + + case LeftJustify: + default: + break; + } +} + + +void Style::readDatabaseMask(const std::string &rname, PixmapMask &pixmapMask, + const otk::Configuration &style) { + Window root_window = otk::OBDisplay::screenInfo(screen_number)->getRootWindow(); + std::string s; + int hx, hy; //ignored + int ret = BitmapOpenFailed; //default to failure. + + if (style.getValue(rname, s)) + { + if (s[0] != '/' && s[0] != '~') + { + std::string xbmFile = std::string("~/.openbox/buttons/") + s; + ret = XReadBitmapFile(otk::OBDisplay::display, root_window, + expandTilde(xbmFile).c_str(), &pixmapMask.w, + &pixmapMask.h, &pixmapMask.mask, &hx, &hy); + } else + ret = XReadBitmapFile(otk::OBDisplay::display, root_window, + expandTilde(s).c_str(), &pixmapMask.w, + &pixmapMask.h, &pixmapMask.mask, &hx, &hy); + + if (ret == BitmapSuccess) + return; + } + + pixmapMask.mask = None; + pixmapMask.w = pixmapMask.h = 0; +} + + +otk::BTexture Style::readDatabaseTexture(const std::string &rname, + const std::string &default_color, + const otk::Configuration &style, + bool allowNoTexture) +{ + otk::BTexture texture; + std::string s; + + if (style.getValue(rname, s)) + texture = otk::BTexture(s); + else if (allowNoTexture) //no default + texture.setTexture(otk::BTexture::NoTexture); + else + texture.setTexture(otk::BTexture::Solid | otk::BTexture::Flat); + + // associate this texture with this screen + texture.setScreen(screen_number); + texture.setImageControl(image_control); + + if (texture.texture() != otk::BTexture::NoTexture) { + texture.setColor(readDatabaseColor(rname + ".color", default_color, + style)); + texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color, + style)); + texture.setBorderColor(readDatabaseColor(rname + ".borderColor", + default_color, style)); + } + + return texture; +} + + +otk::BColor Style::readDatabaseColor(const std::string &rname, + const std::string &default_color, + const otk::Configuration &style) { + otk::BColor color; + std::string s; + if (style.getValue(rname, s)) + color = otk::BColor(s, screen_number); + else + color = otk::BColor(default_color, screen_number); + return color; +} + + +otk::BFont *Style::readDatabaseFont(const std::string &rbasename, + const otk::Configuration &style) { + std::string fontname; + + std::string s; + + int i; + if (style.getValue(rbasename + "xft.font", s) && + style.getValue(rbasename + "xft.size", i)) { + std::string family = s; + bool bold = False; + bool italic = False; + bool dropShadow = False; + + if (style.getValue(rbasename + "xft.flags", s)) { + if (s.find("bold") != std::string::npos) + bold = True; + if (s.find("italic") != std::string::npos) + italic = True; + if (s.find("shadow") != std::string::npos) + dropShadow = True; + } + + unsigned char offset = 1; + if (style.getValue(rbasename + "xft.shadow.offset", s)) { + offset = atoi(s.c_str()); //doesn't detect errors + if (offset > CHAR_MAX) + offset = 1; + } + + unsigned char tint = 0x40; + if (style.getValue(rbasename + "xft.shadow.tint", s)) { + tint = atoi(s.c_str()); + } + + + otk::BFont *b = new otk::BFont(screen_number, family, i, bold, italic, + dropShadow && shadow_fonts, + offset, tint, aa_fonts); + if (b->valid()) + return b; + delete b; + } + + exit(2); // can't continue without a font +} + +}
A otk/style.hh

@@ -0,0 +1,98 @@

+#ifndef __style_hh +#define __style_hh + +#include <string> + +#include "color.hh" +#include "font.hh" +#include "texture.hh" +#include "image.hh" +#include "configuration.hh" + +// XXX: document + +namespace otk { + +class Style { +public: + + enum TextJustify { LeftJustify = 1, RightJustify, CenterJustify }; + enum BulletType { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet }; + + struct PixmapMask { + Pixmap mask; + unsigned int w, h; + }; + +// private: + + otk::BImageControl *image_control; + + otk::BColor + l_text_focus, l_text_unfocus, + b_pic_focus, b_pic_unfocus; + + otk::BColor border_color; + + otk::BFont *font; + + otk::BTexture + f_focus, f_unfocus, + t_focus, t_unfocus, + l_focus, l_unfocus, + h_focus, h_unfocus, + b_focus, b_unfocus, + b_pressed, b_pressed_focus, b_pressed_unfocus, + g_focus, g_unfocus; + + PixmapMask close_button, max_button, icon_button, stick_button; + TextJustify justify; + + unsigned int handle_width, bevel_width, frame_width, border_width; + + unsigned int screen_number; + + bool shadow_fonts, aa_fonts; + +public: + + Style(); + Style(unsigned int); + Style(unsigned int, otk::BImageControl *); + ~Style(); + + void doJustify(const std::string &text, int &start_pos, + unsigned int max_length, unsigned int modifier) const; + + void readDatabaseMask(const std::string &rname, + PixmapMask &pixmapMask, + const otk::Configuration &style); + + otk::BTexture readDatabaseTexture(const std::string &rname, + const std::string &default_color, + const otk::Configuration &style, + bool allowNoTexture = false); + + otk::BColor readDatabaseColor(const std::string &rname, + const std::string &default_color, + const otk::Configuration &style); + + otk::BFont *readDatabaseFont(const std::string &rbasename, + const otk::Configuration &style); + + void load(otk::Configuration &); + + inline unsigned int getHandleWidth(void) const { return handle_width; } + inline unsigned int getBevelWidth(void) const { return bevel_width; } + inline unsigned int getFrameWidth(void) const { return frame_width; } + inline unsigned int getBorderWidth(void) const { return border_width; } + + inline void setImageControl(otk::BImageControl *c) { image_control = c; } + inline void setScreenNumber(unsigned int scr) { screen_number = scr; } + + // XXX add inline accessors for the rest of the bummy +}; + +} + +#endif // __style_hh
A otk/util.cc

@@ -0,0 +1,114 @@

+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +extern "C" { +#include <X11/Xatom.h> + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif // HAVE_UNISTD_H + +#if defined(HAVE_PROCESS_H) && defined(__EMX__) +# include <process.h> +#endif // HAVE_PROCESS_H __EMX__ + +#include <assert.h> +} + +#include <algorithm> + +#include "util.hh" + +using std::string; + +namespace otk { + +string expandTilde(const string& s) { + if (s[0] != '~') return s; + + const char* const home = getenv("HOME"); + if (home == NULL) return s; + + return string(home + s.substr(s.find('/'))); +} + + +void bexec(const string& command, const string& displaystring) { +#ifndef __EMX__ + if (! fork()) { + setsid(); + int ret = putenv(const_cast<char *>(displaystring.c_str())); + assert(ret != -1); + ret = execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL); + exit(ret); + } +#else // __EMX__ + spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", command.c_str(), NULL); +#endif // !__EMX__ +} + + +string textPropertyToString(Display *display, XTextProperty& text_prop) { + string ret; + + if (text_prop.value && text_prop.nitems > 0) { + if (text_prop.encoding == XA_STRING) { + ret = (char *) text_prop.value; + } else { + text_prop.nitems = strlen((char *) text_prop.value); + + char **list; + int num; + if (XmbTextPropertyToTextList(display, &text_prop, + &list, &num) == Success && + num > 0 && *list) { + ret = *list; + XFreeStringList(list); + } + } + } + + return ret; +} + + +string itostring(unsigned long i) { + if (i == 0) + return string("0"); + + string tmp; + for (; i > 0; i /= 10) + tmp.insert(tmp.begin(), "0123456789"[i%10]); + return tmp; +} + + +string itostring(long i) { + std::string tmp = itostring( (unsigned long) std::abs(i)); + if (i < 0) + tmp.insert(tmp.begin(), '-'); + return tmp; +} + +} + +#ifndef HAVE_BASENAME +string basename (const string& path) { + string::size_type slash = path.rfind('/'); + if (slash == string::npos) + return path; + return path.substr(slash+1); +} +#endif // HAVE_BASENAME +
A otk/util.hh

@@ -0,0 +1,49 @@

+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +#ifndef _BLACKBOX_UTIL_HH +#define _BLACKBOX_UTIL_HH + +extern "C" { +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else // !TIME_WITH_SYS_TIME +# ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +# else // !HAVE_SYS_TIME_H +# include <time.h> +# endif // HAVE_SYS_TIME_H +#endif // TIME_WITH_SYS_TIME +} + + +#include <string> +#include <vector> + +namespace otk { + +/* XXX: this needs autoconf help */ +const unsigned int BSENTINEL = 65535; + +std::string expandTilde(const std::string& s); + +void bexec(const std::string& command, const std::string& displaystring); + +std::string textPropertyToString(Display *display, XTextProperty& text_prop); + +std::string itostring(unsigned long i); +std::string itostring(long i); +inline std::string itostring(unsigned int i) + { return itostring((unsigned long) i); } +inline std::string itostring(int i) + { return itostring((long) i); } + +} + +#ifndef HAVE_BASENAME +std::string basename(const std::string& path); +#endif + +#endif