Esempio n. 1
0
void App::setBackground(const string& themedir) {
    string filename;
    filename = themedir + "/background.png";
    Image *image = new Image;
    bool loaded = image->Read(filename.c_str());
    if (!loaded){ // try jpeg if png failed
        filename = "";
        filename = themedir + "/background.jpg";
        loaded = image->Read(filename.c_str());
    }
    if (loaded) {
        string bgstyle = cfg.getOption("background_style");
        if (bgstyle == "stretch") {
            image->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
        } else if (bgstyle == "tile") {
            image->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
        } else if (bgstyle == "center") {
    	    string hexvalue = cfg.getOption("background_color");
            hexvalue = hexvalue.substr(1,6);
    	    image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
        			    hexvalue.c_str());
        } else { // plain color or error
    	    string hexvalue = cfg.getOption("background_color");
            hexvalue = hexvalue.substr(1,6);
    	    image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
        			    hexvalue.c_str());
        }
        Pixmap p = image->createPixmap(Dpy, Scr, Root);
        XSetWindowBackgroundPixmap(Dpy, Root, p);
    }
    XClearWindow(Dpy, Root);

    XFlush(Dpy);
}
Esempio n. 2
0
	void init()
	{
		speed = 20;
		canvas.LoadJpeg( "Data/BG/4.jpg" );
		turtle.LoadPng( "Data/dir.png" );	
		turtle.SetPos( 512, 384 );
		turtle.Center();
		reset();
	}
Esempio n. 3
0
Panel::Panel(Display* dpy, int scr, Window root, Cfg* config,
             const string& themedir) {
    // Set display
    Dpy = dpy;
    Scr = scr;
    Root = root;
    cfg = config;

    session = "";

    // Init GC
    XGCValues gcv;
    unsigned long gcm;
    gcm = GCForeground|GCBackground|GCGraphicsExposures;
    gcv.foreground = GetColor("black");
    gcv.background = GetColor("white");
    gcv.graphics_exposures = False;
    TextGC = XCreateGC(Dpy, Root, gcm, &gcv);

    font = XftFontOpenName(Dpy, Scr, cfg->getOption("input_font").c_str());
    welcomefont = XftFontOpenName(Dpy, Scr, cfg->getOption("welcome_font").c_str());
    introfont = XftFontOpenName(Dpy, Scr, cfg->getOption("intro_font").c_str());
    enterfont = XftFontOpenName(Dpy, Scr, cfg->getOption("username_font").c_str());
    msgfont = XftFontOpenName(Dpy, Scr, cfg->getOption("msg_font").c_str());

    Visual* visual = DefaultVisual(Dpy, Scr);
    Colormap colormap = DefaultColormap(Dpy, Scr);
    // NOTE: using XftColorAllocValue() would be a better solution. Lazy me.
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_fgcolor").c_str(), &fgcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_shadow_color").c_str(), &inputshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_bgcolor").c_str(), &bgcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_color").c_str(), &welcomecolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_shadow_color").c_str(), &welcomeshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_color").c_str(), &entercolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_shadow_color").c_str(), &entershadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_color").c_str(), &msgcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_shadow_color").c_str(), &msgshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("intro_color").c_str(), &introcolor);

    // Load properties from config / theme
    input_name_x = Cfg::string2int(cfg->getOption("input_name_x").c_str());
    input_name_y = Cfg::string2int(cfg->getOption("input_name_y").c_str());
    input_pass_x = Cfg::string2int(cfg->getOption("input_pass_x").c_str());
    input_pass_y = Cfg::string2int(cfg->getOption("input_pass_y").c_str());
    inputShadowXOffset =
        Cfg::string2int(cfg->getOption("input_shadow_xoffset").c_str());
    inputShadowYOffset =
        Cfg::string2int(cfg->getOption("input_shadow_yoffset").c_str());

    if (input_pass_x < 0 || input_pass_y < 0){ // single inputbox mode
        input_pass_x = input_name_x;
        input_pass_y = input_name_y;
    }

    // Load panel and background image
    string panelpng = "";
    panelpng = panelpng + themedir +"/panel.png";
    image = new Image;
    bool loaded = image->Read(panelpng.c_str());
    if (!loaded) { // try jpeg if png failed
        panelpng = themedir + "/panel.jpg";
        loaded = image->Read(panelpng.c_str());
        if (!loaded) {
            cerr << APPNAME << ": could not load panel image for theme '" 
		 << basename(themedir.c_str()) << "'"
		 << endl;
            exit(ERR_EXIT);
        }
    }

    Image* bg = new Image();
    string bgstyle = cfg->getOption("background_style");
    if (bgstyle != "color") {
        panelpng = themedir +"/background.png";
        loaded = bg->Read(panelpng.c_str());
        if (!loaded) { // try jpeg if png failed
            panelpng = themedir + "/background.jpg";
            loaded = bg->Read(panelpng.c_str());
            if (!loaded){
                cerr << APPNAME << ": could not load background image for theme '" 
		        << basename(themedir.c_str()) << "'"
		        << endl;
                exit(ERR_EXIT);
            }
        }
    }
    if (bgstyle == "stretch") {
        bg->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
    } else if (bgstyle == "tile") {
        bg->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
    } else if (bgstyle == "center") {
 	    string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
  	    bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
       			    hexvalue.c_str());
    } else { // plain color or error
	    string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
  	    bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
    			    hexvalue.c_str());
    }

    string cfgX = cfg->getOption("input_panel_x");
    string cfgY = cfg->getOption("input_panel_y");
    X = Cfg::absolutepos(cfgX, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Width());
    Y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Height());

    // Merge image into background
    image->Merge(bg, X, Y);
    PanelPixmap = image->createPixmap(Dpy, Scr, Root);

    // Read (and substitute vars in) the welcome message
    welcome_message = cfg->getWelcomeMessage();
    intro_message = cfg->getOption("intro_msg");

    // Init In
    In = new Input(cfg);
}
Esempio n. 4
0
Panel::Panel(Display* dpy, int scr, Window win, Cfg* config,
             const string& themedir) {
	// Get user
	const char *user = getenv("USER");

    // Set display
    Dpy = dpy;
    Scr = scr;
    Win = win;
    cfg = config;

    XRRScreenConfiguration *rrc;
    XRRScreenSize *rrsizes;
    Rotation rot = ~0;
    SizeID size = -1;
    int nsizes = 0;

    rrc = XRRGetScreenInfo(dpy, RootWindow(Dpy, Scr));
    size = XRRConfigCurrentConfiguration (rrc, &rot);
    rrsizes = XRRConfigSizes (rrc, &nsizes);

    if (nsizes <= 0) {  /* WTF?  Shouldn't happen but does. */
      screen1_width  = DisplayWidth(Dpy, Scr);
      screen1_height = DisplayHeight(Dpy, Scr);
    } else if (rot & (RR_Rotate_90|RR_Rotate_270)) {
      screen1_width  = rrsizes[size].height;
      screen1_height = rrsizes[size].width;
    } else {
      screen1_width  = rrsizes[size].width;
      screen1_height = rrsizes[size].height;
    }

    /* don't free 'rrsizes' */
    XRRFreeScreenConfigInfo (rrc);

    // Init GC
    XGCValues gcv;
    unsigned long gcm;
    gcm = GCForeground|GCBackground|GCGraphicsExposures;
    gcv.foreground = GetColor("black");
    gcv.background = GetColor("white");
    gcv.graphics_exposures = False;
    TextGC = XCreateGC(Dpy, Win, gcm, &gcv);

    font = XftFontOpenName(Dpy, Scr, cfg->getOption("input_font").c_str());
    welcomefont = XftFontOpenName(Dpy, Scr, cfg->getOption("welcome_font").c_str());
    introfont = XftFontOpenName(Dpy, Scr, cfg->getOption("intro_font").c_str());
    enterfont = XftFontOpenName(Dpy, Scr, cfg->getOption("username_font").c_str());
    msgfont = XftFontOpenName(Dpy, Scr, cfg->getOption("msg_font").c_str());

    Visual* visual = DefaultVisual(Dpy, Scr);
    Colormap colormap = DefaultColormap(Dpy, Scr);
    // NOTE: using XftColorAllocValue() would be a better solution. Lazy me.
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_color").c_str(), &inputcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_shadow_color").c_str(), &inputshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_color").c_str(), &welcomecolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_shadow_color").c_str(), &welcomeshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_color").c_str(), &entercolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_shadow_color").c_str(), &entershadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_color").c_str(), &msgcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_shadow_color").c_str(), &msgshadowcolor);
    XftColorAllocName(Dpy, visual, colormap, cfg->getOption("intro_color").c_str(), &introcolor);

    // Load properties from config / theme
    input_name_x = Cfg::string2int(cfg->getOption("input_name_x").c_str());
    input_name_y = Cfg::string2int(cfg->getOption("input_name_y").c_str());
    input_pass_x = Cfg::string2int(cfg->getOption("input_pass_x").c_str());
    input_pass_y = Cfg::string2int(cfg->getOption("input_pass_y").c_str());
    inputShadowXOffset =
        Cfg::string2int(cfg->getOption("input_shadow_xoffset").c_str());
    inputShadowYOffset =
        Cfg::string2int(cfg->getOption("input_shadow_yoffset").c_str());

    if (input_pass_x < 0 || input_pass_y < 0) { // single inputbox mode
        input_pass_x = input_name_x;
        input_pass_y = input_name_y;
    }

    // Load panel and background image
    string panelpng = "";
    panelpng = panelpng + themedir +"/panel.png";
    image = new Image;
    bool loaded = image->Read(panelpng.c_str());
    if (!loaded) { // try jpeg if png failed
        panelpng = themedir + "/panel.jpg";
        loaded = image->Read(panelpng.c_str());
        if (!loaded) {
            cerr << APPNAME
                 << ": could not load panel image for theme '"
                 << basename((char*)themedir.c_str()) << "'"
                 << endl;
            exit(ERR_EXIT);
        }
    }

    Image* bg = new Image;
    string bgstyle = cfg->getOption("background_style");
    if (bgstyle != "color") {
        panelpng = themedir +"/background.png";
        loaded = bg->Read(panelpng.c_str());
        if (!loaded) { // try jpeg if png failed
            panelpng = themedir + "/background.jpg";
            loaded = bg->Read(panelpng.c_str());
            if (!loaded) {
                cerr << APPNAME
                     << ": could not load background image for theme '"
                     << basename((char*)themedir.c_str()) << "'"
                     << endl;
                exit(ERR_EXIT);
            }
        }
    }

    if (bgstyle == "stretch") {
        bg->Resize(screen1_width, screen1_height);
    } else if (bgstyle == "tile") {
        bg->Tile(screen1_width,
                 screen1_height);
    } else if (bgstyle == "center") {
        string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
        bg->Center(screen1_width,
                   screen1_height,
                   hexvalue.c_str());
    } else { // plain color or error
        string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
        bg->Center(screen1_width,
                   screen1_height,
                   hexvalue.c_str());
    }

    string cfgX = cfg->getOption("input_panel_x");
    string cfgY = cfg->getOption("input_panel_y");
    X = Cfg::absolutepos(cfgX, screen1_width, image->Width());
    Y = Cfg::absolutepos(cfgY, screen1_height, image->Height());

    input_name_x += X, input_name_y += Y, input_pass_x += X, input_pass_y += Y;

    // Merge image into background
    image->Merge(bg, X, Y);
    Pixmap p = image->createPixmap(Dpy, Scr, Win);
    XSetWindowBackgroundPixmap(Dpy, Win, p);
    XFreePixmap(Dpy, p);
    XClearWindow(Dpy, Win);

    delete bg;

    // Read (and substitute vars in) the welcome message
    int show_welcome_msg = Cfg::string2int(cfg->getOption("show_welcome_msg").c_str());
    if (show_welcome_msg)
        welcome_message = cfg->getWelcomeMessage();
    else
        welcome_message = "";

    intro_message = cfg->getOption("intro_msg");

    SetName(user);

    // Draw the panel for the first time
    OnExpose();
}
Esempio n. 5
0
Panel::Panel(Display* dpy, int scr, Window root, Cfg* config,
			 const string& themedir, PanelType panel_mode) {	
	/* Set display */
	Dpy = dpy;
	Scr = scr;
	Root = root;
	cfg = config;
	mode = panel_mode;
	monitors_changed = 0;

	session_name = "";
	session_exec = "";
	if (mode == Mode_Lock) {
		Win = root;
		if (!CheckXRandr()) {
			exit (ERR_EXIT);
		}

		display_size.width = DisplayWidth(Dpy, Scr);
		display_size.height = DisplayHeight(Dpy, Scr);
		viewport = GetPrimaryViewport();
	}

	/* Init GC */
	XGCValues gcv;
	unsigned long gcm;
	gcm = GCForeground|GCBackground|GCGraphicsExposures;
	gcv.foreground = GetColor("black");
	gcv.background = GetColor("white");
	gcv.graphics_exposures = False;
	if (mode == Mode_Lock)
		TextGC = XCreateGC(Dpy, Win, gcm, &gcv);
	else
		TextGC = XCreateGC(Dpy, Root, gcm, &gcv);

	if (mode == Mode_Lock) {
		gcm = GCGraphicsExposures;
		gcv.graphics_exposures = False;
		WinGC = XCreateGC(Dpy, Win, gcm, &gcv);
		if (WinGC < 0) {
			cerr << APPNAME
				<< ": failed to create pixmap\n.";
			exit(ERR_EXIT);
		}
	}

	font = XftFontOpenName(Dpy, Scr, cfg->getOption("input_font").c_str());
	welcomefont = XftFontOpenName(Dpy, Scr, cfg->getOption("welcome_font").c_str());
	introfont = XftFontOpenName(Dpy, Scr, cfg->getOption("intro_font").c_str());
	enterfont = XftFontOpenName(Dpy, Scr, cfg->getOption("username_font").c_str());
	msgfont = XftFontOpenName(Dpy, Scr, cfg->getOption("msg_font").c_str());

	Visual* visual = DefaultVisual(Dpy, Scr);
	Colormap colormap = DefaultColormap(Dpy, Scr);
	/* NOTE: using XftColorAllocValue() would be a better solution. Lazy me. */
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_color").c_str(), &inputcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("input_shadow_color").c_str(), &inputshadowcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_color").c_str(), &welcomecolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("welcome_shadow_color").c_str(), &welcomeshadowcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_color").c_str(), &entercolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("username_shadow_color").c_str(), &entershadowcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_color").c_str(), &msgcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("msg_shadow_color").c_str(), &msgshadowcolor);
	XftColorAllocName(Dpy, visual, colormap, cfg->getOption("intro_color").c_str(), &introcolor);
	XftColorAllocName(Dpy, visual, colormap,
					  cfg->getOption("session_color").c_str(), &sessioncolor);
	XftColorAllocName(Dpy, visual, colormap,
					  cfg->getOption("session_shadow_color").c_str(), &sessionshadowcolor);

	/* Load properties from config / theme */
	input_name_x = cfg->getIntOption("input_name_x");
	input_name_y = cfg->getIntOption("input_name_y");
	input_pass_x = cfg->getIntOption("input_pass_x");
	input_pass_y = cfg->getIntOption("input_pass_y");
	inputShadowXOffset = cfg->getIntOption("input_shadow_xoffset");
	inputShadowYOffset = cfg->getIntOption("input_shadow_yoffset");

	if (input_pass_x < 0 || input_pass_y < 0){ /* single inputbox mode */
		input_pass_x = input_name_x;
		input_pass_y = input_name_y;
	}

	/* Load panel and background image */
	string panelpng = "";
	panelpng = panelpng + themedir +"/panel.png";
	image = new Image;
	bool loaded = image->Read(panelpng.c_str());
	if (!loaded) { /* try jpeg if png failed */
		panelpng = themedir + "/panel.jpg";
		loaded = image->Read(panelpng.c_str());
		if (!loaded) {
			logStream << APPNAME
				 << ": could not load panel image for theme '"
				 << basename((char*)themedir.c_str()) << "'"
				 << endl;
			exit(ERR_EXIT);
		}
	}

	Image* bg = new Image();
	string bgstyle = cfg->getOption("background_style");
	if (bgstyle != "color") {
		panelpng = themedir +"/background.png";
		loaded = bg->Read(panelpng.c_str());
		if (!loaded) { /* try jpeg if png failed */
			panelpng = themedir + "/background.jpg";
			loaded = bg->Read(panelpng.c_str());
			if (!loaded){
				logStream << APPNAME
					 << ": could not load background image for theme '"
					 << basename((char*)themedir.c_str()) << "'"
					 << endl;
				exit(ERR_EXIT);
			}
		}
	}

	if (mode == Mode_Lock) {
		if (bgstyle == "stretch")
			bg->Resize(viewport.width, viewport.height);
			//bg->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
			//			XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
		else if (bgstyle == "tile")
			bg->Tile(viewport.width, viewport.height);
		else if (bgstyle == "center") {
			string hexvalue = cfg->getOption("background_color");
			hexvalue = hexvalue.substr(1,6);
			bg->Center(viewport.width,
				viewport.height,
				hexvalue.c_str());
		} else { // plain color or error
			string hexvalue = cfg->getOption("background_color");
			hexvalue = hexvalue.substr(1,6);
			bg->Center(viewport.width,
				viewport.height,
				hexvalue.c_str());
		}
	} else {
		if (bgstyle == "stretch") {
			bg->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
						XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
		} else if (bgstyle == "tile") {
			bg->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
						XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
		} else if (bgstyle == "center") {
			string hexvalue = cfg->getOption("background_color");
			hexvalue = hexvalue.substr(1,6);
			bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
					XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
					hexvalue.c_str());
		} else { /* plain color or error */
			string hexvalue = cfg->getOption("background_color");
			hexvalue = hexvalue.substr(1,6);
			bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
				   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
				   hexvalue.c_str());
		}
	}

	string cfgX = cfg->getOption("input_panel_x");
	string cfgY = cfg->getOption("input_panel_y");

	if (mode == Mode_Lock) {
		X = Cfg::absolutepos(cfgX, viewport.width, image->Width());
		Y = Cfg::absolutepos(cfgY, viewport.height, image->Height());

		input_name_x += X;
		input_name_y += Y;
		input_pass_x += X;
		input_pass_y += Y;
	} else {
		X = Cfg::absolutepos(cfgX, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Width());
		Y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), image->Height());
	}

	if (mode == Mode_Lock) {
		/* Merge image into background without crop */
		image->Merge_non_crop(bg, X, Y);
		PanelPixmap = image->createPixmap(Dpy, Scr, Win);
	} else {
		/* Merge image into background */
		image->Merge(bg, X, Y);
		PanelPixmap = image->createPixmap(Dpy, Scr, Root);
	}
	delete bg;

	/* Read (and substitute vars in) the welcome message */
	welcome_message = cfg->getWelcomeMessage();
	intro_message = cfg->getOption("intro_msg");

	if (mode == Mode_Lock) {
		SetName(getenv("USER"));
		field = Get_Passwd;
		OnExpose();
	}
}
Esempio n. 6
0
Panel::Panel(gi_window_id_t root, Cfg* config,
             const string& themedir) {
    // Set display
    //Dpy = dpy;
    //Scr = scr;
    Root = root;
    cfg = config;

    session = "";

    // Init GC
    //XGCValues gcv;
    //unsigned long gcm;
   // gcm = GCForeground|GCBackground|GCGraphicsExposures;
    //gcv.foreground = GetColor("black");
    //gcv.background = GetColor("white");
    //gcv.graphics_exposures = FALSE;
    //RootGC = gi_create_gc( Root, gcm, &gcv);
    RootGC = gi_create_gc( Root, NULL);

    font = gi_create_ufont( cfg->getOption("input_font").c_str());
    welcomefont = gi_create_ufont( cfg->getOption("welcome_font").c_str());
    introfont = gi_create_ufont( cfg->getOption("intro_font").c_str());
    enterfont = gi_create_ufont( cfg->getOption("username_font").c_str());
    msgfont = gi_create_ufont( cfg->getOption("msg_font").c_str());

    //Visual* visual = DefaultVisual( Scr);
    //Colormap colormap = DefaultColormap( Scr);
    // NOTE: using XftColorAllocValue() would be a better solution. Lazy me.
    XftColorAllocName( cfg->getOption("input_color").c_str(), &inputcolor);
    XftColorAllocName( cfg->getOption("input_shadow_color").c_str(), &inputshadowcolor);
    XftColorAllocName( cfg->getOption("welcome_color").c_str(), &welcomecolor);
    XftColorAllocName( cfg->getOption("welcome_shadow_color").c_str(), &welcomeshadowcolor);
    XftColorAllocName( cfg->getOption("username_color").c_str(), &entercolor);
    XftColorAllocName( cfg->getOption("username_shadow_color").c_str(), &entershadowcolor);
    XftColorAllocName( cfg->getOption("msg_color").c_str(), &msgcolor);
    XftColorAllocName( cfg->getOption("msg_shadow_color").c_str(), &msgshadowcolor);
    XftColorAllocName( cfg->getOption("intro_color").c_str(), &introcolor);
    XftColorAllocName( cfg->getOption("session_color").c_str(), &sessioncolor);
    XftColorAllocName( cfg->getOption("session_shadow_color").c_str(), &sessionshadowcolor);

    // Load properties from config / theme
    input_name_x = Cfg::string2int(cfg->getOption("input_name_x").c_str());
    input_name_y = Cfg::string2int(cfg->getOption("input_name_y").c_str());
    input_pass_x = Cfg::string2int(cfg->getOption("input_pass_x").c_str());
    input_pass_y = Cfg::string2int(cfg->getOption("input_pass_y").c_str());
    inputShadowXOffset =
        Cfg::string2int(cfg->getOption("input_shadow_xoffset").c_str());
    inputShadowYOffset =
        Cfg::string2int(cfg->getOption("input_shadow_yoffset").c_str());

    if (input_pass_x < 0 || input_pass_y < 0){ // single inputbox mode
        input_pass_x = input_name_x;
        input_pass_y = input_name_y;
    }

    // Load panel and background image
    string panelpng = "";
    panelpng = panelpng + themedir +"/panel.png";
    image = new Image;
    bool loaded = image->Read(panelpng.c_str());
    if (!loaded) { // try jpeg if png failed
        panelpng = themedir + "/panel.jpg";
        loaded = image->Read(panelpng.c_str());
        if (!loaded) {
            cerr << APPNAME
                 << ": could not load panel image for theme '"
                 << basename((char*)themedir.c_str()) << "'"
                 << endl;
            FAULT(ERR_EXIT);
        }
    }

    Image* bg = new Image();
    string bgstyle = cfg->getOption("background_style");
    if (bgstyle != "color") {
        panelpng = themedir +"/background.png";
        loaded = bg->Read(panelpng.c_str());
        if (!loaded) { // try jpeg if png failed
            panelpng = themedir + "/background.jpg";
            loaded = bg->Read(panelpng.c_str());
            if (!loaded){
                cerr << APPNAME
                     << ": could not load background image for theme '"
                     << basename((char*)themedir.c_str()) << "'"
                     << endl;
                FAULT(ERR_EXIT);
            }
        }
    }
    if (bgstyle == "stretch") {
        bg->Resize(gi_screen_width(), gi_screen_height());
    } else if (bgstyle == "tile") {
        bg->Tile(gi_screen_width(), gi_screen_height());
    } else if (bgstyle == "center") {
        string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
        bg->Center(gi_screen_width(),
                   gi_screen_height(),
                   hexvalue.c_str());
    } else { // plain color or error
        string hexvalue = cfg->getOption("background_color");
        hexvalue = hexvalue.substr(1,6);
        bg->Center(gi_screen_width(),
                   gi_screen_height(),
                   hexvalue.c_str());
    }

    string cfgX = cfg->getOption("input_panel_x");
    string cfgY = cfg->getOption("input_panel_y");
    X = Cfg::absolutepos(cfgX, gi_screen_width(), image->Width());
    Y = Cfg::absolutepos(cfgY, gi_screen_height(), image->Height());

    // Merge image into background
    image->Merge(bg, X, Y);
    delete bg;
    PanelPixmap = image->createPixmap(Root);

    // Read (and substitute vars in) the welcome message
    welcome_message = cfg->getWelcomeMessage();
    intro_message = cfg->getOption("intro_msg");
}