wmi

git clone git://oldgit.suckless.org/wmi/
Log | Files | Refs | LICENSE

main.cpp (14235B)


      1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us>
      2 // See LICENSE for license details.
      3 
      4 #include "config.h"
      5 
      6 extern "C" {
      7 #include <assert.h>
      8 #include <unistd.h> // getopt stuff
      9 #include <stdlib.h> // getenv stuff
     10 #include <string.h>
     11 #include <X11/Xlib.h>
     12 }
     13 
     14 #include <iostream>
     15 #include <string>
     16 #include <sstream>
     17 #include <map>
     18 
     19 #include "wmi.h"
     20 
     21 #include "loader.h"
     22 #include "util.h"
     23 #include "kernel.h"
     24 
     25 
     26 static void version() {
     27     cout << "wmi - window manager improved - " << __WMI_VERSION
     28          << endl << " (C)opyright 2003 - 2004 by Anselm R. Garbe"
     29          << endl;
     30 }
     31 
     32 static void usage() {
     33     cout << "usage: " << endl << endl
     34          << " wmi [-d <display>] [-h] [-v]" << endl
     35          << endl
     36          << "  -d display specifies the display to use" << endl
     37          << "  -h prints out this help" << endl
     38          << "  -v prints out above version info" << endl;
     39 }
     40 
     41 Display *openDisplay(const char *displayName) {
     42 
     43     Display *display = XOpenDisplay(displayName);
     44     if (!display) {
     45         if (displayName != 0) {
     46             cerr << "wmi[E " << Util::timestamp()
     47                  << "]: cannot open display \'" 
     48                  << displayName << "\', giving up" << endl;
     49         }
     50         else {
     51             cerr << "wmi[E " << Util::timestamp()
     52                  << "]: cannot open default display" 
     53                  << ", giving up" << endl;
     54         }
     55         exit(1);
     56     }
     57 
     58     return display;
     59 }
     60 
     61 static bool loadSettings(MSettings *settings, string filename,
     62                          const char *home, bool suppressWarning = false,
     63                          bool caseSensitive = false)
     64 {
     65     // check global conf
     66     Loader::load(settings, (string)CONFPATH + "/" + filename, true);
     67 
     68     // check local conf
     69     string localConf = (string)home + "/.wmi/" + filename;
     70     bool result = Loader::load(settings, localConf,
     71                                suppressWarning, caseSensitive);
     72     if (!suppressWarning && !result) {
     73         cerr << "wmi[W " << Util::timestamp()
     74             << "]: cannot load settings from '"
     75             << localConf << "', using defaults" << endl;
     76     }
     77     return result;
     78 }
     79 
     80 static MSettings *initThemeSettings() {
     81 
     82     MSettings *themeSettings = new MSettings();
     83 
     84     // init default values
     85     // new default 24Bit grey color schema
     86     (*themeSettings)["color.bar.background"] = "#F6F6F6";
     87     (*themeSettings)["color.bar.text"] = "black";
     88     (*themeSettings)["color.bar.shine"] = "#999999";
     89     (*themeSettings)["color.bar.shadow"] = "#999999";
     90     (*themeSettings)["color.meter.background"] = "#F6F6F6";
     91     (*themeSettings)["color.meter.figure.high"] = "red";
     92     (*themeSettings)["color.meter.figure.normal"] = "#253446";
     93     (*themeSettings)["color.meter.figure.low"] = "green";
     94     (*themeSettings)["color.meter.border.shine"] = "#7AA4D9";
     95     (*themeSettings)["color.meter.border.shadow"] = "#7AA4D9";
     96     (*themeSettings)["color.focusreq.background"] = "#FF4000";
     97     (*themeSettings)["color.focusreq.text"] = "black";
     98     (*themeSettings)["color.focusreq.shine"] = "#FFD900";
     99     (*themeSettings)["color.focusreq.shadow"] = "#FFD900";
    100     (*themeSettings)["color.tiled.shine.focussed"] = "#FFD900";
    101     (*themeSettings)["color.tiled.shadow.focussed"] = "#FFD900";
    102     (*themeSettings)["color.tiled.shine.normal"] = "black";
    103     (*themeSettings)["color.tiled.shadow.normal"] = "black";
    104     (*themeSettings)["color.button.background.normal"] = "#3A5D8A";
    105     (*themeSettings)["color.button.background.pressed"] = "#253446";
    106     (*themeSettings)["color.button.border.shine.normal"] = "#7AA4D9";
    107     (*themeSettings)["color.button.border.shine.pressed"] = "#7AA4D9";
    108     (*themeSettings)["color.button.border.shadow.normal"] = "#7AA4D9";
    109     (*themeSettings)["color.button.border.shadow.pressed"] = "#7AA4D9";
    110     (*themeSettings)["color.button.figure.shine.normal"] = "white";
    111     (*themeSettings)["color.button.figure.shine.pressed"] = "#BDBDBD";
    112     (*themeSettings)["color.button.figure.shadow.normal"] = "white";
    113     (*themeSettings)["color.button.figure.shadow.pressed"] = "#BDBDBD";
    114     (*themeSettings)["color.frame.background.normal"] = "#F6F6F6";
    115     (*themeSettings)["color.frame.background.focussed"] = "#3E71AA";
    116     (*themeSettings)["color.frame.pseudo"] = "#D9D9D9";
    117     (*themeSettings)["color.frame.shine.normal"] = "black";
    118     (*themeSettings)["color.frame.shine.focussed"] = "#26476A";
    119     (*themeSettings)["color.frame.shadow.normal"] = "black";
    120     (*themeSettings)["color.frame.shadow.focussed"] = "#26476A";
    121     (*themeSettings)["color.label.background.normal"] = "#F6F6F6";
    122     (*themeSettings)["color.label.background.focussed"] = "#D9D9D9";
    123     (*themeSettings)["color.label.text.normal"] = "black";
    124     (*themeSettings)["color.label.text.focussed"] = "black";
    125     (*themeSettings)["color.label.shine.normal"] = "#999999";
    126     (*themeSettings)["color.label.shine.focussed"] = "#848484";
    127     (*themeSettings)["color.label.shadow.normal"] = "#999999";
    128     (*themeSettings)["color.label.shadow.focussed"] = "#848484";
    129     (*themeSettings)["color.tab.background.active.normal"] = "#F6F6F6";
    130     (*themeSettings)["color.tab.background.inactive.normal"] = "#D9D9D9";
    131     (*themeSettings)["color.tab.background.active.focussed"] = "#3E71AA";
    132     (*themeSettings)["color.tab.background.inactive.focussed"] = "#F6F6F6";
    133     (*themeSettings)["color.tab.text.active.normal"] = "#ADADAD";
    134     (*themeSettings)["color.tab.text.inactive.normal"] = "#ADADAD";
    135     (*themeSettings)["color.tab.text.active.focussed"] = "white";
    136     (*themeSettings)["color.tab.text.inactive.focussed"] = "#ADADAD";
    137     (*themeSettings)["color.tab.shine.active.normal"] = "#F6F6F6";
    138     (*themeSettings)["color.tab.shine.inactive.normal"] = "#F6F6F6";
    139     (*themeSettings)["color.tab.shine.active.focussed"] = "#3E71AA";
    140     (*themeSettings)["color.tab.shine.inactive.focussed"] = "#F6F6F6";
    141     (*themeSettings)["color.tab.shadow.active.normal"] = "#F6F6F6";
    142     (*themeSettings)["color.tab.shadow.inactive.normal"] = "#F6F6F6";
    143     (*themeSettings)["color.tab.shadow.active.focussed"] = "#3E71AA";
    144     (*themeSettings)["color.tab.shadow.inactive.focussed"] = "#F6F6F6";
    145     (*themeSettings)["font"] = "fixed";
    146     (*themeSettings)["exec"] = "xsetroot -solid #7B96AC";
    147 
    148     return themeSettings;
    149 }
    150 
    151 static MSettings *initCommonSettings() {
    152 
    153     MSettings *commonSettings = new MSettings();
    154 
    155     // init common settings
    156     (*commonSettings)["resize-move.factor"] = "10";
    157     (*commonSettings)["terminal"] = "xterm -e";
    158     (*commonSettings)["statusbar.alignment"] = "bottom";
    159 #ifdef SLOT_SUPPORT
    160     (*commonSettings)["slot.alignment"] = "right"; // left
    161     (*commonSettings)["slot.style"] = "transparent"; // solid
    162     (*commonSettings)["slot.tabs"] = "default"; // name1,name2,...
    163     (*commonSettings)["slot.mode"] = "non-overlap"; // overlap
    164 #endif
    165     (*commonSettings)["bar.buttons"] = "yes"; // no
    166     (*commonSettings)["frame.buttons"] = "yes"; // no
    167     (*commonSettings)["frame.colwidth"] = "60";
    168     (*commonSettings)["frame.autodestroy"] = "yes"; // no
    169     (*commonSettings)["frame.mode"] = "tabbed"; // tiled
    170     (*commonSettings)["border.width"] = "3";
    171     (*commonSettings)["default.client-mode"] = "float";
    172     (*commonSettings)["default.transient-mode"] = "float";
    173     (*commonSettings)["default.bar-mode"] = "show"; // hide
    174     (*commonSettings)["default.border-mode"] = "show"; // hide
    175     (*commonSettings)["startup.chain"] = "";
    176     (*commonSettings)["menu.actions"] = "xterm,restart,quit";
    177     (*commonSettings)["autocompletion.mode"] = "default"; // regex
    178     (*commonSettings)["cycle.mode"] = "default"; // stackedtabbing
    179 
    180     return commonSettings;
    181 }
    182 
    183 
    184 static MSettings *initActionSettings() {
    185 
    186     MSettings *actionSettings = new MSettings();
    187 
    188     // intern action bindings
    189     (*actionSettings)["intern.quit.keys"] = "ctrl+alt+q";
    190     (*actionSettings)["intern.grow-left.keys"] = "alt+r::h";
    191     (*actionSettings)["intern.grow-right.keys"] = "alt+r::l";
    192     (*actionSettings)["intern.grow-up.keys"] = "alt+r::k";
    193     (*actionSettings)["intern.grow-down.keys"] = "alt+r::j";
    194     (*actionSettings)["intern.shrink-left.keys"] = "shift+alt+r::h";
    195     (*actionSettings)["intern.shrink-right.keys"] = "shift+alt+r::l";
    196     (*actionSettings)["intern.shrink-up.keys"] = "shift+alt+r::k";
    197     (*actionSettings)["intern.shrink-down.keys"] = "shift+alt+r::j";
    198     (*actionSettings)["intern.move-client-left.keys"] = "shift+alt+h";
    199     (*actionSettings)["intern.move-client-right.keys"] = "shift+alt+l";
    200     (*actionSettings)["intern.move-client-up.keys"] = "shift+alt+k";
    201     (*actionSettings)["intern.move-client-down.keys"] = "shift+alt+j";
    202     (*actionSettings)["intern.select-frame-left.keys"] = "alt+h";
    203     (*actionSettings)["intern.select-frame-right.keys"] = "alt+l";
    204     (*actionSettings)["intern.select-frame-up.keys"] = "alt+k";
    205     (*actionSettings)["intern.select-frame-down.keys"] = "alt+j";
    206     (*actionSettings)["intern.kill-client.keys"] = "ctrl+alt+c";
    207     (*actionSettings)["intern.cycle-client-next.keys"] = "alt+Tab";
    208     (*actionSettings)["intern.cycle-client-prev.keys"] = "shift+alt+Tab";
    209     (*actionSettings)["intern.cycle-workspace-next.keys"] = "ctrl+alt+Right";
    210     (*actionSettings)["intern.cycle-workspace-prev.keys"] = "ctrl+alt+Left";
    211     (*actionSettings)["intern.split-frame-left.keys"] = "alt+s::h";
    212     (*actionSettings)["intern.split-frame-right.keys"] = "alt+s::l";
    213     (*actionSettings)["intern.split-frame-up.keys"] = "alt+s::k";
    214     (*actionSettings)["intern.split-frame-down.keys"] = "alt+s::j";
    215     (*actionSettings)["intern.join-frame-left.keys"] = "shift+alt+s::h";
    216     (*actionSettings)["intern.join-frame-right.keys"] = "shift+alt+s::l";
    217     (*actionSettings)["intern.join-frame-up.keys"] = "shift+alt+s::k";
    218     (*actionSettings)["intern.join-frame-down.keys"] = "shift+alt+s::j";
    219     (*actionSettings)["intern.detach-client.keys"] = "alt+d";
    220     (*actionSettings)["intern.attach-last-client.keys"] = "alt+a";
    221     (*actionSettings)["intern.toggle-client-mode.keys"] = "alt+m";
    222     (*actionSettings)["intern.toggle-mode.keys"] = "alt+f";
    223     (*actionSettings)["intern.inputmode.keys"] = "alt+i";
    224     (*actionSettings)["intern.exec.keys"] = "alt+e";
    225     (*actionSettings)["intern.grab-move.keys"] = "mod1+Button1";
    226     (*actionSettings)["intern.zoom-client.keys"] = "mod1+z";
    227 
    228     // sample extern commands
    229     (*actionSettings)["extern.xterm.cmd"] = "xterm";
    230     (*actionSettings)["extern.xterm.keys"] = "alt+x";
    231 
    232     // sample chains
    233     (*actionSettings)["chain.grow-full.seq"] =
    234         "grow-left,grow-right,grow-up,grow-down";
    235     (*actionSettings)["chain.grow-full.keys"] = "alt+r::f";
    236     (*actionSettings)["chain.shrink-full.seq"] =
    237         "shrink-left,shrink-right,shrink-up,shrink-down";
    238     (*actionSettings)["chain.shrink-full.keys"] = "shift+alt+r::f";
    239 
    240     return actionSettings;
    241 }
    242 
    243 static MSettings *initSessionSettings(Display *display)
    244 {
    245     MSettings *sessionSettings = new MSettings();
    246 
    247     unsigned int monitorCount = ScreenCount(display);
    248 
    249     ostringstream prefix;
    250 
    251     for (unsigned int i = 0; i < monitorCount; i++) {
    252         prefix.str("");
    253         prefix << "monitor[" << i << "]";
    254 
    255         (*sessionSettings)[prefix.str() + ".workspaces"] = "2";
    256         (*sessionSettings)[prefix.str() + ".focused"] = "0";
    257         (*sessionSettings)[prefix.str() + ".workspace[0].name"] = "workspace 1";
    258         (*sessionSettings)[prefix.str() + ".workspace[0].clientbar"] = "yes";
    259         (*sessionSettings)[prefix.str() + ".workspace[0].statusbar"] = "yes";
    260         (*sessionSettings)[prefix.str() + ".workspace[1].name"] = "workspace 2";
    261         (*sessionSettings)[prefix.str() + ".workspace[1].clientbar"] = "yes";
    262         (*sessionSettings)[prefix.str() + ".workspace[1].statusbar"] = "yes";
    263 #ifdef SLOT_SUPPORT
    264         (*sessionSettings)[prefix.str() + ".workspace[0].slot"] = "default";
    265         (*sessionSettings)[prefix.str() + ".workspace[1].slot"] = "default";
    266 #endif
    267     }
    268 
    269     return sessionSettings;
    270 }
    271 
    272 extern "C" {
    273 ////////////////////////////////////////////////////////////
    274 // Here WMI's life begins
    275 int main(int argc, char *argv[])
    276 {
    277     string *displayName = 0;
    278     int c;
    279     unsigned int size;
    280 
    281     // command line args
    282     while ((c = getopt(argc, argv, "vhd:")) != -1) {
    283         switch (c) {
    284         case 'd':
    285             size = strlen(optarg);
    286             displayName = new string(optarg);
    287             break;
    288         case 'v':
    289             version();
    290             exit(0);
    291             break;
    292         case '?':
    293         case 'h':
    294             usage();
    295             exit(1);
    296             break;
    297         }
    298     }
    299 
    300     const char *home = getenv("HOME");
    301     if (!home) {
    302         cerr << "wmi[E " << Util::timestamp()
    303             << "]: cannot determine your $HOME directory,"
    304             << " giving up" << endl;
    305         exit(1);
    306     }
    307 
    308     Display *display = openDisplay((displayName != 0) ?
    309                                    displayName->c_str() : 0);
    310 
    311     // settings
    312     MSettings *themeSettings = initThemeSettings();
    313     bool existsThemeConf = loadSettings(themeSettings, "theme.conf", home);
    314     MSettings *commonSettings = initCommonSettings();
    315     bool existsCommonConf = loadSettings(commonSettings, "common.conf", home);
    316     MSettings *actionSettings = initActionSettings();
    317     loadSettings(actionSettings, "actions.session", home);
    318     loadSettings(actionSettings, "actions.conf", home, true);
    319     MSettings *sessionSettings = initSessionSettings(display);
    320     loadSettings(sessionSettings, "wmi.session", home, false, true);
    321     loadSettings(sessionSettings, "session.conf", home, true, true);
    322 
    323     // only one Kernel instance is needed
    324     int result = Kernel::instance()->start(argv, display,
    325             themeSettings, commonSettings, actionSettings,
    326             sessionSettings, !existsCommonConf);
    327 
    328     // Check if we should safe all current settings to the rc file
    329     if (result == 0) {
    330         if (!existsThemeConf) {
    331             Loader::saveSettings(themeSettings, (string)home +
    332                     "/.wmi/theme.conf");
    333         }
    334         if (!existsCommonConf) {
    335             Loader::saveSettings(commonSettings, (string)home +
    336                     "/.wmi/common.conf");
    337         }
    338         Kernel::instance()->saveSettings();
    339     }
    340 
    341     return result;
    342 }
    343 
    344 }