/**
* @file Resources.cc
* @author David Reveman <david@waimea.org>
* @date 18-Jul-2001 00:31:22
*
* @brief Implementation of ResourceHandler and StrComp classes
*
* ResourceHandler class is used for reading window manager settings.
* Most settings are retrieved from X resource files. StrComp class
* is used for comparing strings to objects.
*
* Copyright (C) David Reveman. All rights reserved.
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#include <X11/Xlib.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif // STDC_HEADERS
#ifdef HAVE_CTYPE_H
# include <ctype.h>
#endif // HAVE_CTYPE_H
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#else
inline char *basename(char *name) {
int i = strlen(name);
for (; i >= 0 && name[i] != '/'; i--);
if (name[i] == '/') i++;
return &name[i];
}
#endif // HAVE_LIBGEN_H
#ifdef PIXMAP
# include <Imlib2.h>
#endif // PIXMAP
}
#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
#include "Resources.hh"
/**
* @fn ResourceHandler(void)
* @brief Constructor for ResourceHandler class
*
* Sets config file variables. Creates lists with function pointers and
* lists for actions.
*/
ResourceHandler::ResourceHandler(Waimea *wa, struct waoptions *options) {
char *__m_wastrdup_tmp;
waimea = wa;
display = waimea->display;
homedir = getenv("HOME");
style_file = __m_wastrdup((char *) DEFAULTSTYLE);
action_file = __m_wastrdup((char *) DEFAULTACTION);
menu_file = __m_wastrdup((char *) DEFAULTMENU);
rc_forced = style_forced = action_forced = menu_forced = false;
if (options->rcfile) {
rc_file = options->rcfile;
rc_forced = true;
} else {
rc_file = new char[strlen(homedir) + strlen("/.waimearc") + 1];
sprintf(rc_file, "%s/.waimearc", homedir);
}
if (options->stylefile) {
style_file = options->stylefile;
style_forced = true;
}
if (options->actionfile) {
action_file = options->actionfile;
action_forced = true;
}
if (options->menufile) {
menu_file = options->menufile;
menu_forced = true;
}
wacts.push_back(new StrComp("raise", &WaWindow::Raise));
wacts.push_back(new StrComp("lower", &WaWindow::Lower));
wacts.push_back(new StrComp("focus", &WaWindow::Focus));
wacts.push_back(new StrComp("startmove", &WaWindow::Move));
wacts.push_back(new StrComp("startresizeright", &WaWindow::ResizeRight));
wacts.push_back(new StrComp("startresizeleft", &WaWindow::ResizeLeft));
wacts.push_back(new StrComp("startopaquemove", &WaWindow::MoveOpaque));
wacts.push_back(new StrComp("startopaqueresizeright",
&WaWindow::ResizeRightOpaque));
wacts.push_back(new StrComp("startopaqueresizeleft",
&WaWindow::ResizeLeftOpaque));
wacts.push_back(new StrComp("endmoveresize", &WaWindow::EndMoveResize));
wacts.push_back(new StrComp("close", &WaWindow::Close));
wacts.push_back(new StrComp("kill", &WaWindow::Kill));
wacts.push_back(new StrComp("closekill", &WaWindow::CloseKill));
wacts.push_back(new StrComp("menumap", &WaWindow::MenuMap));
wacts.push_back(new StrComp("menuremap", &WaWindow::MenuRemap));
wacts.push_back(new StrComp("menumapfocused",
&WaWindow::MenuMapFocused));
wacts.push_back(new StrComp("menuremapfocused",
&WaWindow::MenuRemapFocused));
wacts.push_back(new StrComp("menuunmap", &WaWindow::MenuUnmap));
wacts.push_back(new StrComp("menuunmapfocused",
&WaWindow::MenuUnmapFocus));
wacts.push_back(new StrComp("shade", &WaWindow::Shade));
wacts.push_back(new StrComp("unshade", &WaWindow::UnShade));
wacts.push_back(new StrComp("toggleshade", &WaWindow::ToggleShade));
wacts.push_back(new StrComp("maximize", &WaWindow::Maximize));
wacts.push_back(new StrComp("unmaximize", &WaWindow::UnMaximize));
wacts.push_back(new StrComp("togglemaximize", &WaWindow::ToggleMaximize));
wacts.push_back(new StrComp("sticky", &WaWindow::Sticky));
wacts.push_back(new StrComp("unsticky", &WaWindow::UnSticky));
wacts.push_back(new StrComp("togglesticky", &WaWindow::ToggleSticky));
wacts.push_back(new StrComp("viewportleft", &WaWindow::MoveViewportLeft));
wacts.push_back(new StrComp("viewportright",
&WaWindow::MoveViewportRight));
wacts.push_back(new StrComp("viewportup", &WaWindow::MoveViewportUp));
wacts.push_back(new StrComp("viewportdown", &WaWindow::MoveViewportDown));
wacts.push_back(new StrComp("viewportrelativemove",
&WaWindow::ViewportRelativeMove));
wacts.push_back(new StrComp("viewportfixedmove",
&WaWindow::ViewportFixedMove));
wacts.push_back(new StrComp("startviewportmove",
&WaWindow::ViewportMove));
wacts.push_back(new StrComp("taskswitcher", &WaWindow::TaskSwitcher));
wacts.push_back(new StrComp("previoustask", &WaWindow::PreviousTask));
wacts.push_back(new StrComp("nexttask", &WaWindow::NextTask));
wacts.push_back(new StrComp("raisefocus", &WaWindow::RaiseFocus));
wacts.push_back(new StrComp("decortitleon", &WaWindow::DecorTitleOn));
wacts.push_back(new StrComp("decorhandleon", &WaWindow::DecorHandleOn));
wacts.push_back(new StrComp("decorborderon", &WaWindow::DecorBorderOn));
wacts.push_back(new StrComp("decorallon", &WaWindow::DecorAllOn));
wacts.push_back(new StrComp("decortitleoff", &WaWindow::DecorTitleOff));
wacts.push_back(new StrComp("decorhandleoff", &WaWindow::DecorHandleOff));
wacts.push_back(new StrComp("decorborderoff", &WaWindow::DecorBorderOff));
wacts.push_back(new StrComp("decoralloff", &WaWindow::DecorAllOff));
wacts.push_back(new StrComp("decortitletoggle",
&WaWindow::DecorTitleToggle));
wacts.push_back(new StrComp("decorhandletoggle",
&WaWindow::DecorHandleToggle));
wacts.push_back(new StrComp("decorbordertoggle",
&WaWindow::DecorBorderToggle));
wacts.push_back(new StrComp("alwaysontopon",
&WaWindow::AlwaysontopOn));
wacts.push_back(new StrComp("alwaysatbottomon",
&WaWindow::AlwaysatbottomOn));
wacts.push_back(new StrComp("alwaysontopoff",
&WaWindow::AlwaysontopOff));
wacts.push_back(new StrComp("alwaysatbottomoff",
&WaWindow::AlwaysatbottomOff));
wacts.push_back(new StrComp("alwaysontoptoggle",
&WaWindow::AlwaysontopToggle));
wacts.push_back(new StrComp("alwaysatbottomtoggle",
&WaWindow::AlwaysatbottomToggle));
wacts.push_back(new StrComp("acceptconfigrequeston",
&WaWindow::AcceptConfigRequestOn));
wacts.push_back(new StrComp("acceptconfigrequestoff",
&WaWindow::AcceptConfigRequestOff));
wacts.push_back(new StrComp("acceptconfigrequesttoggle",
&WaWindow::AcceptConfigRequestToggle));
wacts.push_back(new StrComp("pointerrelativewarp",
&WaWindow::PointerRelativeWarp));
wacts.push_back(new StrComp("pointerfixedwarp",
&WaWindow::PointerFixedWarp));
wacts.push_back(new StrComp("moveresize", &WaWindow::MoveResize));
wacts.push_back(new StrComp("moveresizevirtual",
&WaWindow::MoveResizeVirtual));
wacts.push_back(new StrComp("movetopointer",
&WaWindow::MoveWindowToPointer));
wacts.push_back(new StrComp("movetosmartplace",
&WaWindow::MoveWindowToSmartPlace));
wacts.push_back(new StrComp("gotodesktop", &WaWindow::GoToDesktop));
wacts.push_back(new StrComp("nextdesktop", &WaWindow::NextDesktop));
wacts.push_back(new StrComp("previousdesktop",
&WaWindow::PreviousDesktop));
wacts.push_back(new StrComp("desktopmask", &WaWindow::DesktopMask));
wacts.push_back(new StrComp("joindesktop", &WaWindow::JoinDesktop));
wacts.push_back(new StrComp("partdesktop", &WaWindow::PartDesktop));
wacts.push_back(new StrComp("partcurrentdesktop",
&WaWindow::PartCurrentDesktop));
wacts.push_back(new StrComp("joinalldesktops",
&WaWindow::JoinAllDesktops));
wacts.push_back(new StrComp("partalldesktopsexceptcurrent",
&WaWindow::PartAllDesktopsExceptCurrent));
wacts.push_back(new StrComp("partcurrentjoindesktop",
&WaWindow::PartCurrentJoinDesktop));
wacts.push_back(new StrComp("restart", &WaWindow::Restart));
wacts.push_back(new StrComp("exit", &WaWindow::Exit));
wacts.push_back(new StrComp("nop", &WaWindow::Nop));
racts.push_back(new StrComp("focus", &WaScreen::Focus));
racts.push_back(new StrComp("menumap", &WaScreen::MenuMap));
racts.push_back(new StrComp("menuremap", &WaScreen::MenuRemap));
racts.push_back(new StrComp("menumapfocused", &WaScreen::MenuMapFocused));
racts.push_back(new StrComp("menuremapfocused",
&WaScreen::MenuRemapFocused));
racts.push_back(new StrComp("menuunmap", &WaScreen::MenuUnmap));
racts.push_back(new StrComp("menuunmapfocused",
&WaScreen::MenuUnmapFocus));
racts.push_back(new StrComp("restart", &WaScreen::Restart));
racts.push_back(new StrComp("exit", &WaScreen::Exit));
racts.push_back(new StrComp("viewportleft", &WaScreen::MoveViewportLeft));
racts.push_back(new StrComp("viewportright",
&WaScreen::MoveViewportRight));
racts.push_back(new StrComp("viewportup", &WaScreen::MoveViewportUp));
racts.push_back(new StrComp("viewportdown", &WaScreen::MoveViewportDown));
racts.push_back(new StrComp("viewportrelativemove",
&WaScreen::ViewportRelativeMove));
racts.push_back(new StrComp("viewportfixedmove",
&WaScreen::ViewportFixedMove));
racts.push_back(new StrComp("startviewportmove",
&WaScreen::ViewportMove));
racts.push_back(new StrComp("endmoveresize", &WaScreen::EndMoveResize));
racts.push_back(new StrComp("taskswitcher", &WaScreen::TaskSwitcher));
racts.push_back(new StrComp("previoustask", &WaScreen::PreviousTask));
racts.push_back(new StrComp("nexttask", &WaScreen::NextTask));
racts.push_back(new StrComp("pointerrelativewarp",
&WaScreen::PointerRelativeWarp));
racts.push_back(new StrComp("pointerfixedwarp",
&WaScreen::PointerFixedWarp));
racts.push_back(new StrComp("gotodesktop", &WaScreen::GoToDesktop));
racts.push_back(new StrComp("nextdesktop", &WaScreen::NextDesktop));
racts.push_back(new StrComp("previousdesktop",
&WaScreen::PreviousDesktop));
racts.push_back(new StrComp("nop", &WaScreen::Nop));
macts.push_back(new StrComp("unlink", &WaMenuItem::UnLinkMenu));
macts.push_back(new StrComp("mapsub", &WaMenuItem::MapSubmenu));
macts.push_back(new StrComp("mapsubonly", &WaMenuItem::MapSubmenuOnly));
macts.push_back(new StrComp("remapsub", &WaMenuItem::RemapSubmenu));
macts.push_back(new StrComp("mapsubfocused",
&WaMenuItem::MapSubmenuFocused));
macts.push_back(new StrComp("mapsubfocusedonly",
&WaMenuItem::MapSubmenuFocusedOnly));
macts.push_back(new StrComp("remapsubfocused",
&WaMenuItem::RemapSubmenuFocused));
macts.push_back(new StrComp("unmap", &WaMenuItem::UnmapMenu));
macts.push_back(new StrComp("unmapfocused", &WaMenuItem::UnmapMenuFocus));
macts.push_back(new StrComp("unmapsubs", &WaMenuItem::UnmapSubmenus));
macts.push_back(new StrComp("unmaptree", &WaMenuItem::UnmapTree));
macts.push_back(new StrComp("exec", &WaMenuItem::Exec));
macts.push_back(new StrComp("func", &WaMenuItem::Func));
macts.push_back(new StrComp("raise", &WaMenuItem::Raise));
macts.push_back(new StrComp("focus", &WaMenuItem::Focus));
macts.push_back(new StrComp("lower", &WaMenuItem::Lower));
macts.push_back(new StrComp("startmove", &WaMenuItem::Move));
macts.push_back(new StrComp("startopaquemove", &WaMenuItem::MoveOpaque));
macts.push_back(new StrComp("endmoveresize", &WaMenuItem::EndMoveResize));
macts.push_back(new StrComp("viewportleft",
&WaMenuItem::MoveViewportLeft));
macts.push_back(new StrComp("viewportright",
&WaMenuItem::MoveViewportRight));
macts.push_back(new StrComp("viewportup", &WaMenuItem::MoveViewportUp));
macts.push_back(new StrComp("viewportdown",
&WaMenuItem::MoveViewportDown));
macts.push_back(new StrComp("viewportrelativemove",
&WaMenuItem::ViewportRelativeMove));
macts.push_back(new StrComp("viewportfixedmove",
&WaMenuItem::ViewportFixedMove));
macts.push_back(new StrComp("startviewportmove",
&WaMenuItem::ViewportMove));
macts.push_back(new StrComp("taskswitcher", &WaMenuItem::TaskSwitcher));
macts.push_back(new StrComp("previoustask", &WaMenuItem::PreviousTask));
macts.push_back(new StrComp("nexttask", &WaMenuItem::NextTask));
macts.push_back(new StrComp("nextitem", &WaMenuItem::NextItem));
macts.push_back(new StrComp("previousitem", &WaMenuItem::PreviousItem));
macts.push_back(new StrComp("pointerrelativewarp",
&WaMenuItem::PointerRelativeWarp));
macts.push_back(new StrComp("pointerfixedwarp",
&WaMenuItem::PointerFixedWarp));
macts.push_back(new StrComp("menumap", &WaMenuItem::MenuMap));
macts.push_back(new StrComp("menuremap", &WaMenuItem::MenuRemap));
macts.push_back(new StrComp("menumapfocused",
&WaMenuItem::MenuMapFocused));
macts.push_back(new StrComp("menuremapfocused",
&WaMenuItem::MenuRemapFocused));
macts.push_back(new StrComp("menuunmap", &WaMenuItem::MenuUnmap));
macts.push_back(new StrComp("menuunmapfocused",
&WaMenuItem::MenuUnmapFocus));
macts.push_back(new StrComp("gotodesktop", &WaMenuItem::GoToDesktop));
macts.push_back(new StrComp("nextdesktop", &WaMenuItem::NextDesktop));
macts.push_back(new StrComp("previousdesktop",
&WaMenuItem::PreviousDesktop));
macts.push_back(new StrComp("restart", &WaMenuItem::Restart));
macts.push_back(new StrComp("exit", &WaMenuItem::Exit));
macts.push_back(new StrComp("nop", &WaMenuItem::Nop));
types.push_back(new StrComp("keypress", KeyPress));
types.push_back(new StrComp("keyrelease", KeyRelease));
types.push_back(new StrComp("buttonpress", ButtonPress));
types.push_back(new StrComp("buttonrelease", ButtonRelease));
types.push_back(new StrComp("doubleclick", DoubleClick));
types.push_back(new StrComp("enternotify", EnterNotify));
types.push_back(new StrComp("leavenotify", LeaveNotify));
types.push_back(new StrComp("maprequest", MapRequest));
bdetails.push_back(new StrComp("anybutton", (unsigned long) 0));
bdetails.push_back(new StrComp("button1", Button1));
bdetails.push_back(new StrComp("button2", Button2));
bdetails.push_back(new StrComp("button3", Button3));
bdetails.push_back(new StrComp("button4", Button4));
bdetails.push_back(new StrComp("button5", Button5));
bdetails.push_back(new StrComp("button6", 6));
bdetails.push_back(new StrComp("button7", 7));
bdetails.push_back(new StrComp("button8", 8));
bdetails.push_back(new StrComp("button9", 9));
bdetails.push_back(new StrComp("button10", 10));
bdetails.push_back(new StrComp("button11", 11));
bdetails.push_back(new StrComp("button12", 12));
mods.push_back(new StrComp("shiftmask", ShiftMask));
mods.push_back(new StrComp("lockmask", LockMask));
mods.push_back(new StrComp("controlmask", ControlMask));
mods.push_back(new StrComp("mod1mask", Mod1Mask));
mods.push_back(new StrComp("mod2mask", Mod2Mask));
mods.push_back(new StrComp("mod3mask", Mod3Mask));
mods.push_back(new StrComp("mod4mask", Mod4Mask));
mods.push_back(new StrComp("mod5mask", Mod5Mask));
mods.push_back(new StrComp("button1mask", Button1Mask));
mods.push_back(new StrComp("button2mask", Button2Mask));
mods.push_back(new StrComp("button3mask", Button3Mask));
mods.push_back(new StrComp("button4mask", Button4Mask));
mods.push_back(new StrComp("button5mask", Button5Mask));
mods.push_back(new StrComp("moveresizemask", MoveResizeMask));
const XModifierKeymap* const modmap = XGetModifierMapping(display);
if (modmap && modmap->max_keypermod > 0) {
const int mask_table[] = {
ShiftMask, LockMask, ControlMask, Mod1Mask,
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
};
const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) *
modmap->max_keypermod;
for (size_t i = 0; i < size; ++i) {
if (! modmap->modifiermap[i]) continue;
KeySym ksym = XKeycodeToKeysym(display, modmap->modifiermap[i], 0);
if (ksym) {
char *kstring = XKeysymToString(ksym);
if (kstring) {
int modmask = mask_table[i / modmap->max_keypermod];
mods.push_back(new StrComp(kstring, modmask));
}
}
}
if (modmap) XFreeModifiermap(const_cast<XModifierKeymap*>(modmap));
}
}
/**
* @fn ~ResourceHandler(void)
* @brief Destructor for ResourceHandler class
*
* Deletes all action lists and all WaActions in them.
*/
ResourceHandler::~ResourceHandler(void) {
LISTDEL(wacts);
LISTDEL(racts);
LISTDEL(macts);
LISTDEL(types);
LISTDEL(bdetails);
LISTDEL(mods);
delete [] rc_file;
delete [] style_file;
delete [] action_file;
delete [] menu_file;
}
/**
* @fn LoadConfig(WaScreen *waimea)
* @brief Reads config file
*
* Reads all configuration resources for common for all screens from the
* config file.
*
* @param waimea Pointer to Waimea object
*/
void ResourceHandler::LoadConfig(Waimea *waimea) {
XrmValue value;
char *value_type;
char rc_name[30], rc_class[30];
char *__m_wastrdup_tmp;
database = (XrmDatabase) 0;
if (! (database = XrmGetFileDatabase(rc_file))) {
if (rc_forced) WARNING << "can't open rcfile `" << rc_file <<
"' for reading" << endl;
else
if (! (database = XrmGetFileDatabase(DEFAULTRCFILE)))
WARNING << "can't open system default rcfile `" <<
DEFAULTRCFILE << "' for reading" << endl;
}
waimea->screenmask = 0;
sprintf(rc_name, "screenMask");
sprintf(rc_class, "ScreenMask");
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
char *token = strtok(value.addr, ", \t");
if (token) waimea->screenmask |= (1L << atoi(token));
while ((token = strtok(NULL, ", \t")))
waimea->screenmask |= (1L << atoi(token));
} else
waimea->screenmask = (1L << 0) | (1L << 2) | (1L << 3);
char *path = getenv("PATH");
sprintf(rc_name, "scriptDir");
sprintf(rc_class, "ScriptDir");
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
char *sdir = environment_expansion(__m_wastrdup(value.addr));
waimea->pathenv = new char[strlen(path) + strlen(sdir) + 7];
sprintf(waimea->pathenv, "PATH=%s:%s", sdir, path);
delete [] sdir;
}
else {
waimea->pathenv =
new char[strlen(path) + strlen(DEFAULTSCRIPTDIR) + 7];
sprintf(waimea->pathenv, "PATH=%s:%s", DEFAULTSCRIPTDIR, path);
}
sprintf(rc_name, "doubleClickInterval");
sprintf(rc_class, "DoubleClickInterval");
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (sscanf(value.addr, "%lu", &waimea->double_click) != 1)
waimea->double_click = 300;
} else
waimea->double_click = 300;
if (waimea->double_click > 999) waimea->double_click = 999;
XrmDestroyDatabase(database);
}
/**
* @fn LoadConfig(WaScreen *wascreen)
* @brief Reads config file
*
* Reads all configuration resources for this screen from the config file.
*
* @param wascreen Screen to read resources for
*/
void ResourceHandler::LoadConfig(WaScreen *wascreen) {
XrmValue value;
char *value_type;
char rc_name[30], rc_class[30];
int sn = wascreen->screen_number;
ScreenConfig *sc = &wascreen->config;
char *__m_wastrdup_tmp;
database = (XrmDatabase) 0;
if (! (database = XrmGetFileDatabase(rc_file)))
if (! rc_forced) database = XrmGetFileDatabase(DEFAULTRCFILE);
sc->style_file = __m_wastrdup(style_file);
if (! style_forced) {
sprintf(rc_name, "screen%d.styleFile", sn);
sprintf(rc_class, "Screen%d.StyleFile", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
delete [] sc->style_file;
sc->style_file = environment_expansion(__m_wastrdup(value.addr));
}
}
sc->action_file = __m_wastrdup(action_file);
if (! action_forced) {
sprintf(rc_name, "screen%d.actionFile", sn);
sprintf(rc_class, "Screen%d.ActionFile", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
delete [] sc->action_file;
sc->action_file = environment_expansion(__m_wastrdup(value.addr));
}
}
sc->menu_file = __m_wastrdup(menu_file);
if (! menu_forced) {
sprintf(rc_name, "screen%d.menuFile", sn);
sprintf(rc_class, "Screen%d.MenuFile", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
delete [] sc->menu_file;
sc->menu_file = environment_expansion(__m_wastrdup(value.addr));
}
}
sprintf(rc_name, "screen%d.numberOfDesktops", sn);
sprintf(rc_class, "Screen%d.NumberOfDesktops", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (sscanf(value.addr, "%u", &sc->desktops) != 1) {
sc->desktops = 1;
} else {
if (sc->desktops < 1) sc->desktops = 1;
if (sc->desktops > 16) sc->desktops = 16;
}
} else
sc->desktops = 1;
sprintf(rc_name, "screen%d.desktopNames", sn);
sprintf(rc_class, "Screen%d.DesktopNames", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
wascreen->net->SetDesktopNames(wascreen, value.addr);
}
sprintf(rc_name, "screen%d.virtualSize", sn);
sprintf(rc_class, "Screen%d.VirtualSize", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (sscanf(value.addr, "%ux%u", &sc->virtual_x, &sc->virtual_y) != 2) {
sc->virtual_x = sc->virtual_y = 3;
}
} else
sc->virtual_x = sc->virtual_y = 3;
if (sc->virtual_x > 20) sc->virtual_x = 20;
if (sc->virtual_y > 20) sc->virtual_y = 20;
if (sc->virtual_x < 1) sc->virtual_x = 1;
if (sc->virtual_y < 1) sc->virtual_y = 1;
sprintf(rc_name, "screen%d.doubleBufferedText", sn);
sprintf(rc_class, "Screen%d.DoubleBufferedText", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (! strncasecmp("true", value.addr, value.size))
sc->db = true;
else
sc->db = false;
} else
sc->db = true;
#ifdef RENDER
sprintf(rc_name, "screen%d.lazyTransparency", sn);
sprintf(rc_class, "Screen%d.LazyTransparency", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (! strncasecmp("true", value.addr, value.size))
sc->lazy_trans = true;
else
sc->lazy_trans = false;
} else
sc->lazy_trans = true;
#endif // RENDER
sprintf(rc_name, "screen%d.colorsPerChannel", sn);
sprintf(rc_class, "Screen%d.ColorsPerChannel", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (sscanf(value.addr, "%d", &sc->colors_per_channel) != 1) {
sc->colors_per_channel = 4;
} else {
if (sc->colors_per_channel < 2) sc->colors_per_channel = 2;
if (sc->colors_per_channel > 6) sc->colors_per_channel = 6;
}
} else
sc->colors_per_channel = 4;
sprintf(rc_name, "screen%d.cacheMax", sn);
sprintf(rc_class, "Screen%d.CacheMax", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (sscanf(value.addr, "%lu", &sc->cache_max) != 1)
sc->cache_max = 200;
} else
sc->cache_max = 200;
sprintf(rc_name, "screen%d.imageDither", sn);
sprintf(rc_class, "screen%d.ImageDither", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (! strncasecmp("true", value.addr, value.size))
sc->image_dither = true;
else
sc->image_dither = false;
} else
sc->image_dither = true;
sprintf(rc_name, "screen%d.menuStacking", sn);
sprintf(rc_class, "Screen%d.MenuStacking", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (! strncasecmp("AlwaysAtBottom", value.addr, value.size))
sc->menu_stacking = AlwaysAtBottom;
else if (! strncasecmp("AlwaysOnTop", value.addr, value.size))
sc->menu_stacking = AlwaysOnTop;
} else
sc->menu_stacking = NormalStacking;
sprintf(rc_name, "screen%d.transientAbove", sn);
sprintf(rc_class, "Screen%d.TransientAbove", sn);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
if (! strncasecmp("true", value.addr, value.size))
sc->transient_above = true;
else
sc->transient_above = false;
} else
sc->transient_above = true;
unsigned int dummy;
char *token;
int dock_num, i;
bool d_exists = true;
DockStyle *dockstyle;
for (dock_num = 0; d_exists && dock_num < 100; ++dock_num) {
d_exists = false;
dockstyle = new DockStyle;
sprintf(rc_name, "screen%d.dock%d.geometry", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Geometry", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
dockstyle->geometry = XParseGeometry(value.addr, &dockstyle->x,
&dockstyle->y, &dummy,
&dummy);
d_exists = true;
} else
dockstyle->geometry = XParseGeometry("-0+0", &dockstyle->x,
&dockstyle->y, &dummy,
&dummy);
sprintf(rc_name, "screen%d.dock%d.order", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Order", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value)) {
d_exists = true;
token = value.addr;
while (strlen(token) > 6) {
token = strtrim(token);
if (token[0] == 'n' && token[1] == '/') {
for (i = 2; token[i] != '\0' &&
! (token[i] == '/' && token[i - 1] != '\\'); i++);
if (token[i] == '\0') break;
token[i] = '\0';
dockstyle->order.push_back(new Regex(&token[2]));
dockstyle->order_type.push_back(NameMatchType);
}
else if (token[0] == 'c' && token[1] == '/') {
for (i = 2; token[i] != '\0' &&
! (token[i] == '/' && token[i - 1] != '\\'); i++);
if (token[i] == '\0') break;
token[i] = '\0';
dockstyle->order.push_back(new Regex(&token[2]));
dockstyle->order_type.push_back(ClassMatchType);
}
else if (token[0] == 't' && token[1] == '/') {
for (i = 2; token[i] != '\0' &&
! (token[i] == '/' && token[i - 1] != '\\'); i++);
if (token[i] == '\0') break;
token[i] = '\0';
dockstyle->order.push_back(new Regex(&token[2]));
dockstyle->order_type.push_back(TitleMatchType);
}
token = token + strlen(token) + 1;
}
}
sprintf(rc_name, "screen%d.dock%d.desktopMask", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.DesktopMask", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (! strncasecmp("all", value.addr, 3))
dockstyle->desktop_mask = (1L << 16) - 1;
else {
dockstyle->desktop_mask = 0;
char *token = strtok(value.addr, " \t");
while (token) {
int desk = (unsigned int) atoi(token);
if (desk < 16) dockstyle->desktop_mask |= (1L << desk);
token = strtok(NULL, " \t");
}
}
} else
dockstyle->desktop_mask = (1L << 16) - 1;
sprintf(rc_name, "screen%d.dock%d.centered", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Centered", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (! strncasecmp("true", value.addr, value.size))
dockstyle->centered = true;
else
dockstyle->centered = false;
} else
dockstyle->centered = false;
sprintf(rc_name, "screen%d.dock%d.inworkspace", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Inworkspace", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (! strncasecmp("true", value.addr, value.size))
dockstyle->inworkspace = true;
else
dockstyle->inworkspace = false;
} else
dockstyle->inworkspace = false;
sprintf(rc_name, "screen%d.dock%d.direction", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Direction", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (! strncasecmp("Horizontal", value.addr, value.size))
dockstyle->direction = HorizontalDock;
else
dockstyle->direction = VerticalDock;
} else
dockstyle->direction = VerticalDock;
sprintf(rc_name, "screen%d.dock%d.gridSpace", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.GridSpace", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (sscanf(value.addr, "%u", &dockstyle->gridspace) != 1)
dockstyle->gridspace = 2;
} else
dockstyle->gridspace = 2;
if (dockstyle->gridspace > 50) dockstyle->gridspace = 50;
sprintf(rc_name, "screen%d.dock%d.stacking", sn, dock_num);
sprintf(rc_class, "Screen%d.Dock%d.Stacking", sn, dock_num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
d_exists = true;
if (! strncasecmp("AlwaysAtBottom", value.addr, value.size))
dockstyle->stacking = AlwaysAtBottom;
else
dockstyle->stacking = AlwaysOnTop;
} else
dockstyle->stacking = AlwaysOnTop;
if (d_exists || ! dock_num)
wascreen->wstyle.dockstyles.push_back(dockstyle);
else
delete dockstyle;
}
XrmDestroyDatabase(database);
}
/**
* @fn LoadStyle(WaScreen *wascreen)
* @brief Reads style file
*
* Reads a style resources from a style file.
*
* @param wascreen WaScreen to load style for
*/
void ResourceHandler::LoadStyle(WaScreen *wascreen) {
XrmValue value;
char *value_type;
int screen = wascreen->screen_number;
WindowStyle *wstyle = &wascreen->wstyle;
MenuStyle *mstyle = &wascreen->mstyle;
WaImageControl *ic = wascreen->ic;
char *__m_wastrdup_tmp;
database = (XrmDatabase) 0;
if (! (database = XrmGetFileDatabase(wascreen->config.style_file)))
WARNING << "can't open stylefile `" << wascreen->config.style_file
<< "' for reading" << endl;
int slen = strlen(wascreen->config.style_file) - 1;
for (; slen >= 1 && wascreen->config.style_file[slen] != '/'; slen--);
wascreen->config.style_file[slen] = '\0';
WaFont default_font;
#ifdef XFT
default_font.xft = true;
default_font.font = "arial:pixelsize=12";
#else // !XFT
default_font.xft = false;
default_font.font = "fixed";
#endif // XFT
ReadDatabaseFont("window.font", "Window.Font", &wstyle->wa_font,
&default_font);
ReadDatabaseFont("menu.frame.font", "Menu.Frame.Font",
&mstyle->wa_f_font, &wstyle->wa_font);
ReadDatabaseFont("menu.title.font", "Menu.Title.Font",
&mstyle->wa_t_font, &mstyle->wa_f_font);
ReadDatabaseFont("menu.bullet.font", "Menu.Bullet.Font",
&mstyle->wa_b_font, &mstyle->wa_f_font);
ReadDatabaseFont("menu.checkbox.true.font",
"Menu.Checkbox.True.Font",
&mstyle->wa_ct_font, &mstyle->wa_f_font);
ReadDatabaseFont("menu.checkbox.false.font",
"Menu.Checkbox.False.Font",
&mstyle->wa_cf_font, &mstyle->wa_ct_font);
ReadDatabaseTexture("window.title.focus", "Window.Title.Focus",
&wstyle->t_focus, WhitePixel(display, screen), ic);
ReadDatabaseTexture("window.title.unfocus", "Window.Title.Unfocus",
&wstyle->t_unfocus, BlackPixel(display, screen), ic);
ReadDatabaseTexture("window.label.focus", "Window.Label.Focus",
&wstyle->l_focus, WhitePixel(display, screen), ic);
ReadDatabaseTexture("window.label.unfocus", "Window.Label.Unfocus",
&wstyle->l_unfocus, BlackPixel(display, screen), ic);
ReadDatabaseTexture("window.handle.focus", "Window.Handle.Focus",
&wstyle->h_focus, WhitePixel(display, screen), ic);
ReadDatabaseTexture("window.handle.unfocus", "Window.Handle.Unfocus",
&wstyle->h_unfocus, BlackPixel(display, screen), ic);
ReadDatabaseTexture("window.grip.focus", "Window.Grip.Focus",
&wstyle->g_focus, WhitePixel(display, screen), ic);
ReadDatabaseTexture("window.grip.unfocus", "Window.Grip.Unfocus",
&wstyle->g_unfocus, BlackPixel(display, screen), ic);
ReadDatabaseColor("window.label.focus.textColor",
"Window.Label.Focus.TextColor",
&wstyle->l_text_focus, BlackPixel(display, screen), ic);
ReadDatabaseColor("window.label.focus.textShadowColor",
"Window.Label.Focus.TextShadowColor",
&wstyle->l_text_focus_s,
BlackPixel(display, screen), ic);
ReadDatabaseColor("window.label.unfocus.textColor",
"Window.Label.Unfocus.TextColor",
&wstyle->l_text_unfocus, WhitePixel(display, screen),
ic);
ReadDatabaseColor("window.label.unfocus.textShadowColor",
"Window.Label.Unfocus.TextShadowColor",
&wstyle->l_text_unfocus_s, BlackPixel(display, screen),
ic);
if (XrmGetResource(database,
"window.label.focus.textShadowXOffset",
"Window.Label.focus.TextShadowXOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &wstyle->wa_font.shodow_off_x) != 1)
wstyle->wa_font.shodow_off_x = 0;
} else
wstyle->wa_font.shodow_off_x = 0;
if (wstyle->wa_font.shodow_off_x > 10) wstyle->wa_font.shodow_off_x = 10;
if (wstyle->wa_font.shodow_off_x < -10) wstyle->wa_font.shodow_off_x = -10;
if (XrmGetResource(database,
"window.label.focus.textShadowYOffset",
"Window.Label.focus.TextShadowYOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &wstyle->wa_font.shodow_off_y) != 1)
wstyle->wa_font.shodow_off_y = 0;
} else
wstyle->wa_font.shodow_off_y = 0;
if (wstyle->wa_font.shodow_off_y > 10) wstyle->wa_font.shodow_off_y = 10;
if (wstyle->wa_font.shodow_off_y < -10) wstyle->wa_font.shodow_off_y = -10;
if (XrmGetResource(database,
"window.label.unfocus.textShadowXOffset",
"Window.Label.Unfocus.TextShadowXOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &wstyle->wa_font_u.shodow_off_x) != 1)
wstyle->wa_font_u.shodow_off_x = 0;
} else
wstyle->wa_font_u.shodow_off_x = 0;
if (wstyle->wa_font_u.shodow_off_x > 10)
wstyle->wa_font_u.shodow_off_x = 10;
if (wstyle->wa_font_u.shodow_off_x < -10)
wstyle->wa_font_u.shodow_off_x = -10;
if (XrmGetResource(database,
"window.label.unfocus.textShadowYOffset",
"Window.Label.Unfocus.TextShadowYOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &wstyle->wa_font_u.shodow_off_y) != 1)
wstyle->wa_font_u.shodow_off_y = 0;
} else
wstyle->wa_font_u.shodow_off_y = 0;
if (wstyle->wa_font_u.shodow_off_y > 10)
wstyle->wa_font_u.shodow_off_y = 10;
if (wstyle->wa_font_u.shodow_off_y < -10)
wstyle->wa_font_u.shodow_off_y = -10;
if (XrmGetResource(database, "window.justify", "Window.Justify",
&value_type, &value)) {
if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
wstyle->justify = RightJustify;
else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
wstyle->justify = CenterJustify;
else
wstyle->justify = LeftJustify;
} else
wstyle->justify = LeftJustify;
ReadDatabaseTexture("menu.frame", "Menu.Frame",
&mstyle->back_frame, WhitePixel(display, screen), ic);
ReadDatabaseTexture("menu.hilite", "Menu.Hilite",
&mstyle->hilite, WhitePixel(display, screen), ic);
ReadDatabaseTexture("menu.title", "Menu.Title",
&mstyle->title, WhitePixel(display, screen), ic);
ReadDatabaseColor("menu.frame.textColor", "Menu.Frame.TextColor",
&mstyle->f_text, BlackPixel(display, screen), ic);
ReadDatabaseColor("menu.frame.textShadowColor",
"Menu.Frame.TextShadowColor",
&mstyle->f_text_s, BlackPixel(display, screen), ic);
ReadDatabaseColor("menu.hilite.textColor", "Menu.Hilite.TextColor",
&mstyle->f_hilite_text, BlackPixel(display, screen),
ic);
ReadDatabaseColor("menu.hilite.textShadowColor",
"Menu.Hilite.TextShadowColor",
&mstyle->f_hilite_text_s, BlackPixel(display, screen),
ic);
ReadDatabaseColor("menu.title.textColor", "Menu.Title.TextColor",
&mstyle->t_text, BlackPixel(display, screen), ic);
ReadDatabaseColor("menu.title.textShadowColor",
"Menu.Title.TextShadowColor",
&mstyle->t_text_s, BlackPixel(display, screen), ic);
if (XrmGetResource(database,
"menu.frame.textShadowXOffset",
"Menu.Frame.TextShadowXOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_f_font.shodow_off_x) != 1)
mstyle->wa_f_font.shodow_off_x = 0;
} else
mstyle->wa_f_font.shodow_off_x = 0;
if (mstyle->wa_f_font.shodow_off_x > 10)
mstyle->wa_f_font.shodow_off_x = 10;
if (mstyle->wa_f_font.shodow_off_x < -10)
mstyle->wa_f_font.shodow_off_x = -10;
if (XrmGetResource(database,
"menu.frame.textShadowYOffset",
"Menu.Frame.TextShadowYOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_f_font.shodow_off_y) != 1)
mstyle->wa_f_font.shodow_off_y = 0;
} else
mstyle->wa_f_font.shodow_off_y = 0;
if (mstyle->wa_f_font.shodow_off_y > 10)
mstyle->wa_f_font.shodow_off_y = 10;
if (mstyle->wa_f_font.shodow_off_y < -10)
mstyle->wa_f_font.shodow_off_y = -10;
if (XrmGetResource(database,
"menu.hilite.textShadowXOffset",
"Menu.Hilite.TextShadowXOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_fh_font.shodow_off_x) != 1)
mstyle->wa_fh_font.shodow_off_x = 0;
} else
mstyle->wa_fh_font.shodow_off_x = 0;
if (mstyle->wa_fh_font.shodow_off_x > 10)
mstyle->wa_fh_font.shodow_off_x = 10;
if (mstyle->wa_fh_font.shodow_off_x < -10)
mstyle->wa_fh_font.shodow_off_x = -10;
if (XrmGetResource(database,
"menu.hilite.textShadowYOffset",
"Menu.Hilite.TextShadowYOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_fh_font.shodow_off_y) != 1)
mstyle->wa_fh_font.shodow_off_y = 0;
} else
mstyle->wa_fh_font.shodow_off_y = 0;
if (mstyle->wa_fh_font.shodow_off_y > 10)
mstyle->wa_fh_font.shodow_off_y = 10;
if (mstyle->wa_fh_font.shodow_off_y < -10)
mstyle->wa_fh_font.shodow_off_y = -10;
if (XrmGetResource(database,
"menu.title.textShadowXOffset",
"Menu.Title.TextShadowXOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_t_font.shodow_off_x) != 1)
mstyle->wa_t_font.shodow_off_x = 0;
} else
mstyle->wa_t_font.shodow_off_x = 0;
if (mstyle->wa_t_font.shodow_off_x > 10)
mstyle->wa_t_font.shodow_off_x = 10;
if (mstyle->wa_t_font.shodow_off_x < -10)
mstyle->wa_t_font.shodow_off_x = -10;
if (XrmGetResource(database,
"menu.title.textShadowYOffset",
"Menu.Title.TextShadowYOffset", &value_type,
&value)) {
if (sscanf(value.addr, "%d", &mstyle->wa_t_font.shodow_off_y) != 1)
mstyle->wa_t_font.shodow_off_y = 0;
} else
mstyle->wa_t_font.shodow_off_y = 0;
if (mstyle->wa_t_font.shodow_off_y > 10)
mstyle->wa_t_font.shodow_off_y = 10;
if (mstyle->wa_t_font.shodow_off_y < -10)
mstyle->wa_t_font.shodow_off_y = -10;
if (XrmGetResource(database, "menu.justify", "Menu.Justify",
&value_type, &value)) {
if (strstr(value.addr, "right") || strstr(value.addr, "Right")) {
mstyle->f_justify = RightJustify;
mstyle->t_justify = RightJustify;
}
else if (strstr(value.addr, "center") ||
strstr(value.addr, "Center")) {
mstyle->f_justify = CenterJustify;
mstyle->t_justify = CenterJustify;
}
else {
mstyle->f_justify = LeftJustify;
mstyle->t_justify = LeftJustify;
}
} else {
mstyle->f_justify = LeftJustify;
mstyle->t_justify = LeftJustify;
}
if (XrmGetResource(database, "menu.frame.justify", "Menu.Frame.Justify",
&value_type, &value)) {
if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
mstyle->f_justify = RightJustify;
else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
mstyle->f_justify = CenterJustify;
else
mstyle->f_justify = LeftJustify;
}
if (XrmGetResource(database, "menu.title.justify", "Menu.Title.Justify",
&value_type, &value)) {
if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
mstyle->t_justify = RightJustify;
else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
mstyle->t_justify = CenterJustify;
else
mstyle->t_justify = LeftJustify;
}
char *look_tmp;
unsigned int ch;
if (XrmGetResource(database, "menu.bullet.look", "Menu.Bullet.Look",
&value_type, &value)) {
if (sscanf(value.addr, "'%u'", &ch) != 1) {
mstyle->bullet = __m_wastrdup(value.addr);
} else {
look_tmp = new char[2];
sprintf(look_tmp, "%c", ch);
mstyle->bullet = look_tmp;
}
} else {
look_tmp = new char[2];
sprintf(look_tmp, ">");
mstyle->bullet = look_tmp;
}
if (XrmGetResource(database, "menu.checkbox.true.look",
"Menu.Checkbox.True.Look", &value_type, &value)) {
if (sscanf(value.addr, "'%u'", &ch) != 1) {
mstyle->checkbox_true = __m_wastrdup(value.addr);
} else {
look_tmp = new char[2];
sprintf(look_tmp, "%c", ch);
mstyle->checkbox_true = look_tmp;
}
} else
mstyle->checkbox_true = __m_wastrdup("[x]");
if (XrmGetResource(database, "menu.checkbox.false.look",
"Menu.Checkbox.False.Look", &value_type, &value)) {
if (sscanf(value.addr, "'%u'", &ch) != 1) {
mstyle->checkbox_false = __m_wastrdup(value.addr);
} else {
look_tmp = new char[2];
sprintf(look_tmp, "%c", ch);
mstyle->checkbox_false = look_tmp;
}
} else
mstyle->checkbox_false = __m_wastrdup("[ ]");
ReadDatabaseColor("borderColor", "BorderColor",
&wstyle->border_color, BlackPixel(display, screen), ic);
mstyle->border_color = wstyle->border_color;
ReadDatabaseColor("outlineColor", "OutlineColor",
&wstyle->outline_color, WhitePixel(display, screen),
ic);
mstyle->border_color = wstyle->border_color;
if (XrmGetResource(database, "handleWidth", "HandleWidth", &value_type,
&value)) {
if (sscanf(value.addr, "%u", &wstyle->handle_width) != 1 ||
wstyle->handle_width > 6)
wstyle->handle_width = 6;
} else
wstyle->handle_width = 6;
if (XrmGetResource(database, "borderWidth", "BorderWidth", &value_type,
&value)) {
if (sscanf(value.addr, "%u", &wstyle->border_width) != 1)
wstyle->border_width = 1;
} else
wstyle->border_width = 1;
mstyle->border_width = wstyle->border_width;
if (XrmGetResource(database, "menu.borderWidth", "Menu.BorderWidth",
&value_type, &value))
sscanf(value.addr, "%u", &mstyle->border_width);
if (XrmGetResource(database, "window.title.height", "window.title.height",
&value_type, &value)) {
if (sscanf(value.addr, "%u", &wstyle->title_height) != 1)
wstyle->title_height = 0;
else if (wstyle->title_height > 50)
wstyle->title_height = 50;
} else
wstyle->title_height = 0;
if (XrmGetResource(database, "menu.title.height", "menu.title.height",
&value_type, &value)) {
if (sscanf(value.addr, "%u", &mstyle->title_height) != 1)
mstyle->title_height = 0;
else if (mstyle->title_height > 50)
mstyle->title_height = 50;
} else
mstyle->title_height = 0;
if (XrmGetResource(database, "menu.item.height", "menu.item.height",
&value_type, &value)) {
if (sscanf(value.addr, "%u", &mstyle->item_height) != 1)
mstyle->item_height = mstyle->title_height;
else if (mstyle->item_height > 50)
mstyle->item_height = 50;
} else
mstyle->item_height = mstyle->title_height;
if (XrmGetResource(database, "rootCommand", "RootCommand",
&value_type, &value))
waexec(value.addr, wascreen->displaystring);
int num = 0;
char rc_name[50], rc_class[50];
list<DockStyle *>::iterator dit = wascreen->wstyle.dockstyles.begin();
for (; dit != wascreen->wstyle.dockstyles.end(); ++dit, ++num) {
(*dit)->style.border_color = wstyle->border_color;
(*dit)->style.texture = wstyle->t_focus;
(*dit)->style.border_width = wstyle->border_width;
sprintf(rc_name, "dockappholder.dock%d.frame", num);
sprintf(rc_class, "Dockappholder.Dock%d.frame", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value))
ReadDatabaseTexture(rc_name, rc_class, &(*dit)->style.texture,
WhitePixel(display, screen), ic);
sprintf(rc_name, "dockappholder.dock%d.borderWidth", num);
sprintf(rc_class, "Dockappholder.Dock%d.BorderWidth", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (sscanf(value.addr, "%u", &(*dit)->style.border_width) != 1)
(*dit)->style.border_width = wstyle->border_width;
}
sprintf(rc_name, "dockappholder.dock%d.borderColor", num);
sprintf(rc_class, "Dockappholder.Dock%d.BorderColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type, &value))
ReadDatabaseColor(rc_name, rc_class, &(*dit)->style.border_color,
BlackPixel(display, screen), ic);
}
WaTexture tf_tmp, tu_tmp, tp_tmp;
WaColor cf_tmp, cu_tmp, cp_tmp;
ReadDatabaseTexture("window.button.focus", "Window.Button.Focus",
&tf_tmp, WhitePixel(display, screen), ic);
ReadDatabaseTexture("window.button.unfocus", "Window.Button.Unfocus",
&tu_tmp, BlackPixel(display, screen), ic);
ReadDatabaseTexture("window.button.pressed", "Window.Button.Pressed",
&tp_tmp, BlackPixel(display, screen), ic);
ReadDatabaseColor("window.button.focus.picColor",
"Window.Button.Focus.PicColor",
&cf_tmp, BlackPixel(display, screen), ic);
ReadDatabaseColor("window.button.unfocus.picColor",
"Window.Button.Unfocus.PicColor",
&cu_tmp, WhitePixel(display, screen), ic);
ReadDatabaseColor("window.button.pressed.picColor",
"Window.Button.Pressed.PicColor",
&cp_tmp, cf_tmp.getPixel(), ic);
list<ButtonStyle *> *buttonstyles = &wascreen->wstyle.buttonstyles;
ButtonStyle *b = new ButtonStyle;
b->id = 0;
b->autoplace = WestType;
b->cb = ShadeCBoxType;
buttonstyles->push_back(b);
b = new ButtonStyle;
b->id = 1;
b->autoplace = EastType;
b->cb = CloseCBoxType;
buttonstyles->push_back(b);
b = new ButtonStyle;
b->id = 2;
b->autoplace = EastType;
b->cb = MaxCBoxType;
buttonstyles->push_back(b);
list<ButtonStyle *>::iterator bit = buttonstyles->begin();
for (; bit != buttonstyles->end(); ++bit) {
(*bit)->fg = true;
(*bit)->x = 0;
(*bit)->t_focused = (*bit)->t_focused2 = tf_tmp;
(*bit)->c_focused = (*bit)->c_focused2 = cf_tmp;
(*bit)->t_unfocused = (*bit)->t_unfocused2 = tu_tmp;
(*bit)->c_unfocused = (*bit)->c_unfocused2 = cu_tmp;
(*bit)->t_pressed = (*bit)->t_pressed2 = tp_tmp;
(*bit)->c_pressed = (*bit)->c_pressed2 = cp_tmp;
}
bool first = true, found = true;
for (num = 0; found; ++num) {
found = false;
b = new ButtonStyle;
b->id = num;
b->autoplace = EastType;
b->cb = b->x = 0;
b->fg = true;
b->t_focused = tf_tmp;
b->c_focused = cf_tmp;
b->t_unfocused = tu_tmp;
b->c_unfocused = cu_tmp;
b->t_pressed = tp_tmp;
b->c_pressed = cp_tmp;
sprintf(rc_name, "window.button%d.foreground", num);
sprintf(rc_class, "Window.Button%d.Foreground", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
if (! strncasecmp("true", value.addr, value.size)) b->fg = true;
else b->fg = false;
found = true;
}
sprintf(rc_name, "window.button%d.autoplace", num);
sprintf(rc_class, "Window.Button%d.Autoplace", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
if (! strncasecmp("Left", value.addr, value.size))
b->autoplace = WestType;
else if(! strncasecmp("False", value.addr, value.size))
b->autoplace = 0;
else b->autoplace = EastType;
found = true;
}
sprintf(rc_name, "window.button%d.position", num);
sprintf(rc_class, "Window.Button%d.Position", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
if (! sscanf(value.addr, "%d", &b->x)) {
b->autoplace = EastType;
}
else if (b->x != 0) b->autoplace = 0;
found = true;
}
sprintf(rc_name, "window.button%d.state", num);
sprintf(rc_class, "Window.Button%d.State", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
if (! strncasecmp("SHADED", value.addr, value.size))
b->cb = ShadeCBoxType;
else if(! strncasecmp("MAXIMIZED", value.addr, value.size))
b->cb = MaxCBoxType;
else if(! strncasecmp("STICKY", value.addr, value.size))
b->cb = StickCBoxType;
else if(! strncasecmp("ALWAYSONTOP", value.addr, value.size))
b->cb = AOTCBoxType;
else if(! strncasecmp("ALWAYSATBOTTOM", value.addr, value.size))
b->cb = AABCBoxType;
else if(! strncasecmp("DECORTITLE", value.addr, value.size))
b->cb = TitleCBoxType;
else if(! strncasecmp("DECORHANDLE", value.addr, value.size))
b->cb = HandleCBoxType;
else if(! strncasecmp("DECORBORDER", value.addr, value.size))
b->cb = BorderCBoxType;
else if(! strncasecmp("DECORALL", value.addr, value.size))
b->cb = AllCBoxType;
else if(! strncasecmp("CLOSE", value.addr, value.size))
b->cb = CloseCBoxType;
found = true;
}
sprintf(rc_name, "window.button%d.false.focus", num);
sprintf(rc_class, "Window.Button%d.False.Focus", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_focused,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.false.focus.picColor", num);
sprintf(rc_class, "Window.Button%d.False.Focus.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_focused,
BlackPixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.false.unfocus", num);
sprintf(rc_class, "Window.Button%d.False.Unfocus", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_unfocused,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.false.unfocus.picColor", num);
sprintf(rc_class, "Window.Button%d.False.Unfocus.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_unfocused,
BlackPixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.false.pressed", num);
sprintf(rc_class, "Window.Button%d.False.Pressed", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_pressed,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.false.pressed.picColor", num);
sprintf(rc_class, "Window.Button%d.False.Pressed.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_pressed,
BlackPixel(display, screen), ic);
found = true;
}
b->t_focused2 = b->t_focused;
b->c_focused2 = b->c_focused;
b->t_unfocused2 = b->t_unfocused;
b->c_unfocused2 = b->c_unfocused;
b->t_pressed2 = b->t_pressed;
b->c_pressed2 = b->c_pressed;
sprintf(rc_name, "window.button%d.true.focus", num);
sprintf(rc_class, "Window.Button%d.True.Focus", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_focused2,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.true.focus.picColor", num);
sprintf(rc_class, "Window.Button%d.True.Focus.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_focused2,
BlackPixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.true.unfocus", num);
sprintf(rc_class, "Window.Button%d.True.Unfocus", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_unfocused2,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.true.unfocus.picColor", num);
sprintf(rc_class, "Window.Button%d.True.Unfocus.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_unfocused2,
BlackPixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.true.pressed", num);
sprintf(rc_class, "Window.Button%d.True.Pressed", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseTexture(rc_name, rc_class, &b->t_pressed2,
WhitePixel(display, screen), ic);
found = true;
}
sprintf(rc_name, "window.button%d.true.pressed.picColor", num);
sprintf(rc_class, "Window.Button%d.True.Pressed.PicColor", num);
if (XrmGetResource(database, rc_name, rc_class, &value_type,
&value)) {
if (first) { LISTPTRDEL(buttonstyles); first = false; }
ReadDatabaseColor(rc_name, rc_class, &b->c_pressed2,
BlackPixel(display, screen), ic);
found = true;
}
if (found) buttonstyles->push_back(b);
else delete b;
}
wstyle->b_num = buttonstyles->size();
XrmDestroyDatabase(database);
}
/**
* @fn LoadMenus(WaScreen *wascreen)
* @brief Reads menu file
*
* Creates menus by parsing the menu file.
*
* @param wascreen WaScreen to load menus for
*/
void ResourceHandler::LoadMenus(WaScreen *wascreen) {
FILE *file;
if (! (file = fopen(wascreen->config.menu_file, "r"))) {
WARNING << "can't open menufile `" << wascreen->config.menu_file <<
"' for reading" << endl;
return;
}
while (! feof(file)) ParseMenu(NULL, file, wascreen);
fclose(file);
}
/**
* @fn LoadActions(WaScreen *wascreen)
* @brief Reads action file
*
* Creates action lists by parsing the action file.
*
* @param wascreen WaScreen to create action lists for
*/
void ResourceHandler::LoadActions(WaScreen *wascreen) {
ScreenConfig *sc = &wascreen->config;
FILE *file;
int i, i2, i3;
bool cmd;
int ret;
char buffer[8192];
char buffer2[8192];
char *str;
WaActionExtList *ext_list;
list<Define *> *defs = new list<Define *>;
sc->bacts = new list<WaAction *>*[wascreen->wstyle.b_num];
sc->ext_bacts = new list<WaActionExtList *>*[wascreen->wstyle.b_num];
for (i = 0; i < wascreen->wstyle.b_num; i++) {
sc->bacts[i] = new list<WaAction *>;
sc->ext_bacts[i] = new list<WaActionExtList *>;
}
if (! (file = fopen(sc->action_file, "r"))) {
WARNING << "can't open action file `" << sc->action_file <<
"' for reading" << endl;
return;
}
for (;;) {
for (i = 0; (ret = fgetc(file)) != EOF &&
ret != '{'; i++) {
buffer[i] = ret;
if (buffer[i] == '#' || buffer[i] == '!') {
i--;
while ((ret = fgetc(file)) != EOF && ret != '\n');
}
}
if (ret == EOF) {
fclose(file);
LISTPTRDEL(defs);
delete defs;
return;
}
else buffer[i] = ret;
str = strtrim(buffer);
switch (buffer[i]) {
case '\n':
i = 0;
break;
case '{':
buffer[i] = '\0';
cmd = false;
for (i2 = 0; (ret = fgetc(file)) != EOF &&
(ret != '}' || cmd); i2++) {
buffer2[i2] = ret;
if (buffer2[i2] == '{') cmd = true;
if (buffer2[i2] == '}') cmd = false;
if (buffer2[i2] == '#' || buffer[i] == '!') {
i2--;
while ((ret = fgetc(file)) != EOF && ret != '\n');
}
}
buffer2[i2] = ret;
if (ret == EOF) ERROR << "missing '}'" << endl;
buffer2[i2] = '\0';
if (! strncasecmp(str, "DEF", 3)) {
str = strtrim(str + 3);
defs->push_front(new Define(str, strtrim(buffer2)));
}
else {
str = strtrim(str);
if (! strcasecmp(str, "root")) {
ReadActions((char *) buffer2, defs, &racts,
&sc->rootacts, wascreen);
}
else if (! strcasecmp(str, "westedge")) {
ReadActions((char *) buffer2, defs, &racts,
&sc->weacts, wascreen);
}
else if (! strcasecmp(str, "eastedge")) {
ReadActions((char *) buffer2, defs, &racts,
&sc->eeacts, wascreen);
}
else if (! strcasecmp(str, "northedge")) {
ReadActions((char *) buffer2, defs, &racts,
&sc->neacts, wascreen);
}
else if (! strcasecmp(str, "southedge")) {
ReadActions((char *) buffer2, defs, &racts,
&sc->seacts, wascreen);
}
else if (! strcasecmp(str, "menu.title")) {
ReadActions((char *) buffer2, defs, &macts,
&sc->mtacts, wascreen);
}
else if (! strcasecmp(str, "menu.item")) {
ReadActions((char *) buffer2, defs, &macts,
&sc->miacts, wascreen);
}
else if (! strcasecmp(str, "menu.sub")) {
ReadActions((char *) buffer2, defs, &macts,
&sc->msacts, wascreen);
}
else if (! strcasecmp(str, "menu.checkbox")) {
ReadActions((char *) buffer2, defs, &macts,
&sc->mcbacts, wascreen);
}
else {
ext_list = NULL;
if (str[0] == 'c' && str[1] == '/') {
for (i3 = 2; str[i3] != '\0' &&
! (str[i3] == '/' && str[i3 - 1] != '\\');
i3++);
if (str[i3] == '\0') {
WARNING << "missing '/'" << endl;
break;
}
str[i3] = '\0';
ext_list = new WaActionExtList(NULL, str + 2,
NULL);
str = str + i3 + 1;
ReadActions((char *) buffer2, defs, &wacts,
&ext_list->list, wascreen);
}
else if (str[0] == 'n' && str[1] == '/') {
for (i3 = 2; str[i3] != '\0' &&
! (str[i3] == '/' && str[i3 - 1] != '\\');
i3++);
if (str[i3] == '\0') {
WARNING << "missing '/'" << endl;
break;
}
str[i3] = '\0';
ext_list = new WaActionExtList(str + 2, NULL,
NULL);
str = str + i3 + 1;
ReadActions((char *) buffer2, defs, &wacts,
&ext_list->list, wascreen);
}
else if (str[0] == 't' && str[1] == '/') {
for (i3 = 2; str[i3] != '\0' &&
! (str[i3] == '/' && str[i3 - 1] != '\\');
i3++);
if (str[i3] == '\0') {
WARNING << "missing '/'" << endl;
break;
}
str[i3] = '\0';
ext_list = new WaActionExtList(NULL, NULL,
str + 2);
str = str + i3 + 1;
ReadActions((char *) buffer2, defs, &wacts,
&ext_list->list, wascreen);
}
else if (! strncasecmp(str, "window", 6)) {
str = str + 6;
}
else {
WARNING << "unknown window: " << str << endl;
break;
}
if (! strcasecmp(str, ".frame")) {
if (ext_list)
sc->ext_frameacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->frameacts, wascreen);
}
else if (! strcasecmp(str, ".title")) {
if (ext_list)
sc->ext_titleacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->titleacts, wascreen);
}
else if (! strcasecmp(str, ".label")) {
if (ext_list)
sc->ext_labelacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->labelacts, wascreen);
}
else if (! strcasecmp(str, ".handle")) {
if (ext_list)
sc->ext_handleacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->handleacts, wascreen);
}
else if (! strcasecmp(str, ".activeclient")) {
if (ext_list)
sc->ext_awinacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->awinacts, wascreen);
}
else if (! strcasecmp(str, ".passiveclient")) {
if (ext_list)
sc->ext_pwinacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->pwinacts, wascreen);
}
else if (! strcasecmp(str, ".leftgrip")) {
if (ext_list) sc->ext_lgacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->lgacts, wascreen);
}
else if (! strcasecmp(str, ".rightgrip")) {
if (ext_list) sc->ext_rgacts.push_back(ext_list);
else ReadActions((char *) buffer2, defs, &wacts,
&sc->rgacts, wascreen);
}
else if (! strncasecmp(str, ".button", 7)) {
int id;
if (strlen(str) > 7) {
id = atoi(str + 7);
if (id < 0 || id >= wascreen->wstyle.b_num)
WARNING << "bad button id: " << id <<
endl;
else {
if (ext_list)
sc->ext_bacts[id]->push_back(
ext_list);
else
ReadActions((char *) buffer2, defs,
&wacts, sc->bacts[id],
wascreen);
}
}
}
else {
WARNING << "unknown child window: " << str << endl;
break;
}
}
}
break;
}
}
}
/**
* @fn ReadActions(char *s,
* list<Define *> *defs,
* list<StrComp *> *comp,
* list<WaAction *> *insert,
* WaScreen *wascreen)
* @brief Parses a block of actions
*
* Parses a block of action lines. All defines are replaced with actual lines
* and then parsed.
*
* @param defs List with temporary defined action lists
* @param comp List with available actions
* @param insert List to insert action in
* @param wascreen WaScreen to create action list for
*/
void ResourceHandler::ReadActions(char s[8192],
list<Define *> *defs,
list<StrComp *> *comp,
list<WaAction *> *insert,
WaScreen *wascreen) {
bool match, ret = false;
char tmp[8192];
char *ts;
int i;
list<Define *>::iterator it;
for (;;) {
for (i = 0; s[i] != ',' && s[i] != '\0'; i++);
if (s[i] == '\0') {
s[i + 1] = '\0';
ret = true;
}
else s[i] = '\0';
ts = strtrim(s);
if (strlen(ts) == 0) {
s = s + i + 1;
if (ret) return;
continue;
}
match = false;
for (it = defs->begin(); it != defs->end(); ++it) {
if (! strcasecmp(ts, (*it)->name)) {
if (! ret) {
s[i] = ',';
sprintf(tmp, "%s", s + i);
}
else tmp[0] = '\0';
sprintf(s, "%s%s", (*it)->value, tmp);
ret = false;
match = true;
break;
}
}
if (! match) {
ParseAction(ts, comp, insert, wascreen);
s = s + i + 1;
}
if (ret) return;
}
}
/**
* @fn ReadDatabaseColor(char *rname, char *rclass,
* WaColor *color,
* unsigned long default_pixel,
* WaImageControl *ic)
* @brief Reads a color
*
* Reads a color from resource database.
*
* @param rname Resource name to use
* @param rclass Resource class name to use
* @param default_pixel Pixel value to use if resource doesn't exist
* @param ic WaImageControl to use for parsing color
*/
void ResourceHandler::ReadDatabaseColor(char *rname, char *rclass,
WaColor *color,
unsigned long default_pixel,
WaImageControl *ic) {
XrmValue value;
char *value_type;
int opacity;
if (XrmGetResource(database, rname, rclass, &value_type,
&value)) {
strtrim(value.addr);
ic->parseColor(color, value.addr);
} else {
ic->parseColor(color);
color->setPixel(default_pixel);
}
int clen = strlen(rclass) + 9, nlen = strlen(rname) + 9;
char *oclass = new char[clen], *oname = new char[nlen];
sprintf(oclass, "%s.Opacity", rclass);
sprintf(oname, "%s.opacity", rname);
if (XrmGetResource(database, oname, oclass, &value_type, &value))
opacity = atoi(value.addr);
else
opacity = 0;
if (opacity > 100) opacity = 100;
else if (opacity < 0) opacity = 0;
#ifdef XFT
color->setXftOpacity(opacity);
#endif // XFT
delete [] oclass;
delete [] oname;
}
/**
* @fn ReadDatabaseTexture(char *rname, char *rclass,
* WaColor *color,
* unsigned long default_pixel,
* WaImageControl *ic)
* @brief Reads a texture
*
* Reads a texture from resource database.
*
* @param rname Resource name to use
* @param rclass Resource class name to use
* @param default_pixel Pixel value to use if resource doesn't exist
* @param ic WaImageControl to use for parsing color
*/
void ResourceHandler::ReadDatabaseTexture(char *rname, char *rclass,
WaTexture *texture,
unsigned long default_pixel,
WaImageControl *ic) {
XrmValue value;
char *value_type;
Colormap colormap = ic->getColormap();
if (XrmGetResource(database, rname, rclass, &value_type,
&value))
ic->parseTexture(texture, value.addr);
else
texture->setTexture(WaImage_Solid | WaImage_Flat);
int clen = strlen(rclass) + 32, nlen = strlen(rname) + 32;
char *colorclass = new char[clen], *colorname = new char[nlen];
#ifdef PIXMAP
if (texture->getTexture() & WaImage_Pixmap) {
int clen = strlen(rclass) + 20, nlen = strlen(rname) + 20;
char *pixmapclass = new char[clen], *pixmapname = new char[nlen];
char pixmap_path[1024];
imlib_context_push(ic->getWaScreen()->imlib_context);
texture->setContext(&ic->getWaScreen()->imlib_context);
imlib_context_set_mask(0);
Imlib_Border bd;
Imlib_Image image = NULL;
sprintf(pixmapclass, "%s.Pixmap", rclass);
sprintf(pixmapname, "%s.pixmap", rname);
if (XrmGetResource(database, pixmapname, pixmapclass, &value_type,
&value)) {
if (strstr(value.addr, "/")) {
if (! (image = imlib_load_image(value.addr)))
WARNING << "failed loading image `" << value.addr <<
"'\n";
}
else {
sprintf(pixmap_path, "%s/%s",
ic->getWaScreen()->config.style_file, value.addr);
if (! (image = imlib_load_image(pixmap_path))) {
WARNING << "failed loading image `" << value.addr <<
"'\n";
}
}
}
if (image) {
texture->setPixmap(image);
if (texture->getTexture() & WaImage_Stretch) {
sprintf(pixmapclass, "%s.Border", rclass);
sprintf(pixmapname, "%s.border", rname);
imlib_context_set_image(image);
if (XrmGetResource(database, pixmapname, pixmapclass,
&value_type, &value)) {
sscanf(value.addr, "{ %u, %u, %u, %u }",
(unsigned int *) &bd.left,
(unsigned int *) &bd.right,
(unsigned int *) &bd.top,
(unsigned int *) &bd.bottom);
if (bd.left > imlib_image_get_width())
bd.left = imlib_image_get_width();
if (bd.right > imlib_image_get_width())
bd.right = imlib_image_get_width();
if ((bd.left + bd.right) > imlib_image_get_width())
bd.right = imlib_image_get_width() - bd.left - 1;
if (bd.top > imlib_image_get_height())
bd.top = imlib_image_get_height();
if (bd.bottom > imlib_image_get_height())
bd.bottom = imlib_image_get_height();
if ((bd.top + bd.bottom) > imlib_image_get_height())
bd.bottom = imlib_image_get_width() - bd.top - 1;
}
else {
bd.left = imlib_image_get_width() / 2;
bd.right = imlib_image_get_width() - bd.left - 1;
bd.top = imlib_image_get_height() / 2;
bd.bottom = imlib_image_get_height() - bd.top - 1;
}
imlib_image_set_border(&bd);
}
}
else
texture->setTexture(WaImage_Solid | WaImage_Flat);
delete [] pixmapclass;
delete [] pixmapname;
imlib_context_pop();
}
#endif // PIXMAP
if (texture->getTexture() & WaImage_Solid) {
sprintf(colorclass, "%s.Color", rclass);
sprintf(colorname, "%s.color", rname);
strtrim(colorclass);
strtrim(colorname);
ReadDatabaseColor(colorname, colorclass, texture->getColor(),
default_pixel, ic);
#ifdef INTERLACE
sprintf(colorclass, "%s.ColorTo", rclass);
sprintf(colorname, "%s.colorTo", rname);
strtrim(colorclass);
strtrim(colorname);
ReadDatabaseColor(colorname, colorclass, texture->getColorTo(),
default_pixel, ic);
#endif // INTERLACE
if (texture->getColor()->isAllocated() &&
(!(texture->getTexture() & WaImage_Flat))) {
XColor xcol;
xcol.red = (unsigned int) (texture->getColor()->getRed() +
(texture->getColor()->getRed() >> 1));
if (xcol.red >= 0xff) xcol.red = 0xffff;
else xcol.red *= 0xff;
xcol.green = (unsigned int) (texture->getColor()->getGreen() +
(texture->getColor()->getGreen() >>
1));
if (xcol.green >= 0xff) xcol.green = 0xffff;
else xcol.green *= 0xff;
xcol.blue = (unsigned int) (texture->getColor()->getBlue() +
(texture->getColor()->getBlue() >>
1));
if (xcol.blue >= 0xff) xcol.blue = 0xffff;
else xcol.blue *= 0xff;
if (! XAllocColor(display, colormap, &xcol))
xcol.pixel = 0;
texture->getHiColor()->setPixel(xcol.pixel);
xcol.red =
(unsigned int) ((texture->getColor()->getRed() >> 2) +
(texture->getColor()->getRed() >> 1)) * 0xff;
xcol.green =
(unsigned int) ((texture->getColor()->getGreen() >> 2) +
(texture->getColor()->getGreen() >> 1)) *
0xff;
xcol.blue =
(unsigned int) ((texture->getColor()->getBlue() >> 2) +
(texture->getColor()->getBlue() >> 1)) * 0xff;
if (! XAllocColor(display, colormap, &xcol))
xcol.pixel = 0;
texture->getLoColor()->setPixel(xcol.pixel);
}
} else if (texture->getTexture() & WaImage_Gradient) {
int clen = strlen(rclass) + 10, nlen = strlen(rname) + 10;
char *colortoclass = new char[clen], *colortoname = new char[nlen];
sprintf(colorclass, "%s.Color", rclass);
sprintf(colorname, "%s.color", rname);
strtrim(colorclass);
strtrim(colorname);
sprintf(colortoclass, "%s.ColorTo", rclass);
sprintf(colortoname, "%s.colorTo", rname);
strtrim(colortoclass);
strtrim(colortoname);
ReadDatabaseColor(colorname, colorclass, texture->getColor(),
default_pixel, ic);
ReadDatabaseColor(colortoname, colortoclass, texture->getColorTo(),
default_pixel, ic);
delete [] colortoclass;
delete [] colortoname;
}
#ifdef RENDER
if (texture->getTexture() & WaImage_ParentRelative) {
delete [] colorclass;
delete [] colorname;
return;
}
if (! ic->getWaScreen()->render_extension) {
texture->setOpacity(0);
delete [] colorclass;
delete [] colorname;
return;
}
int opacity;
XRenderPictFormat *xformat;
XRenderPictFormat Rpf;
XRenderPictureAttributes Rpa;
XRenderColor clr;
Pixmap alphaPixmap, solidPixmap;
Picture alphaPicture, solidPicture;
sprintf(colorclass, "%s.Opacity", rclass);
sprintf(colorname, "%s.opacity", rname);
if (XrmGetResource(database, colorname, colorclass, &value_type,
&value))
opacity = atoi(value.addr);
else
opacity = 0;
opacity = (opacity * 255) / 100;
if (opacity > 255) opacity = 255;
else if (opacity < 0) opacity = 0;
texture->setOpacity(opacity);
if (opacity > 0 && opacity < 255) {
clr.alpha = ((unsigned short) (255 * opacity) << 8);
Rpf.type = PictTypeDirect;
Rpf.depth = 8;
Rpf.direct.alphaMask = 0xff;
Rpa.repeat = True;
xformat = XRenderFindFormat(ic->getDisplay(), PictFormatType |
PictFormatDepth | PictFormatAlphaMask,
&Rpf, 0);
alphaPixmap = XCreatePixmap(ic->getDisplay(), ic->getDrawable(),
1, 1, 8);
alphaPicture = XRenderCreatePicture(ic->getDisplay(), alphaPixmap,
xformat, CPRepeat, &Rpa);
XRenderFillRectangle(ic->getDisplay(), PictOpSrc, alphaPicture, &clr,
0, 0, 1, 1);
texture->setAlphaPicture(alphaPicture);
XFreePixmap(ic->getDisplay(), alphaPixmap);
if (texture->getTexture() == (WaImage_Solid | WaImage_Flat)) {
Rpf.depth = ic->getDepth();
xformat = XRenderFindFormat(ic->getDisplay(), PictFormatType |
PictFormatDepth,
&Rpf, 0);
solidPixmap = XCreatePixmap(ic->getDisplay(), ic->getDrawable(),
1, 1, ic->getDepth());
solidPicture = XRenderCreatePicture(ic->getDisplay(), solidPixmap,
xformat, CPRepeat, &Rpa);
XRenderFillRectangle(ic->getDisplay(), PictOpSrc, solidPicture,
texture->getColor()->getXRenderColor(),
0, 0, 1, 1);
texture->setSolidPicture(solidPicture);
XFreePixmap(ic->getDisplay(), solidPixmap);
}
}
#endif // RENDER
delete [] colorclass;
delete [] colorname;
}
/**
* @fn ReadDatabaseFont(char *rname, char *rclass,
* WaFont *font, WaFont *defaultfont)
* @brief Reads a font
*
* Reads a font from resource database.
*
* @param rname Resource name to use
* @param rclass Resource class name to use
* @param font Pointer to WaFont structure
* @param defaultfont Font to use if resource doesn't exist
*/
void ResourceHandler::ReadDatabaseFont(char *rname, char *rclass,
WaFont *font, WaFont *defaultfont) {
XrmValue value;
char *value_type;
char *xft_match;
char *f;
char *__m_wastrdup_tmp;
if (XrmGetResource(database, rname, rclass, &value_type, &value)) {
f = value.addr;
font->xft = false;
if ((xft_match = strchr(f, '['))) {
xft_match[0] = '\0';
#ifdef XFT
if (xft_match[1] != '\0' && xft_match[2] != '\0' &&
xft_match[3] != '\0')
if (strncasecmp(&xft_match[1], "XFT", 3) == 0)
font->xft = true;
#endif // XFT
}
font->font = __m_wastrdup(f);
strtrim(font->font);
if (xft_match) xft_match[0] = '[';
} else {
font->xft = defaultfont->xft;
font->font = __m_wastrdup(defaultfont->font);
}
}
/**
* @fn ParseAction(const char *_s, list<StrComp *> *comp,
* list<WaAction *> *insert, WaScreen *wascreen)
* @brief Parses an action line
*
* Parses an action line into an action object and inserts it in action list.
*
* @param _s Action line to parse
* @param comp List with available actions
* @param insert List to insert action in
* @param wascreen WaScreen to parse action for
*/
void ResourceHandler::ParseAction(const char *_s, list<StrComp *> *comp,
list<WaAction *> *insert,
WaScreen *wascreen) {
char *line, *token, *par, *tmp_par;
int i, detail, mod;
WaAction *act_tmp;
KeySym keysym;
list<StrComp *>::iterator it;
char *__m_wastrdup_tmp;
char *s = NULL;
int min_key, max_key;
XDisplayKeycodes(wascreen->display, &min_key, &max_key);
act_tmp = new WaAction;
act_tmp->replay = false;
act_tmp->delay.tv_sec = act_tmp->delay.tv_usec = 0;
act_tmp->delay_breaks = NULL;
line = __m_wastrdup((char *) _s);
detail = strchr(line, '=') ? 1: 0;
mod = strchr(line, '&') ? 1: 0;
token = strtok(line, ":");
token = strtrim(token);
if (*token == '*') {
act_tmp->replay = true;
token++;
}
tmp_par = __m_wastrdup(token);
par = tmp_par;
act_tmp->exec = NULL;
act_tmp->param = NULL;
for (; *par != '(' && *par != '\0'; par++);
if (*(par++) == '(') {
for (i = 0; par[i] != ')'; i++)
if (par[i] == '\0') {
WARNING << "missing `)' in resource line `" << s << "'"
<< endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
if (*par == '\0' || *par == ')') {
if ((! strncasecmp(token, "menu", 4)) ||
(! strncasecmp(token, "pointer", 7)) ||
(! strncasecmp(token, "viewportrelative", 16)) ||
(! strncasecmp(token, "viewportfixed", 13)) ||
(! strncasecmp(token, "gotodesktop", 11)) ||
(! strncasecmp(token, "partdesktop", 11)) ||
(! strncasecmp(token, "joindesktop", 11)) ||
(! strncasecmp(token, "desktopmask", 11)) ||
(! strncasecmp(token, "partcurrentjoindesktop", 22)) ) {
WARNING "`" << token << "' action must have a parameter" <<
endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
}
if (strlen(par)) {
par[i] = '\0';
act_tmp->param = param_eval(token, par, wascreen);
}
for (i = 0; token[i] != '('; i++);
token[i] = '\0';
}
else if ((! strncasecmp(token, "menu", 4)) ||
(! strncasecmp(token, "pointer", 7)) ||
(! strncasecmp(token, "viewportrelative", 16)) ||
(! strncasecmp(token, "viewportfixed", 13)) ||
(! strncasecmp(token, "gotodesktop", 11)) ||
(! strncasecmp(token, "partdesktop", 11)) ||
(! strncasecmp(token, "joindesktop", 11)) ||
(! strncasecmp(token, "desktopmask", 11)) ||
(! strncasecmp(token, "partcurrentjoindesktop", 22)) ) {
WARNING "`" << token << "' action must have a parameter" <<
endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
delete [] tmp_par;
it = comp->begin();
for (; it != comp->end(); ++it) {
if ((*it)->Comp(token)) {
if ((*it)->type & WindowFuncMask)
act_tmp->winfunc = (*it)->winfunc;
if ((*it)->type & RootFuncMask)
act_tmp->rootfunc = (*it)->rootfunc;
if ((*it)->type & MenuFuncMask)
act_tmp->menufunc = (*it)->menufunc;
break;
}
}
if (! *it) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(token, '{', '}'))) {
act_tmp->exec = __m_wastrdup(s);
} else {
WARNING << "`" << token << "' unknown action" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
}
if (detail) token = strtok(NULL, "=");
else {
if (mod) token = strtok(NULL, "&");
else token = strtok(NULL, "[");
}
if (! token) {
WARNING << "`" << _s << "' no event type in action line" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
token = strtrim(token);
it = types.begin();
for (; it != types.end(); ++it) {
if ((*it)->Comp(token)) {
act_tmp->type = (*it)->value;
break;
}
}
if (! *it) {
WARNING << "`" << token << "' unknown type" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
act_tmp->detail = 0;
if (detail) {
if (mod) token = strtok(NULL, "&");
else token = strtok(NULL, "[");
token = strtrim(token);
if (act_tmp->type == KeyPress || act_tmp->type == KeyRelease) {
if (! strcasecmp(token, "anykey"))
act_tmp->detail = 0;
else {
if ((keysym = XStringToKeysym(token)) == NoSymbol) {
WARNING << "`" << token << "' unknown key" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
} else {
act_tmp->detail = XKeysymToKeycode(display, keysym);
if (act_tmp->detail < (unsigned int) min_key ||
act_tmp->detail > (unsigned int) max_key) {
WARNING << "`" << token << "' bad keycode" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
}
}
} else if (act_tmp->type == ButtonPress ||
act_tmp->type == ButtonRelease ||
act_tmp->type == DoubleClick) {
it = bdetails.begin();
for (; it != bdetails.end(); ++it) {
if ((*it)->Comp(token)) {
act_tmp->detail = (*it)->value;
break;
}
}
if (! *it) {
WARNING << "`" << token << "' unknown detail" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
}
}
bool negative;
act_tmp->mod = act_tmp->nmod = 0;
if (mod) {
token = strtok(NULL, "[");
for (token = strtok(token, "&"); token; token = strtok(NULL, "&")) {
token = strtrim(token);
negative = false;
if (*token == '!') {
negative = true;
token = strtrim(token + 1);
}
for (it = mods.begin(); it != mods.end(); ++it) {
if ((*it)->Comp(token)) {
if (negative)
act_tmp->nmod |= (*it)->value;
else
act_tmp->mod |= (*it)->value;
break;
}
}
if (! *it) {
WARNING << "`" << token << "' unknown modifier " <<
"or bad modifier key" << endl;
delete act_tmp;
delete [] line;
if (s) delete [] s; s = NULL;
return;
}
}
}
if ((token = strtok(NULL, "]"))) {
int msdelay = 0;
act_tmp->delay_breaks = new list<int>;
if ((token = strtok(token, ":"))) {
token = strtrim(token);
msdelay = atoi(token);
act_tmp->delay.tv_usec = (msdelay % 1000) * 1000;
act_tmp->delay.tv_sec = msdelay / 1000;
act_tmp->delay_breaks = new list<int>;
while ((token = strtok(NULL, "|"))) {
token = strtrim(token);
it = types.begin();
for (; it != types.end(); ++it) {
if ((*it)->Comp(token)) {
act_tmp->delay_breaks->push_back((*it)->value);
break;
}
}
if (! *it) {
WARNING << "`" << token <<
"' unknown break event type" << endl;
}
}
}
}
delete [] line;
insert->push_back(act_tmp);
if (s) delete [] s; s = NULL;
}
/**
* @fn ParseMenu(WaMenu *menu, FILE *file, WaScreen *wascreen)
* @brief Parses a menu file
*
* Parses a menu section of the menu file and creates a menu object for the
* menu. If a [start] or [begin] statement is found when parsing a menu, we
* make a recursive function call to this function. This makes it possible to
* to define a submenu within a the menu itself.
*
* @param menu Menu to add items to
* @param file File descriptor for menu file
*
* @return Pointer to new menu if menu was sucessfully parsed,
* otherwise NULL
*/
WaMenu *ResourceHandler::ParseMenu(WaMenu *menu, FILE *file,
WaScreen *wascreen) {
char *s = NULL, line[8192], *line1 = NULL, *line2 = NULL,
*par = NULL, *tmp_par = NULL;
WaMenuItem *m;
int i, type, cb;
WaMenu *tmp_menu;
list<StrComp *>::iterator it;
char *__m_wastrdup_tmp;
while (fgets(line, 8192, file)) {
linenr++;
for (i = 0; line[i] == ' ' || line[i] == '\t'; i++);
if (line[i] == '\n') continue;
if (line[i] == '#') continue;
if (line[i] == '!') continue;
cb = 0;
if (s) delete [] s; s = NULL;
if (! (s = strwithin(line, '[', ']'))) {
WARNING << "(" << basename(menu_file) << ":" << linenr << "):" <<
" missing tag" << endl;
continue;
}
if (! strcasecmp(s, "include")) {
FILE *include_file;
char *tmp_mf;
int tmp_linenr;
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true))) {
if (! (include_file = fopen(s, "r"))) {
WARNING << "can't open menufile `" << s <<
"' for reading" << endl;
continue;
}
tmp_mf = menu_file;
tmp_linenr = linenr;
menu_file = s;
while (! feof(include_file))
ParseMenu(menu, include_file, wascreen);
menu_file = tmp_mf;
linenr = tmp_linenr;
fclose(include_file);
} else {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): missing menufile name" << endl;
}
continue;
}
if ((strcasecmp(s, "start") && strcasecmp(s, "begin"))) {
if (menu == NULL) {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): bad tag, expected [start], [begin] or [include]" <<
endl;
continue;
}
}
if (! strcasecmp(s, "start")) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true))) {
tmp_menu = new WaMenu(s);
if (menu) {
if (menu->dynamic) {
tmp_menu->dynamic = true;
if (ParseMenu(tmp_menu, file, wascreen))
tmp_menu->Build(wascreen);
} else
ParseMenu(tmp_menu, file, wascreen);
}
else menu = tmp_menu;
} else
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): missing menu name" << endl;
continue;
}
else if ((! strcasecmp(s, "submenu")) || (! strcasecmp(s, "begin"))) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true))) {
if (menu) {
m = new WaMenuItem(s);
m->type = MenuSubType;
m->func_mask |= MenuSubMask;
m->func_mask1 |= MenuSubMask;
m->sub = m->sub1 = __m_wastrdup(s);
menu->AddItem(m);
}
tmp_menu = new WaMenu(s);
m = new WaMenuItem(s);
m->type = MenuTitleType;
tmp_menu->AddItem(m);
if (menu) {
if (menu->dynamic) {
tmp_menu->dynamic = true;
if (ParseMenu(tmp_menu, file, wascreen))
tmp_menu->Build(wascreen);
} else
ParseMenu(tmp_menu, file, wascreen);
}
else menu = tmp_menu;
} else
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): missing menu name" << endl;
continue;
}
else if (! strcasecmp(s, "restart")) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true)))
m = new WaMenuItem(s);
else
m = new WaMenuItem("");
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '{', '}')))
m->param1 = m->param = __m_wastrdup(s);
m->type = MenuItemType;
m->func_mask = MenuRFuncMask | MenuWFuncMask | MenuMFuncMask;
m->rfunc = &WaScreen::Restart;
m->wfunc = &WaWindow::Restart;
m->mfunc = &WaMenuItem::Restart;
menu->AddItem(m);
continue;
}
else if (! strcasecmp(s, "exit")) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true)))
m = new WaMenuItem(s);
else
m = new WaMenuItem("");
m->type = MenuItemType;
m->func_mask = MenuRFuncMask | MenuWFuncMask | MenuMFuncMask;
m->rfunc = &WaScreen::Exit;
m->wfunc = &WaWindow::Exit;
m->mfunc = &WaMenuItem::Exit;
menu->AddItem(m);
continue;
}
else if (! strcasecmp(s, "exec")) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true)))
m = new WaMenuItem(s);
else
m = new WaMenuItem("");
m->type = MenuItemType;
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '{', '}'))) {
if (*s != '\0') {
m->exec = m->exec1 = __m_wastrdup(s);
m->func_mask |= MenuExecMask;
m->func_mask1 |= MenuExecMask;
}
}
menu->AddItem(m);
continue;
}
else if (! strcasecmp(s, "nop")) {
if (s) delete [] s; s = NULL;
if ((s = strwithin(line, '(', ')', true)))
m = new WaMenuItem(s);
else
m = new WaMenuItem("");
m->type = MenuItemType;
menu->AddItem(m);
continue;
}
else if (! strcasecmp(s, "end")) {
if (menu->item_list.empty()) {
WARNING << "no elements in menu `" << menu->name <<
"'" << endl;
delete menu;
if (s) delete [] s; s = NULL;
return NULL;
}
wascreen->wamenu_list.push_back(menu);
if (s) delete [] s; s = NULL;
return menu;
}
else if (! strncasecmp(s, "checkbox", 8)) {
if (! strcasecmp(s + 9, "MAXIMIZED")) {
type = MenuCBItemType;
cb = MaxCBoxType;
}
else if (! strcasecmp(s + 9, "SHADED")) {
type = MenuCBItemType;
cb = ShadeCBoxType;
}
else if (! strcasecmp(s + 9, "STICKY")) {
type = MenuCBItemType;
cb = StickCBoxType;
}
else if (! strcasecmp(s + 9, "DECORTITLE")) {
type = MenuCBItemType;
cb = TitleCBoxType;
}
else if (! strcasecmp(s + 9, "DECORHANDLE")) {
type = MenuCBItemType;
cb = HandleCBoxType;
}
else if (! strcasecmp(s + 9, "DECORBORDER")) {
type = MenuCBItemType;
cb = BorderCBoxType;
}
else if (! strcasecmp(s + 9, "DECORALL")) {
type = MenuCBItemType;
cb = AllCBoxType;
}
else if (! strcasecmp(s + 9, "ALWAYSONTOP")) {
type = MenuCBItemType;
cb = AOTCBoxType;
}
else if (! strcasecmp(s + 9, "ALWAYSATBOTTOM")) {
type = MenuCBItemType;
cb = AABCBoxType;
}
else {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): '"<< s + 9 << "' unknown checkbox" << endl;
continue;
}
for (i = 0; strncasecmp(&line[i], "@TRUE", 5) &&
line[i + 5] != '\0'; i++);
if (line[i + 5] == '\0') {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): No '@TRUE' linepart for checkbox item" << endl;
continue;
}
line2 = &line[i + 5];
for (i = 0; strncasecmp(&line[i], "@FALSE", 6) &&
line[i + 6] != '\0'; i++);
if (line[i + 6] == '\0') {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): No '@FALSE' linepart for checkbox item" << endl;
continue;
}
line1 = &line[i + 6];
for (i = 0; strncasecmp(&line1[i], "@TRUE", 5) &&
line1[i + 5] != '\0'; i++);
if (line1[i + 5] != '\0') line1[i] = '\0';
for (i = 0; strncasecmp(&line2[i], "@FALSE", 6) &&
line2[i + 6] != '\0'; i++);
if (line2[i + 6] != '\0') line2[i] = '\0';
}
else if (! strcasecmp(s, "title")) {
type = MenuTitleType;
}
else if (! strcasecmp(s, "item")) {
type = MenuItemType;
}
else if (! strcasecmp(s, "sub")) {
type = MenuSubType;
}
else {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): bad tag [" << s << "]" << endl;
continue;
}
if (! cb) line1 = line;
if (s) delete [] s; s = NULL;
if (! (s = strwithin(line1, '(', ')', true)))
m = new WaMenuItem("");
else
m = new WaMenuItem(s);
m->label1 = m->label;
m->type = type;
m->cb = cb;
if (s) delete [] s; s = NULL;
if ((s = strwithin(line1, '{', '}'))) {
if (*s != '\0') {
m->exec = m->exec1 = __m_wastrdup(s);
m->func_mask |= MenuExecMask;
m->func_mask1 |= MenuExecMask;
}
}
if (s) delete [] s; s = NULL;
if ((s = strwithin(line1, '<', '>'))) {
m->sub = m->sub1 = __m_wastrdup(s);
m->func_mask |= MenuSubMask;
m->func_mask1 |= MenuSubMask;
}
if (s) delete [] s; s = NULL;
if ((s = strwithin(line1, '"', '"'))) {
tmp_par = par = __m_wastrdup(s);
for (i = 0; *par != '(' && *par != '\0'; par++, i++);
if (*(par++) == '(') {
s[i] = '\0';
for (i = 0; par[i] != ')' && par[i] != '\0'; i++);
if (par[i] == '\0') {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): missing ')'" << endl;
delete [] tmp_par;
continue;
}
if (strlen(par)) {
par[i] = '\0';
m->param1 = m->param = param_eval(s, par, wascreen);
delete [] tmp_par;
}
}
else
delete [] tmp_par;
it = wacts.begin();
for (; it != wacts.end(); ++it) {
if ((*it)->Comp(s)) {
m->wfunc = (*it)->winfunc;
m->wfunc1 = (*it)->winfunc;
m->func_mask |= MenuWFuncMask;
m->func_mask1 |= MenuWFuncMask;
break;
}
}
it = racts.begin();
for (; it != racts.end(); ++it) {
if ((*it)->Comp(s)) {
m->rfunc = (*it)->rootfunc;
m->rfunc1 = (*it)->rootfunc;
m->func_mask |= MenuRFuncMask;
m->func_mask1 |= MenuRFuncMask;
break;
}
}
it = macts.begin();
for (; it != macts.end(); ++it) {
if ((*it)->Comp(s)) {
m->mfunc = (*it)->menufunc;
m->mfunc1 = (*it)->menufunc;
m->func_mask |= MenuMFuncMask;
m->func_mask1 |= MenuMFuncMask;
break;
}
}
if (! (m->wfunc || m->rfunc || m->mfunc)) {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): function `" << s << "' not available" << endl;
continue;
}
}
if (cb) {
if (s) delete [] s; s = NULL;
if (! (s = strwithin(line2, '(', ')', true)))
m->label2 = __m_wastrdup("");
else
m->label2 = __m_wastrdup(s);
if (s) delete [] s; s = NULL;
if ((s = strwithin(line2, '{', '}'))) {
if (*s != '\0') {
m->exec2 = __m_wastrdup(s);
m->func_mask2 |= MenuExecMask;
}
}
if (s) delete [] s; s = NULL;
if ((s = strwithin(line2, '<', '>'))) {
m->sub2 = __m_wastrdup(s);
m->func_mask2 |= MenuSubMask;
}
if (s) delete [] s; s = NULL;
if ((s = strwithin(line2, '"', '"'))) {
tmp_par = par = __m_wastrdup(s);
for (i = 0; *par != '(' && *par != '\0'; par++, i++);
if (*(par++) == '(') {
s[i] = '\0';
for (i = 0; par[i] != ')' && par[i] != '\0'; i++);
if (par[i] == '\0') {
WARNING << "(" << basename(menu_file) << ":" <<
linenr << "): missing ')'" << endl;
delete [] tmp_par;
continue;
}
if (strlen(par)) {
par[i] = '\0';
m->param2 = param_eval(s, par, wascreen);
delete [] tmp_par;
}
}
else
delete [] tmp_par;
it = wacts.begin();
for (; it != wacts.end(); ++it) {
if ((*it)->Comp(s)) {
m->wfunc2 = (*it)->winfunc;
m->func_mask2 |= MenuWFuncMask;
break;
}
}
it = racts.begin();
for (; it != racts.end(); ++it) {
if ((*it)->Comp(s)) {
m->rfunc2 = (*it)->rootfunc;
m->func_mask2 |= MenuRFuncMask;
break;
}
}
it = macts.begin();
for (; it != macts.end(); ++it) {
if ((*it)->Comp(s)) {
m->mfunc2 = (*it)->menufunc;
m->func_mask2 |= MenuMFuncMask;
break;
}
}
if (! (m->wfunc2 || m->rfunc2 || m->mfunc2)) {
WARNING << "(" << basename(menu_file) << ":" << linenr <<
"): function `" << s << "' not available" << endl;
continue;
}
}
}
menu->AddItem(m);
}
if (menu) {
if (menu->item_list.empty()) {
WARNING << "no elements in menu `" << menu->name <<
"'" << endl;
delete menu;
if (s) delete [] s; s = NULL;
return NULL;
}
wascreen->wamenu_list.push_back(menu);
if (s) delete [] s; s = NULL;
return menu;
}
if (s) delete [] s; s = NULL;
return NULL;
}
/**
* @fn StrComp(char *s, ???)
* @brief Constructor for StrComp class
*
* Creates a string comparer object. There is one constructor for each type
* of object you can compare a string to. Objects are: int, WwActionFn,
* RootActionFn, MenuActionFn.
*
* @param s String that match object
* @param ??? Object that match string
*/
StrComp::StrComp(char *s, unsigned long v) { str = s; value = v; type = 0; }
StrComp::StrComp(char *s, WwActionFn a) {
str = s; winfunc = a; type = WindowFuncMask; }
StrComp::StrComp(char *s, RootActionFn ra) {
str = s; rootfunc = ra; type = RootFuncMask; }
StrComp::StrComp(char *s, MenuActionFn ma) {
str = s; menufunc = ma; type = MenuFuncMask; }
/**
* @fn Comp(char *s)
* @brief Tries to match object with string
*
* Tries to match string s with object string, if they match we return true
* otherwise false.
*
* @param s String we want to try matching with
*
* @return True if match, otherwise false
*/
bool StrComp::Comp(char *s) {
if (! strcasecmp(s, str))
return true;
return false;
}
/**
* @fn strtrim(char *s)
* @brief Trims a string
*
* Removes leading and trailing spaces, tabs and newlines.
*
* @param s String we want to trim
*
* @return Trimmed string
*/
char *strtrim(char *s) {
for (; *s != '\0' && *s == ' ' || *s == '\t' || *s == '\n'; s++);
if (*s == '\0') return s;
while (s[strlen(s) - 1] == ' ' ||
s[strlen(s) - 1] == '\t' ||
s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = '\0';
return s;
}
/**
* @fn strwithin(char *s, char c1, char c2, bool eval_env)
* @brief Return string between to characters
*
* Duplicates and returns the string between c1 and c2 if c1 and c2 was
* found. Possible environment variables are evaluated if eval_env
* parameter is true. All special character sequences are replaced
* with real characters.
*
* @param s String to search for c1 and c2 in
* @param c1 Starting character
* @param c2 Ending character
* @param eval_env True if environment variables should be evaluated
*
* @return String within c1 and c2
*/
char *strwithin(char *s, char c1, char c2, bool eval_env) {
int i, n;
char *str;
char *__m_wastrdup_tmp;
for (i = 0;; i++) {
if (s[i] == '\0') break;
if (s[i] == c1 && (i == 0 || s[i - 1] != '\\')) break;
}
if (s[i] == '\0') return NULL;
for (n = i + 1;; n++) {
if (s[n] == '\0') break;
if (s[n] == c2 && s[n - 1] != '\\') break;
}
if (s[n] == '\0') return NULL;
s[n] = '\0';
str = __m_wastrdup(s + i + 1);
s[n] = c2;
if (eval_env) {
str = environment_expansion(str);
}
for (i = 0; str[i] != '\0'; i++) {
if (str[i] == '\\' &&
(str[i + 1] == '$' ||
str[i + 1] == '\\' ||
str[i + 1] == '"' ||
str[i + 1] == '(' ||
str[i + 1] == ')' ||
str[i + 1] == '[' ||
str[i + 1] == ']' ||
str[i + 1] == '{' ||
str[i + 1] == '}' ||
str[i + 1] == '<' ||
str[i + 1] == '>')) {
for (n = 1; str[i + n] != '\0'; n++)
str[i + n - 1] = str[i + n];
str[i + n - 1] = '\0';
}
}
return str;
}
/**
* @fn environment_expansion(char *s)
* @brief Expand '~' and environment variables
*
* Replaces all '~' characters with HOME environment variable and all
* $ENVIRONMENT_VARIABLE with environment variable value.
*
* @param s String to expand
* @return Pointer to expanded string
*/
char *environment_expansion(char *s) {
char *tmp, *env, *env_name;
int i, tmp_char;
for (i = 0; s[i] != '\0'; i++) {
switch (s[i]) {
case '\\':
if (s[i + 1] != '\0') i++;
break;
case '$':
if (IS_ENV_CHAR(s[i + 1])) {
s[i] = '\0';
env_name = &s[++i];
for (; IS_ENV_CHAR(s[i]); i++);
tmp_char = s[i];
s[i] = '\0';
if ((env = getenv(env_name)) == NULL) env = "";
s[i] = tmp_char;
tmp = new char[strlen(s) + strlen(env) +
strlen(&s[i]) + 1];
sprintf(tmp, "%s%s%s", s, env, &s[i]);
i = strlen(s) + strlen(env);
delete [] s;
s = tmp;
}
break;
case '~':
s[i] = '\0';
if ((env = getenv("HOME")) == NULL) env = "~";
tmp = new char[strlen(s) + strlen(env) +
strlen(&s[i + 1]) + 1];
sprintf(tmp, "%s%s%s", s, env, &s[i + 1]);
i = strlen(s) + strlen(env);
delete [] s;
s = tmp;
break;
}
}
return s;
}
/**
* @fn param_eval(char *action, char *param, WaScreen *wascreen)
* @brief Evaluate parameter string
*
* Replaces special parameter characters and returns new parameter string.
*
* @param action Action name for parameter
* @param param Parameter string
* @param wascreen WaScreen object pointer
*
* @return New parameter
*/
char *param_eval(char *action, char *param, WaScreen *wascreen) {
char *tmp, *p;
int i;
char *__m_wastrdup_tmp;
if (! param) return param;
p = __m_wastrdup(param);
if ((! strncasecmp(action, "viewport", 8)) ||
(! strncasecmp(action, "moveresize", 10))) {
for (i = 0; p[i] != '\0'; i++) {
if (p[i] == 'W' || p[i] == 'w') {
tmp = new char[strlen(p) + 5];
p[i] = '\0';
sprintf(tmp, "%s%d%s", p, wascreen->width, &p[i + 1]);
delete [] p;
p = tmp;
}
else if (p[i] == 'H' || p[i] == 'h') {
tmp = new char[strlen(p) + 5];
p[i] = '\0';
sprintf(tmp, "%s%d%s", p, wascreen->height, &p[i + 1]);
delete [] p;
p = tmp;
}
}
}
return p;
}
syntax highlighted by Code2HTML, v. 0.9.1