// // Config.cc for pekwm // Copyright (C) 2002-2005 Claes Nasten // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "../config.h" #include "Config.hh" #include "Util.hh" #include "PScreen.hh" // for DPY in keyconfig code #include #include #include extern "C" { #include #include #include } using std::cerr; using std::endl; using std::string; using std::list; using std::map; using std::vector; using std::pair; using std::ifstream; using std::ofstream; Config* Config::_instance = NULL; const int FRAME_MASK = FRAME_OK|FRAME_BORDER_OK|CLIENT_OK|WINDOWMENU_OK| KEYGRABBER_OK|BUTTONCLICK_OK; const int ANY_MASK = KEYGRABBER_OK|FRAME_OK|FRAME_BORDER_OK|CLIENT_OK|ROOTCLICK_OK| BUTTONCLICK_OK|WINDOWMENU_OK|ROOTMENU_OK|SCREEN_EDGE_OK; //! @brief Constructor for Config class Config::Config(void) : _moveresize_edgeattract(0), _moveresize_edgeresist(0), _moveresize_woattract(0), _moveresize_woresist(0), _moveresize_opaquemove(0), _moveresize_opaqueresize(0), _screen_workspaces(4), _screen_pixmap_cache_size(20),_screen_edge_size(0), _screen_doubleclicktime(250), _screen_showframelist(true), _screen_place_new(true), _screen_focus_new(false), _screen_focus_new_child (true), _screen_placement_row(false), _screen_placement_ltr(true), _screen_placement_ttb(true), _screen_placement_offset_x(0), _screen_placement_offset_y(0), _screen_client_unique_name(true), _screen_client_unique_name_pre(" #"), _screen_client_unique_name_post(""), _menu_select_mask(0), _menu_enter_mask(0), _menu_exec_mask(0), #ifdef HARBOUR _harbour_da_min_s(0), _harbour_da_max_s(0), #ifdef HAVE_XINERAMA _harbour_head_nr(0), #endif // HAVE_XINERAMA #endif // HARBOUR _viewport_cols(1), _viewport_rows(1) { if (_instance != NULL) { throw string("Config, trying to create multiple instances"); } _instance = this; // fill parsing maps _action_map[""] = pair(ACTION_NO, 0); _action_map["FOCUS"] = pair(ACTION_FOCUS, ANY_MASK); _action_map["UNFOCUS"] = pair(ACTION_UNFOCUS, ANY_MASK); _action_map["SET"] = pair(ACTION_SET, ANY_MASK); _action_map["UNSET"] = pair(ACTION_UNSET, ANY_MASK); _action_map["TOGGLE"] = pair(ACTION_TOGGLE, ANY_MASK); _action_map["MAXFILL"] = pair(ACTION_MAXFILL, FRAME_MASK); _action_map["GROWDIRECTION"] = pair(ACTION_GROW_DIRECTION, FRAME_MASK); _action_map["CLOSE"] = pair(ACTION_CLOSE, FRAME_MASK); _action_map["CLOSEFRAME"] = pair(ACTION_CLOSE_FRAME, FRAME_MASK); _action_map["KILL"] = pair(ACTION_KILL, FRAME_MASK); _action_map["RAISE"] = pair(ACTION_RAISE, FRAME_MASK); _action_map["LOWER"] = pair(ACTION_LOWER, FRAME_MASK); _action_map["ACTIVATEORRAISE"] = pair(ACTION_ACTIVATE_OR_RAISE, FRAME_MASK); _action_map["ACTIVATECLIENTREL"] = pair(ACTION_ACTIVATE_CLIENT_REL, FRAME_MASK); _action_map["MOVECLIENTREL"] = pair(ACTION_MOVE_CLIENT_REL, FRAME_MASK); _action_map["ACTIVATECLIENT"] = pair(ACTION_ACTIVATE_CLIENT, FRAME_MASK); _action_map["ACTIVATECLIENTNUM"] = pair(ACTION_ACTIVATE_CLIENT_NUM, KEYGRABBER_OK); _action_map["RESIZE"] = pair(ACTION_RESIZE, BUTTONCLICK_OK|CLIENT_OK|FRAME_OK|FRAME_BORDER_OK); _action_map["MOVE"] = pair(ACTION_MOVE, FRAME_OK|FRAME_BORDER_OK|CLIENT_OK); _action_map["MOVERESIZE"] = pair(ACTION_MOVE_RESIZE, KEYGRABBER_OK); _action_map["GROUPINGDRAG"] = pair(ACTION_GROUPING_DRAG, FRAME_OK|CLIENT_OK); _action_map["WARPTOVIEWPORT"] = pair(ACTION_WARP_TO_VIEWPORT, SCREEN_EDGE_OK); _action_map["WARPTOWORKSPACE"] = pair(ACTION_WARP_TO_WORKSPACE, SCREEN_EDGE_OK); _action_map["MOVETOEDGE"] = pair(ACTION_MOVE_TO_EDGE, KEYGRABBER_OK); _action_map["NEXTFRAME"] = pair(ACTION_NEXT_FRAME, KEYGRABBER_OK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["PREVFRAME"] = pair(ACTION_PREV_FRAME, KEYGRABBER_OK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["NEXTFRAMEMRU"] = pair(ACTION_NEXT_FRAME_MRU, KEYGRABBER_OK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["PREVFRAMEMRU"] = pair(ACTION_PREV_FRAME_MRU, KEYGRABBER_OK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["FOCUSDIRECTIONAL"] = pair(ACTION_FOCUS_DIRECTIONAL, FRAME_MASK); _action_map["ATTACHMARKED"] = pair(ACTION_ATTACH_MARKED, FRAME_MASK); _action_map["ATTACHCLIENTINNEXTFRAME"] = pair(ACTION_ATTACH_CLIENT_IN_NEXT_FRAME, FRAME_MASK); _action_map["ATTACHCLIENTINPREVFRAME"] = pair(ACTION_ATTACH_CLIENT_IN_PREV_FRAME, FRAME_MASK); _action_map["VIEWPORTMOVEXY"] = pair(ACTION_VIEWPORT_MOVE_XY, ANY_MASK); _action_map["VIEWPORTMOVEDRAG"] = pair(ACTION_VIEWPORT_MOVE_DRAG, ANY_MASK); _action_map["VIEWPORTMOVEDIRECTION"] = pair(ACTION_VIEWPORT_MOVE_DIRECTION, ANY_MASK); _action_map["VIEWPORTSCROLL"] = pair(ACTION_VIEWPORT_SCROLL, ANY_MASK); _action_map["VIEWPORTGOTO"] = pair(ACTION_VIEWPORT_GOTO, ANY_MASK); _action_map["FINDCLIENT"] = pair(ACTION_FIND_CLIENT, ANY_MASK); _action_map["DETACH"] = pair(ACTION_DETACH, FRAME_MASK); _action_map["SENDTOWORKSPACE"] = pair(ACTION_SEND_TO_WORKSPACE, ANY_MASK); _action_map["GOTOWORKSPACE"] = pair(ACTION_GOTO_WORKSPACE, ANY_MASK ); _action_map["EXEC"] = pair(ACTION_EXEC, FRAME_MASK|ROOTMENU_OK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["RELOAD"] = pair(ACTION_RELOAD, KEYGRABBER_OK|ROOTMENU_OK); _action_map["RESTART"] = pair(ACTION_RESTART, KEYGRABBER_OK|ROOTMENU_OK); _action_map["RESTARTOTHER"] = pair(ACTION_RESTART_OTHER, KEYGRABBER_OK|ROOTMENU_OK); _action_map["EXIT"] = pair(ACTION_EXIT, KEYGRABBER_OK|ROOTMENU_OK); _action_map["SHOWCMDDIALOG"] = pair(ACTION_SHOW_CMD_DIALOG, KEYGRABBER_OK|ROOTCLICK_OK|SCREEN_EDGE_OK|ROOTMENU_OK|WINDOWMENU_OK); #ifdef MENUS _action_map["SHOWMENU"] = pair(ACTION_SHOW_MENU, FRAME_MASK|ROOTCLICK_OK|SCREEN_EDGE_OK|ROOTMENU_OK|WINDOWMENU_OK); _action_map["HIDEALLMENUS"] = pair(ACTION_HIDE_ALL_MENUS, FRAME_MASK|ROOTCLICK_OK|SCREEN_EDGE_OK); _action_map["SUBMENU"] = pair(ACTION_MENU_SUB, ROOTMENU_OK|WINDOWMENU_OK); _action_map["DYNAMIC"] = pair(ACTION_MENU_DYN, ROOTMENU_OK|WINDOWMENU_OK); #endif // MENUS _placement_map[""] = PLACE_NO; _placement_map["SMART"] = PLACE_SMART; _placement_map["MOUSENOTUNDER"] = PLACE_MOUSE_NOT_UNDER; _placement_map["MOUSECENTERED"] = PLACE_MOUSE_CENTERED; _placement_map["MOUSETOPLEFT"] = PLACE_MOUSE_TOP_LEFT; _placement_map["CENTEREDONPARENT"] = PLACE_CENTERED_ON_PARENT; _edge_map[""] = NO_EDGE; _edge_map["TOPLEFT"] = TOP_LEFT; _edge_map["TOPEDGE"] = TOP_EDGE; _edge_map["TOPCENTEREDGE"] = TOP_CENTER_EDGE; _edge_map["TOPRIGHT"] = TOP_RIGHT; _edge_map["BOTTOMRIGHT"] = BOTTOM_RIGHT; _edge_map["BOTTOMEDGE"] = BOTTOM_EDGE; _edge_map["BOTTOMCENTEREDGE"] = BOTTOM_CENTER_EDGE; _edge_map["BOTTOMLEFT"] = BOTTOM_LEFT; _edge_map["LEFTEDGE"] = LEFT_EDGE; _edge_map["LEFTCENTEREDGE"] = LEFT_CENTER_EDGE; _edge_map["RIGHTEDGE"] = RIGHT_EDGE; _edge_map["RIGHTCENTEREDGE"] = RIGHT_CENTER_EDGE; _edge_map["CENTER"] = CENTER; _raise_map[""] = NO_RAISE; _raise_map["ALWAYSRAISE"] = ALWAYS_RAISE; _raise_map["ENDRAISE"] = END_RAISE; _raise_map["NEVERRAISE"] = NEVER_RAISE; _skip_map[""] = SKIP_NONE; _skip_map["MENUS"] = SKIP_MENUS; _skip_map["FOCUSTOGGLE"] = SKIP_FOCUS_TOGGLE; _skip_map["SNAP"] = SKIP_SNAP; _layer_map[""] = LAYER_NONE; _layer_map["DESKTOP"] = LAYER_DESKTOP; _layer_map["BELOW"] = LAYER_BELOW; _layer_map["NORMAL"] = LAYER_NORMAL; _layer_map["ONTOP"] = LAYER_ONTOP; _layer_map["HARBOUR"] = LAYER_DOCK; _layer_map["ABOVEHARBOUR"] = LAYER_ABOVE_DOCK; _layer_map["MENU"] = LAYER_MENU; _moveresize_map[""] = NO_MOVERESIZE_ACTION; _moveresize_map["MOVEHORIZONTAL"] = MOVE_HORIZONTAL; _moveresize_map["MOVEVERTICAL"] = MOVE_VERTICAL; _moveresize_map["RESIZEHORIZONTAL"] = RESIZE_HORIZONTAL; _moveresize_map["RESIZEVERTICAL"] = RESIZE_VERTICAL; _moveresize_map["MOVESNAP"] = MOVE_SNAP; _moveresize_map["CANCEL"] = MOVE_CANCEL; _moveresize_map["END"] = MOVE_END; _cmddialog_map[""] = CMD_D_NO_ACTION; _cmddialog_map["INSERT"] = CMD_D_INSERT; _cmddialog_map["ERASE"] = CMD_D_REMOVE; _cmddialog_map["CLEAR"] = CMD_D_CLEAR; _cmddialog_map["EXEC"] = CMD_D_EXEC; _cmddialog_map["CLOSE"] = CMD_D_CLOSE; _cmddialog_map["COMPLETE"] = CMD_D_COMPLETE; _cmddialog_map["CURSNEXT"] = CMD_D_CURS_NEXT; _cmddialog_map["CURSPREV"] = CMD_D_CURS_PREV; _cmddialog_map["CURSEND"] = CMD_D_CURS_END; _cmddialog_map["CURSBEGIN"] = CMD_D_CURS_BEGIN; _cmddialog_map["HISTNEXT"] = CMD_D_HIST_NEXT; _cmddialog_map["HISTPREV"] = CMD_D_HIST_PREV; _direction_map[""] = DIRECTION_NO; _direction_map["UP"] = DIRECTION_UP; _direction_map["DOWN"] = DIRECTION_DOWN; _direction_map["LEFT"] = DIRECTION_LEFT; _direction_map["RIGHT"] = DIRECTION_RIGHT; _workspace_change_map[""] = WORKSPACE_NO; _workspace_change_map["LEFT"] = WORKSPACE_LEFT; _workspace_change_map["PREV"] = WORKSPACE_PREV; _workspace_change_map["RIGHT"] = WORKSPACE_RIGHT; _workspace_change_map["NEXT"] = WORKSPACE_NEXT; _workspace_change_map["LAST"] = WORKSPACE_LAST; _borderpos_map[""] = BORDER_NO_POS; _borderpos_map["TOPLEFT"] = BORDER_TOP_LEFT; _borderpos_map["TOP"] = BORDER_TOP; _borderpos_map["TOPRIGHT"] = BORDER_TOP_RIGHT; _borderpos_map["LEFT"] = BORDER_LEFT; _borderpos_map["RIGHT"] = BORDER_RIGHT; _borderpos_map["BOTTOMLEFT"] = BORDER_BOTTOM_LEFT; _borderpos_map["BOTTOM"] = BORDER_BOTTOM; _borderpos_map["BOTTOMRIGHT"] = BORDER_BOTTOM_RIGHT; _mouse_event_map[""] = MOUSE_EVENT_NO; _mouse_event_map["BUTTONPRESS"] = MOUSE_EVENT_PRESS; _mouse_event_map["BUTTONRELEASE"] = MOUSE_EVENT_RELEASE; _mouse_event_map["DOUBLECLICK"] = MOUSE_EVENT_DOUBLE; _mouse_event_map["MOTION"] = MOUSE_EVENT_MOTION; _mouse_event_map["ENTER"] = MOUSE_EVENT_ENTER; _mouse_event_map["LEAVE"] = MOUSE_EVENT_LEAVE; _mouse_event_map["ENTERMOVING"] = MOUSE_EVENT_ENTER_MOVING; _mod_map[""] = 0; _mod_map["NONE"] = 0; _mod_map["SHIFT"] = ShiftMask; _mod_map["CTRL"] = ControlMask; _mod_map["MOD1"] = Mod1Mask; _mod_map["MOD2"] = Mod2Mask; _mod_map["MOD3"] = Mod3Mask; _mod_map["MOD4"] = Mod4Mask; _mod_map["MOD5"] = Mod5Mask; _mod_map["ANY"] = MOD_ANY; _action_state_map[""] = ACTION_STATE_NO; _action_state_map["MAXIMIZED"] = ACTION_STATE_MAXIMIZED; _action_state_map["FULLSCREEN"] = ACTION_STATE_FULLSCREEN; _action_state_map["SHADED"] = ACTION_STATE_SHADED; _action_state_map["STICKY"] = ACTION_STATE_STICKY; _action_state_map["ALWAYSONTOP"] = ACTION_STATE_ALWAYS_ONTOP; _action_state_map["ALWAYSBELOW"] = ACTION_STATE_ALWAYS_BELOW; _action_state_map["DECORBORDER"] = ACTION_STATE_DECOR_BORDER; _action_state_map["DECORTITLEBAR"] = ACTION_STATE_DECOR_TITLEBAR; _action_state_map["ICONIFIED"] = ACTION_STATE_ICONIFIED; _action_state_map["TAGGED"] = ACTION_STATE_TAGGED; _action_state_map["MARKED"] = ACTION_STATE_MARKED; _action_state_map["SKIP"] = ACTION_STATE_SKIP; _action_state_map["CFGDENY"] = ACTION_STATE_CFG_DENY; _action_state_map["TITLE"] = ACTION_STATE_TITLE; _action_state_map["GLOBALGROUPING"] = ACTION_STATE_GLOBAL_GROUPING; _cfg_deny_map["POSITION"] = CFG_DENY_POSITION; _cfg_deny_map["SIZE"] = CFG_DENY_SIZE; _cfg_deny_map["STACKING"] = CFG_DENY_STACKING; _cfg_deny_map["ACTIVEWINDOW"] = CFG_DENY_ACTIVE_WINDOW; _cfg_deny_map["MAXIMIZEDVERT"] = CFG_DENY_STATE_MAXIMIZED_VERT; _cfg_deny_map["MAXIMIZEDHORZ"] = CFG_DENY_STATE_MAXIMIZED_HORZ; _cfg_deny_map["HIDDEN"] = CFG_DENY_STATE_HIDDEN; _cfg_deny_map["FULLSCREEN"] = CFG_DENY_STATE_FULLSCREEN; _cfg_deny_map["ABOVE"] = CFG_DENY_STATE_ABOVE; _cfg_deny_map["BELOW"] = CFG_DENY_STATE_BELOW; #ifdef MENUS _menu_type_map[""] = NO_MENU_TYPE; _menu_type_map["WINDOW"] = WINDOWMENU_TYPE; _menu_type_map["ROOT"] = ROOTMENU_TYPE; _menu_type_map["GOTO"] = GOTOMENU_TYPE; _menu_type_map["GOTOCLIENT"] = GOTOCLIENTMENU_TYPE; _menu_type_map["ICON"] = ICONMENU_TYPE; _menu_type_map["ATTACHCLIENT"] = ATTACH_CLIENT_TYPE; _menu_type_map["ATTACHFRAME"] = ATTACH_FRAME_TYPE; _menu_type_map["ATTACHCLIENTINFRAME"] = ATTACH_CLIENT_IN_FRAME_TYPE; _menu_type_map["ATTACHFRAMEINFRAME"] = ATTACH_FRAME_IN_FRAME_TYPE; _menu_type_map["DECOR"] = DECORMENU_TYPE; _menu_action_map[""] = ACTION_MENU_NEXT; _menu_action_map["NEXTITEM"] = ACTION_MENU_NEXT; _menu_action_map["PREVITEM"] = ACTION_MENU_PREV; _menu_action_map["SELECT"] = ACTION_MENU_SELECT; _menu_action_map["ENTERSUBMENU"] = ACTION_MENU_ENTER_SUBMENU; _menu_action_map["LEAVESUBMENU"] = ACTION_MENU_LEAVE_SUBMENU; _menu_action_map["CLOSE"] = ACTION_CLOSE; #endif // MENUS #ifdef HARBOUR _harbour_placement_map[""] = NO_HARBOUR_PLACEMENT; _harbour_placement_map["TOP"] = TOP; _harbour_placement_map["LEFT"] = LEFT; _harbour_placement_map["RIGHT"] = RIGHT; _harbour_placement_map["BOTTOM"] = BOTTOM; _harbour_orientation_map[""] = NO_ORIENTATION; _harbour_orientation_map["TOPTOBOTTOM"] = TOP_TO_BOTTOM; _harbour_orientation_map["LEFTTORIGHT"] = TOP_TO_BOTTOM; _harbour_orientation_map["BOTTOMTOTOP"] = BOTTOM_TO_TOP; _harbour_orientation_map["RIGHTTOLEFT"] = BOTTOM_TO_TOP; #endif // HARBOUR // fill the mouse action map _mouse_action_map[MOUSE_ACTION_LIST_TITLE_FRAME] = new list; _mouse_action_map[MOUSE_ACTION_LIST_TITLE_OTHER] = new list; _mouse_action_map[MOUSE_ACTION_LIST_CHILD_FRAME] = new list; _mouse_action_map[MOUSE_ACTION_LIST_CHILD_OTHER] = new list; _mouse_action_map[MOUSE_ACTION_LIST_ROOT] = new list; _mouse_action_map[MOUSE_ACTION_LIST_MENU] = new list; _mouse_action_map[MOUSE_ACTION_LIST_OTHER] = new list; _mouse_action_map[MOUSE_ACTION_LIST_EDGE_T] = new list; _mouse_action_map[MOUSE_ACTION_LIST_EDGE_B] = new list; _mouse_action_map[MOUSE_ACTION_LIST_EDGE_L] = new list; _mouse_action_map[MOUSE_ACTION_LIST_EDGE_R] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TL] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_T] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TR] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_L] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_R] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BL] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_B] = new list; _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BR] = new list; } //! @brief Destructor for Config class Config::~Config(void) { _instance = NULL; map* >::iterator it; for (it = _mouse_action_map.begin(); it != _mouse_action_map.end(); ++it) { delete it->second; } } //! @brief Tries to load config_file, ~/.pekwm/config, SYSCONFDIR/config void Config::load(const std::string &config_file) { CfgParser cfg; bool success = false; string file_success; _config_file = config_file; // Try loading command line specified file. if (_config_file.size ()) { success = cfg.parse (config_file, CfgParserSource::SOURCE_FILE); if (success) file_success = config_file; } // Try loading ~/.pekwm/config if (!success) { _config_file = string(getenv("HOME")) + string("/.pekwm/config"); success = cfg.parse (_config_file, CfgParserSource::SOURCE_FILE); if (success) file_success = _config_file; } // Copy cfg files to ~/.pekwm and then try loading global config if (!success) { copyConfigFiles(); _config_file = string(SYSCONFDIR "/config"); success = cfg.parse (_config_file, CfgParserSource::SOURCE_FILE); if (success) file_success = _config_file; } if (!success) { cerr << " *** WARNING: unable to load configuration files!" << endl; return; } // Update PEKWM_CONFIG_FILE environment if needed ( to reflect active file ) char *cfg_env = getenv("PEKWM_CONFIG_FILE"); if (!cfg_env || (strcmp(cfg_env, file_success.c_str()) != 0)) setenv("PEKWM_CONFIG_FILE", file_success.c_str(), 1); string o_file_mouse; // temporary filepath for mouseconfig CfgParser::Entry *op_section, *op_value, *op_sub, *op_sub_2; // Get other config files dests. op_section = cfg.get_entry_root ()->find_section ("FILES"); if (op_section) { op_section = op_section->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyPath ("KEYS", _files_keys, SYSCONFDIR "/keys")); o_key_list.push_back (new CfgParserKeyPath ("MOUSE", o_file_mouse, SYSCONFDIR "/mouse")); o_key_list.push_back (new CfgParserKeyPath ("MENU", _files_menu, SYSCONFDIR "/menu")); o_key_list.push_back (new CfgParserKeyPath ("START", _files_start, SYSCONFDIR "/start")); o_key_list.push_back (new CfgParserKeyPath ("AUTOPROPS", _files_autoprops, SYSCONFDIR "/autoproperties")); o_key_list.push_back (new CfgParserKeyPath ("THEME", _files_theme, DATADIR "/pekwm/themes/default/theme")); op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } // Parse moving / resizing options. op_section = cfg.get_entry_root ()->find_section ("MOVERESIZE"); if (op_section) { op_section = op_section->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyInt ("EDGEATTRACT", _moveresize_edgeattract, 0, 0)); o_key_list.push_back (new CfgParserKeyInt ("EDGERESIST", _moveresize_edgeresist, 0, 0)); o_key_list.push_back (new CfgParserKeyInt ("WINDOWATTRACT", _moveresize_woattract, 0, 0)); o_key_list.push_back (new CfgParserKeyInt ("WINDOWRESIST", _moveresize_woresist, 0, 0)); o_key_list.push_back (new CfgParserKeyBool ("OPAQUEMOVE", _moveresize_opaquemove)); o_key_list.push_back (new CfgParserKeyBool ("OPAQUERESIZE", _moveresize_opaqueresize)); op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } // Screen, important stuff such as number of workspaces op_section = cfg.get_entry_root ()->find_section ("SCREEN"); if (op_section) { op_section = op_section->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyInt ("WORKSPACES", _screen_workspaces, 4, 1)); o_key_list.push_back (new CfgParserKeyInt ("PIXMAPCACHESIZE", _screen_pixmap_cache_size)); o_key_list.push_back (new CfgParserKeyInt ("EDGESIZE", _screen_edge_size, 0, 0)); o_key_list.push_back (new CfgParserKeyInt ("DOUBLECLICKTIME", _screen_doubleclicktime, 250, 0)); o_key_list.push_back (new CfgParserKeyString ("TRIMTITLE", _screen_trim_title)); o_key_list.push_back (new CfgParserKeyBool ("SHOWFRAMELIST", _screen_showframelist)); o_key_list.push_back (new CfgParserKeyBool ("SHOWSTATUSWINDOW", _screen_show_status_window)); o_key_list.push_back (new CfgParserKeyBool ("PLACENEW", _screen_place_new)); o_key_list.push_back (new CfgParserKeyBool ("FOCUSNEW", _screen_focus_new)); o_key_list.push_back (new CfgParserKeyBool ("FOCUSNEWCHILD", _screen_focus_new_child, true)); op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); op_sub = op_section->find_section ("VIEWPORTS"); if (op_sub) { op_sub = op_sub->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyInt ("COLUMNS", _viewport_cols, 1, 1)); o_key_list.push_back (new CfgParserKeyInt ("ROWS", _viewport_rows, 1, 1)); op_sub->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } op_sub = op_section->find_section ("PLACEMENT"); if (op_sub) { op_sub = op_sub->get_section (); op_value = op_sub->find_entry ("MODEL"); if (op_value) { _screen_placementmodels.clear (); vector models; if (Util::splitString (op_value->get_value (), models, " \t")) { vector::iterator it( models.begin()); for (; it != models.end(); ++it) _screen_placementmodels.push_back(ParseUtil::getValue (*it, _placement_map)); } } op_sub_2 = op_sub->find_section ("SMART"); if (op_sub_2) { op_sub_2 = op_sub_2->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyBool ("ROW", _screen_placement_row)); o_key_list.push_back (new CfgParserKeyBool ("LEFTTORIGHT", _screen_placement_ltr)); o_key_list.push_back (new CfgParserKeyBool ("TOPTOBOTTOM", _screen_placement_ttb)); o_key_list.push_back (new CfgParserKeyInt ("OFFSETX", _screen_placement_offset_x, 0, 0)); o_key_list.push_back (new CfgParserKeyInt ("OFFSETY", _screen_placement_offset_y, 0, 0)); // Do the parsing op_sub_2->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } } if (!_screen_placementmodels.size()) _screen_placementmodels.push_back(PLACE_MOUSE_CENTERED); op_sub = op_section->find_section ("UNIQUENAMES"); if (op_sub) { op_sub = op_sub->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyBool ("SETUNIQUE", _screen_client_unique_name)); o_key_list.push_back (new CfgParserKeyString ("PRE", _screen_client_unique_name_pre)); o_key_list.push_back (new CfgParserKeyString ("POST", _screen_client_unique_name_post)); op_sub->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } } op_section = cfg.get_entry_root ()->find_section ("MENU"); if (op_section) { op_section = op_section->get_section (); list o_key_list; string o_value_select, o_value_enter, o_value_exec; o_key_list.push_back (new CfgParserKeyString ("SELECT", o_value_select, "MOTION", 0)); o_key_list.push_back (new CfgParserKeyString ("ENTER", o_value_enter, "BUTTONPRESS", 0)); o_key_list.push_back (new CfgParserKeyString ("EXEC", o_value_exec, "BUTTONRELEASE", 0)); op_section->parse_key_values (o_key_list.begin (), o_key_list. end()); _menu_select_mask = getMenuMask (o_value_select); _menu_enter_mask = getMenuMask (o_value_enter); _menu_exec_mask = getMenuMask (o_value_exec); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } #ifdef HARBOUR op_section = cfg.get_entry_root ()->find_section ("HARBOUR"); if (op_section) { op_section = op_section->get_section (); list o_key_list; string o_value_placement, o_value_orientation; o_key_list.push_back (new CfgParserKeyBool ("ONTOP", _harbour_ontop)); o_key_list.push_back (new CfgParserKeyBool ("MAXIMIZEOVER", _harbour_maximize_over)); #ifdef HAVE_XINERAMA o_key_list.push_back (new CfgParserKeyInt ("HEAD", _harbour_head_nr, 0, 0)); #endif // HAVE_XINERAMA o_key_list.push_back (new CfgParserKeyString ("PLACEMENT", o_value_placement, "RIGHT", 0)); o_key_list.push_back (new CfgParserKeyString ("ORIENTATION", o_value_orientation, "TOPTOBOTTOM", 0)); op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); _harbour_placement = ParseUtil::getValue(o_value_placement, _harbour_placement_map); _harbour_orientation = ParseUtil::getValue(o_value_orientation, _harbour_orientation_map); if (_harbour_placement == NO_HARBOUR_PLACEMENT) _harbour_placement = TOP; if (_harbour_orientation == NO_ORIENTATION) _harbour_orientation = TOP_TO_BOTTOM; op_sub = op_section->find_section ("DOCKAPP"); if (op_sub) { op_sub = op_sub->get_section (); list o_key_list; o_key_list.push_back (new CfgParserKeyInt ("SIDEMIN", _harbour_da_min_s, 64, 0)); o_key_list.push_back (new CfgParserKeyInt ("SIDEMAX", _harbour_da_max_s, 64, 0)); op_sub->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); } } #endif // HARBOUR // Load the mouse configuration loadMouseConfig(o_file_mouse); } //! @brief ActionType Config::getAction(const std::string &name, uint mask) { pair val(ParseUtil::getValue >(name, _action_map)); if ((val.first != ACTION_NO) && (val.second&mask)) { return val.first; } return ACTION_NO; } //! @brief bool Config::parseKey(const std::string &key_string, uint &mod, uint &key) { // used for parsing static vector tok; static vector::iterator it; static uint num; // chop the string up separating mods and the end key/button tok.clear(); if (Util::splitString(key_string, tok, " \t")) { num = tok.size() - 1; if ((tok[num].size() > 1) && (tok[num][0] == '#')) { key = strtol(tok[num].c_str() + 1, NULL, 10); } else { key = XKeysymToKeycode(PScreen::instance()->getDpy(), XStringToKeysym(tok[num].c_str())); if (strcasecmp(tok[num].c_str(), "ANY") == 0) { key = 0; // FIXME: for now, but there's no XK_Any? } } // if the last token isn't an key/button, the action isn't valid if ((key != 0) || (strcasecmp(tok[num].c_str(), "ANY") == 0)) { tok.pop_back(); // remove the key/button // add the modifier mod = 0; for (it = tok.begin(); it != tok.end(); ++it) { mod |= getMod(*it); } return true; } } return false; } bool Config::parseButton(const std::string &button_string, uint &mod, uint &button) { // used for parsing static vector tok; static vector::iterator it; // chop the string up separating mods and the end key/button tok.clear(); if (Util::splitString(button_string, tok, " \t")) { // if the last token isn't an key/button, the action isn't valid button = getMouseButton(tok[tok.size() - 1]); if (button != BUTTON_NO) { tok.pop_back(); // remove the key/button // add the modifier mod = 0; uint tmp_mod; for (it = tok.begin(); it != tok.end(); ++it) { tmp_mod = getMod(*it); if (tmp_mod == MOD_ANY) { mod = MOD_ANY; break; } else { mod |= tmp_mod; } } return true; } } return false; } bool Config::parseAction(const std::string &action_string, Action &action, uint mask) { static vector tok; // chop the string up separating the action and parameters tok.clear(); if (Util::splitString(action_string, tok, " \t", 2)) { action.setAction(getAction(tok[0], mask)); if (action.getAction() != ACTION_NO) { if (tok.size() == 2) { // we got enough tok for a parameter switch (action.getAction()) { case ACTION_EXEC: case ACTION_RESTART_OTHER: case ACTION_FIND_CLIENT: #ifdef MENUS case ACTION_MENU_DYN: #endif // MENUS action.setParamS(tok[1]); break; case ACTION_ACTIVATE_CLIENT_REL: case ACTION_MOVE_CLIENT_REL: action.setParamI(0, strtol(tok[1].c_str(), NULL, 10)); break; case ACTION_SET: case ACTION_UNSET: case ACTION_TOGGLE: parseActionState(action, tok[1]); break; case ACTION_MAXFILL: if ((Util::splitString(tok[1], tok, " \t", 2)) == 2) { action.setParamI(0, Util::isTrue(tok[tok.size() - 2])); action.setParamI(1, Util::isTrue(tok[tok.size() - 1])); } else { cerr << "*** WARNING: Missing argument to MaxFill." << endl; } break; case ACTION_GROW_DIRECTION: action.setParamI(0, ParseUtil::getValue(tok[1], _direction_map)); break; case ACTION_ACTIVATE_CLIENT_NUM: action.setParamI(0, strtol(tok[1].c_str(), NULL, 10) - 1); if (action.getParamI(0) < 0) { cerr << "*** WARNING: Negative number to ActivateClientNum." << endl; action.setParamI(0, 0); } break; case ACTION_WARP_TO_WORKSPACE: case ACTION_SEND_TO_WORKSPACE: case ACTION_GOTO_WORKSPACE: action.setParamI(0, ParseUtil::getValue(tok[1], _workspace_change_map)); if (static_cast(action.getParamI(0)) == WORKSPACE_NO) { action.setParamI(0, strtol(tok[1].c_str(), NULL, 10) - 1); if (action.getParamI(0) < 0) { action.setParamI(0, 0); } } break; case ACTION_GROUPING_DRAG: action.setParamI(0, Util::isTrue(tok[1])); break; case ACTION_MOVE_TO_EDGE: action.setParamI(0, ParseUtil::getValue(tok[1], _edge_map)); break; case ACTION_NEXT_FRAME: case ACTION_NEXT_FRAME_MRU: case ACTION_PREV_FRAME: case ACTION_PREV_FRAME_MRU: action.setParamI(0, ParseUtil::getValue(tok[1], _raise_map)); break; case ACTION_FOCUS_DIRECTIONAL: if ((Util::splitString(tok[1], tok, " \t", 2)) == 2) { action.setParamI(0, ParseUtil::getValue(tok[tok.size() - 2], _direction_map)); action.setParamI(1, Util::isTrue(tok[tok.size() - 1])); // raise? } else { action.setParamI(0, ParseUtil::getValue(tok[1], _direction_map)); action.setParamI(1, true); // default to raise } break; case ACTION_RESIZE: action.setParamI(0, ParseUtil::getValue(tok[1], _borderpos_map)); break; case ACTION_WARP_TO_VIEWPORT: case ACTION_VIEWPORT_MOVE_DIRECTION: action.setParamI(0, ParseUtil::getValue(tok[1], _direction_map)); break; case ACTION_VIEWPORT_SCROLL: case ACTION_VIEWPORT_MOVE_XY: if ((Util::splitString(tok[1], tok, " \t", 2)) == 2) { action.setParamI(0, strtol(tok[tok.size() - 2].c_str(), NULL, 10)); action.setParamI(1, strtol(tok[tok.size() - 1].c_str(), NULL, 10)); } break; case ACTION_VIEWPORT_GOTO: if ((Util::splitString(tok[1], tok, " \t", 2)) == 2) { action.setParamI(0, strtol(tok[tok.size() - 2].c_str(), NULL, 10) - 1); action.setParamI(1, strtol(tok[tok.size() - 1].c_str(), NULL, 10) - 1); } break; case ACTION_RAISE: case ACTION_LOWER: if ((Util::splitString(tok[1], tok, " \t", 1)) == 1) { action.setParamI(0, Util::isTrue(tok[tok.size() - 1])); } else { action.setParamI(0, false); } break; #ifdef MENUS case ACTION_SHOW_MENU: if ((Util::splitString(tok[1], tok, " \t", 2)) == 2) { action.setParamI(0, ParseUtil::getValue(tok[tok.size() - 2], _menu_type_map)); action.setParamI(1, Util::isTrue(tok[tok.size() - 1])); } else { action.setParamI(0, ParseUtil::getValue(tok[1], _menu_type_map)); action.setParamI(1, false); // Default to non-sticky } break; #endif // MENUS default: // do nothing break; } } else { switch (action.getAction()) { case ACTION_MAXFILL: action.setParamI(0, 1); action.setParamI(1, 1); break; default: // do nothing break; } } return true; } } return false; } //! @brief bool Config::parseActionState(Action &action, const std::string &as_action) { static vector tok; // chop the string up separating the action and parameters tok.clear(); if (Util::splitString(as_action, tok, " \t", 2)) { action.setParamI(0, ParseUtil::getValue(tok[0], _action_state_map)); if (action.getParamI(0) != ACTION_STATE_NO) { if (tok.size() == 2) { // we got enough tok for a parameter switch (action.getParamI(0)) { case ACTION_STATE_MAXIMIZED: Util::splitString(tok[1], tok, " \t", 2); if (tok.size() == 4) { action.setParamI(1, Util::isTrue(tok[2])); action.setParamI(2, Util::isTrue(tok[3])); } else { cerr << "*** WARNING: Missing argument to Maximized." << endl; } break; case ACTION_STATE_TAGGED: action.setParamI(1, Util::isTrue(tok[1])); break; case ACTION_STATE_SKIP: action.setParamI(1, getSkip(tok[1])); break; case ACTION_STATE_CFG_DENY: action.setParamI(1, getCfgDeny(tok[1])); break; case ACTION_STATE_DECOR: case ACTION_STATE_TITLE: action.setParamS(tok[1]); break; }; } else { switch (action.getParamI(0)) { case ACTION_STATE_MAXIMIZED: action.setParamI(1, 1); action.setParamI(2, 1); break; default: // do nothing break; } } return true; } } return false; } //! @brief bool Config::parseActions(const std::string &action_string, ActionEvent &ae, uint mask) { static vector tok; static vector::iterator it; static Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions tok.clear(); if (Util::splitString(action_string, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseAction(*it, action, mask)) { ae.action_list.push_back(action); action.setParamS(""); } } return true; } return false; } //! @brief bool Config::parseActionEvent(CfgParser::Entry *op_section, ActionEvent &ae, uint mask, bool button) { CfgParser::Entry *op_value; string o_button = op_section->get_value (); if (!o_button.size()) { if ((ae.type == MOUSE_EVENT_ENTER) || (ae.type == MOUSE_EVENT_LEAVE)) o_button = "1"; else return false; } bool ok; if (button) ok = parseButton (o_button, ae.mod, ae.sym); else ok = parseKey (o_button, ae.mod, ae.sym); op_value = op_section->get_section ()->find_entry ("ACTIONS"); if (ok && op_value) return parseActions (op_value->get_value (), ae, mask); return false; } //! @brief bool Config::parseMoveResizeAction(const std::string &action_string, Action &action) { static vector tok; // Chop the string up separating the actions. tok.clear(); if (Util::splitString(action_string, tok, " \t", 2)) { action.setAction(ParseUtil::getValue(tok[0], _moveresize_map)); if (action.getAction() != NO_MOVERESIZE_ACTION) { if (tok.size() == 2) { // we got enough tok for a paremeter switch (action.getAction()) { case MOVE_HORIZONTAL: case MOVE_VERTICAL: case RESIZE_HORIZONTAL: case RESIZE_VERTICAL: case MOVE_SNAP: action.setParamI(0, strtol(tok[1].c_str(), NULL, 10)); break; default: // Do nothing. break; } } return true; } } return false; } //! @brief bool Config::parseMoveResizeActions(const std::string &action_string, ActionEvent& ae) { static vector tok; static vector::iterator it; static Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions tok.clear(); if (Util::splitString(action_string, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseMoveResizeAction(*it, action)) { ae.action_list.push_back(action); action.setParamS(""); } } return true; } return false; } //! @brief Parses MoveResize Event. bool Config::parseMoveResizeEvent(CfgParser::Entry *op_section, ActionEvent& ae) { CfgParser::Entry *op_value; if (!op_section->get_value ().size ()) return false; if (parseKey (op_section->get_value (), ae.mod, ae.sym)) { op_value = op_section->get_section ()->find_entry ("ACTIONS"); if (op_value) return parseMoveResizeActions (op_value->get_value (), ae); } return false; } //! @brief bool Config::parseCmdDialogAction(const std::string &val, Action &action) { action.setAction(ParseUtil::getValue(val, _cmddialog_map)); return (action.getAction() != CMD_D_NO_ACTION); } //! @brief bool Config::parseCmdDialogActions(const std::string &actions, ActionEvent &ae) { static vector tok; static vector::iterator it; static Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions tok.clear(); if (Util::splitString(actions, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseCmdDialogAction(*it, action)) { ae.action_list.push_back(action); } } return true; } return false; } //! @brief Parses CmdDialog Event. bool Config::parseCmdDialogEvent (CfgParser::Entry *op_section, ActionEvent &ae) { CfgParser::Entry *op_value; if (!op_section->get_value ().size ()) return false; if (parseKey (op_section->get_value (), ae.mod, ae.sym)) { op_value = op_section->get_section ()->find_entry ("ACTIONS"); if (op_value) return parseCmdDialogActions(op_value->get_value (), ae); } return false; } //! @brief uint Config::getMenuMask (const std::string &mask) { uint mask_return = 0, val; vector tok; Util::splitString (mask, tok, " \t"); vector::iterator it (tok.begin ()); for (; it != tok.end(); ++it) { val = ParseUtil::getValue (*it, _mouse_event_map); if (val < MOUSE_EVENT_ENTER) mask_return |= val; } return mask_return; } #ifdef MENUS //! @brief bool Config::parseMenuAction(const std::string &action_string, Action &action) { static vector tok; // chop the string up separating the actions tok.clear(); if (Util::splitString(action_string, tok, " \t", 2)) { action.setAction(ParseUtil::getValue(tok[0], _menu_action_map)); if (action.getAction() != ACTION_NO) { return true; } } return false; } //! @brief bool Config::parseMenuActions(const std::string &actions, ActionEvent &ae) { static vector tok; static vector::iterator it; static Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions tok.clear(); if (Util::splitString(actions, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseMenuAction(*it, action)) { ae.action_list.push_back(action); action.setParamS(""); } } return true; } return false; } //! @brief Parses MenuEvent. bool Config::parseMenuEvent (CfgParser::Entry *op_section, ActionEvent& ae) { CfgParser::Entry *op_value; if (!op_section->get_value ().size ()) return false; if (parseKey (op_section->get_value (), ae.mod, ae.sym)) { op_value = op_section->get_section ()->find_entry ("ACTIONS"); if (op_value) return parseMenuActions (op_value->get_value (), ae); } return false; } #endif // MENUS //! @brief uint Config::getMouseButton(const std::string &button) { uint btn; if (button.size() == 1) { // it's a button btn = unsigned(strtol(button.c_str(), NULL, 10)); } else if (strcasecmp(button.c_str(), "ANY") == 0) { // any button btn = BUTTON_ANY; } else { btn = BUTTON_NO; } if (btn > BUTTON_NO) { btn = BUTTON_NO; } return btn; } //! @brief Populates the ~/.pekwm/ dir with config files void Config::copyConfigFiles(void) { string cfg_dir = getenv("HOME") + string("/.pekwm"); string cfg_file = cfg_dir + string("/config"); string keys_file = cfg_dir + string("/keys"); string mouse_file = cfg_dir + string("/mouse"); string menu_file = cfg_dir + string("/menu"); string autoprops_file = cfg_dir + string("/autoproperties"); string start_file = cfg_dir + string("/start"); string vars_file = cfg_dir + string("/vars"); bool cp_config, cp_keys, cp_mouse, cp_menu; bool cp_autoprops, cp_start, cp_vars; cp_config = cp_keys = cp_mouse = cp_menu = false; cp_autoprops = cp_start = cp_vars = false; struct stat stat_buf; // check and see if we allready have a ~/.pekwm/ directory if (stat(cfg_dir.c_str(), &stat_buf) == 0) { // is it a dir or file? if (!S_ISDIR(stat_buf.st_mode)) { cerr << cfg_dir << " allready exists and isn't a directory" << endl << "Can't copy config files !" << endl; return; } // we allready have a directory, see if it's writeable and executable bool cfg_dir_ok = false; if (getuid() == stat_buf.st_uid) { if ((stat_buf.st_mode&S_IWUSR) && (stat_buf.st_mode&(S_IXUSR))) { cfg_dir_ok = true; } } if (! cfg_dir_ok) { if (getgid() == stat_buf.st_gid) { if ((stat_buf.st_mode&S_IWGRP) && (stat_buf.st_mode&(S_IXGRP))) { cfg_dir_ok = true; } } } if (!cfg_dir_ok) { if (!(stat_buf.st_mode&S_IWOTH) || !(stat_buf.st_mode&(S_IXOTH))) { cerr << "You don't have the rights to add files to the: " << cfg_dir << " directory! Therefor I can't copy the config files!" << endl; return; } } // we apperently could write and exec that dir, now see if we have any // files in it if (stat(cfg_file.c_str(), &stat_buf)) cp_config = true; if (stat(keys_file.c_str(), &stat_buf)) cp_keys = true; if (stat(mouse_file.c_str(), &stat_buf)) cp_mouse = true; if (stat(menu_file.c_str(), &stat_buf)) cp_menu = true; if (stat(autoprops_file.c_str(), &stat_buf)) cp_autoprops = true; if (stat(start_file.c_str(), &stat_buf)) cp_start = true; if (stat(vars_file.c_str(), &stat_buf)) cp_vars = true; } else { // we didn't have a ~/.pekwm directory allready, lets create one if (mkdir(cfg_dir.c_str(), 0700)) { cerr << "Can't create " << cfg_dir << " directory!" << endl; cerr << "Can't copy config files !" << endl; return; } cp_config = cp_keys = cp_mouse = cp_menu = true; cp_autoprops = cp_start = cp_vars = true; } if (cp_config) copyTextFile(SYSCONFDIR "/config", cfg_file); if (cp_keys) copyTextFile(SYSCONFDIR "/keys", keys_file); if (cp_mouse) copyTextFile(SYSCONFDIR "/mouse", mouse_file); if (cp_menu) copyTextFile(SYSCONFDIR "/menu", menu_file); if (cp_autoprops) copyTextFile(SYSCONFDIR "/autoproperties", autoprops_file); if (cp_start) copyTextFile(SYSCONFDIR "/start", start_file); if (cp_vars) copyTextFile(SYSCONFDIR "/vars", vars_file); } //! @brief Copies a single text file. void Config::copyTextFile(const std::string &from, const std::string &to) { if ((from.length() == 0) || (to.length() == 0)) { return; } ifstream stream_from(from.c_str()); if (stream_from.good() == false) { cerr << __FILE__ << "@" << __LINE__ << ": " << "Can't copy: " << from << " to: " << to << endl << "Shutting down" << endl; exit(1); } ofstream stream_to(to.c_str()); if (stream_to.good() == false) { cerr << __FILE__ << "@" << __LINE__ << ": " << "Can't copy: " << from << " to: " << to << endl; } stream_to << stream_from.rdbuf(); } //! @brief Parses the Section for mouse actions. void Config::loadMouseConfig(const std::string &file) { if (!file.size()) return; CfgParser mouse_cfg; bool success = mouse_cfg.parse (file, CfgParserSource::SOURCE_FILE); if (!success) success = mouse_cfg.parse (string(SYSCONFDIR "/mouse"), CfgParserSource::SOURCE_FILE); if (!success) return; // Make sure old actions get unloaded. map* >::iterator it; for (it = _mouse_action_map.begin (); it != _mouse_action_map.end (); ++it) it->second->clear (); CfgParser::Entry *op_section, *op_sub; op_section = mouse_cfg.get_entry_root ()->find_section ("FRAMETITLE"); if (op_section) { parseButtons (op_section, _mouse_action_map[MOUSE_ACTION_LIST_TITLE_FRAME], FRAME_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("OTHERTITLE"); if (op_section) { parseButtons(op_section, _mouse_action_map[MOUSE_ACTION_LIST_TITLE_OTHER], FRAME_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("CLIENT"); if (op_section) { parseButtons (op_section, _mouse_action_map[MOUSE_ACTION_LIST_CHILD_FRAME], CLIENT_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("ROOT"); if (op_section) { parseButtons(op_section, _mouse_action_map[MOUSE_ACTION_LIST_ROOT], ROOTCLICK_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("MENU"); if (op_section) { parseButtons (op_section, _mouse_action_map[MOUSE_ACTION_LIST_MENU], FRAME_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("OTHER"); if (op_section) { parseButtons (op_section, _mouse_action_map[MOUSE_ACTION_LIST_OTHER], FRAME_OK); } op_section = mouse_cfg.get_entry_root ()->find_section ("SCREENEDGE"); if (op_section) { op_section = op_section->get_section (); uint pos; for (op_sub = op_section->get_section_next (); op_sub != NULL; op_sub = op_sub->get_section_next ()) { pos = ParseUtil::getValue(op_sub->get_name (), _direction_map); if (pos != SCREEN_EDGE_NO) parseButtons (op_sub, getEdgeListFromPosition (pos), SCREEN_EDGE_OK); } } op_section = mouse_cfg.get_entry_root ()->find_section ("BORDER"); if (op_section) { op_section = op_section->get_section (); uint pos; for (op_sub = op_section->get_section_next (); op_sub; op_sub = op_sub->get_section_next ()) { pos = ParseUtil::getValue(op_sub->get_name(), _borderpos_map); if (pos != BORDER_NO_POS) parseButtons(op_sub, getBorderListFromPosition (pos), FRAME_BORDER_OK); } } } //! @brief Parses mouse config section, like FRAME void Config::parseButtons(CfgParser::Entry *op_section, std::list* mouse_list, ActionOk action_ok) { if (!op_section || !mouse_list) return; op_section = op_section->get_section (); ActionEvent ae; CfgParser::Entry *op_value; while ((op_section = op_section->get_section_next ()) != NULL) { ae.type = ParseUtil::getValue(op_section->get_name (), _mouse_event_map); if (ae.type == MOUSE_EVENT_NO) continue; if (ae.type == MOUSE_EVENT_MOTION) { op_value = op_section->get_section ()->find_entry ("THRESHOLD"); if (op_value) ae.threshold = strtol (op_value->get_value ().c_str (), NULL, 10); else ae.threshold = 0; } if (parseActionEvent (op_section, ae, action_ok, true)) mouse_list->push_back(ae); } } // frame border configuration list* Config::getBorderListFromPosition(uint pos) { list *ret = NULL; switch (pos) { case BORDER_TOP_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TL]; break; case BORDER_TOP: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_T]; break; case BORDER_TOP_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TR]; break; case BORDER_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_L]; break; case BORDER_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_R]; break; case BORDER_BOTTOM_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BL]; break; case BORDER_BOTTOM: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_B]; break; case BORDER_BOTTOM_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BR]; break; } return ret; } list* Config::getEdgeListFromPosition(uint pos) { list *ret = NULL; switch (pos) { case SCREEN_EDGE_TOP: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_T]; break; case SCREEN_EDGE_BOTTOM: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_B]; break; case SCREEN_EDGE_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_L]; break; case SCREEN_EDGE_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_R]; break; }; return ret; }