2010-01-04 04:50:02 +00:00
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim : ts = 4 sw = 4 noet ai cindent syntax = cpp
2009-07-28 21:44:22 +00:00
*
* Conky , a system monitor , based on torsmo
2005-07-20 00:30:40 +00:00
*
2007-08-10 19:53:44 +00:00
* Any original torsmo code is licensed under the BSD license
*
* All code written since the fork of torsmo is licensed under the GPL
*
* Please see COPYING for details
*
* Copyright ( c ) 2004 , Hannu Saransaari and Lauri Hakkarainen
2012-05-03 23:34:44 +00:00
* Copyright ( c ) 2005 - 2012 Brenden Matthews , Philip Kovacs , et . al .
2008-02-20 20:30:45 +00:00
* ( see AUTHORS )
2007-08-10 19:53:44 +00:00
* All rights reserved .
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
2008-02-20 20:30:45 +00:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-08-05 01:06:17 +00:00
*
2008-12-09 23:35:49 +00:00
*/
2005-07-20 00:30:40 +00:00
2008-12-15 21:40:24 +00:00
# include "config.h"
2008-12-15 17:31:23 +00:00
# include "text_object.h"
2005-07-20 00:30:40 +00:00
# include "conky.h"
2008-12-15 21:40:24 +00:00
# include "common.h"
2010-02-26 00:17:27 +00:00
# include <iostream>
2010-02-24 21:06:06 +00:00
# include <algorithm>
2010-06-04 13:47:01 +00:00
# include <sstream>
2010-02-24 21:06:06 +00:00
# include <string>
2008-04-17 20:40:53 +00:00
# include <stdarg.h>
2010-01-03 07:59:24 +00:00
# include <cmath>
# include <ctime>
2005-07-20 00:30:40 +00:00
# include <locale.h>
# include <signal.h>
# include <errno.h>
# include <limits.h>
2009-12-08 05:16:11 +00:00
# ifdef HAVE_DIRENT_H
2005-07-20 00:30:40 +00:00
# include <dirent.h>
2009-12-08 05:16:11 +00:00
# endif /* HAVE_DIRENT_H */
2005-07-20 00:30:40 +00:00
# include <sys/time.h>
2008-12-23 03:59:42 +00:00
# include <sys/param.h>
2009-05-19 23:14:34 +00:00
# ifdef HAVE_SYS_INOTIFY_H
# include <sys/inotify.h>
# endif /* HAVE_SYS_INOTIFY_H */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2008-12-15 21:40:24 +00:00
# include "x11.h"
2005-07-20 00:30:40 +00:00
# include <X11/Xutil.h>
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2006-05-24 06:34:37 +00:00
# include <X11/extensions/Xdamage.h>
2009-08-07 07:24:24 +00:00
# endif
2010-01-10 23:35:22 +00:00
# ifdef BUILD_IMLIB2
2009-08-07 07:21:56 +00:00
# include "imlib2.h"
2010-01-10 23:35:22 +00:00
# endif /* BUILD_IMLIB2 */
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2005-07-20 00:30:40 +00:00
# include <sys/types.h>
# include <sys/stat.h>
2006-05-12 12:41:18 +00:00
# include <netinet/in.h>
# include <netdb.h>
2007-09-28 20:16:16 +00:00
# include <fcntl.h>
2008-01-06 01:35:14 +00:00
# include <getopt.h>
2010-05-06 15:29:09 +00:00
# if defined BUILD_WEATHER_XOAP || defined BUILD_RSS
2009-08-03 17:58:21 +00:00
# include <libxml/parser.h>
2010-05-06 15:29:09 +00:00
# endif
2010-08-29 11:31:18 +00:00
# ifdef BUILD_CURL
# include <curl/curl.h>
# endif
2006-03-22 19:35:58 +00:00
2008-12-15 21:40:24 +00:00
/* local headers */
2009-08-07 07:24:24 +00:00
# include "core.h"
2008-12-15 21:40:24 +00:00
# include "build.h"
2009-02-22 16:53:30 +00:00
# include "colours.h"
2009-08-07 07:21:56 +00:00
# include "diskio.h"
2009-10-15 19:51:21 +00:00
# include "exec.h"
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-02-22 16:53:30 +00:00
# include "fonts.h"
2009-03-17 17:36:46 +00:00
# endif
2010-01-20 17:17:30 +00:00
# ifdef BUILD_ICONV
2009-10-03 18:01:33 +00:00
# include "iconv_tools.h"
# endif
2009-12-28 20:05:40 +00:00
# include "llua.h"
2008-12-15 21:40:24 +00:00
# include "logging.h"
# include "mail.h"
2010-04-30 17:33:21 +00:00
# include "nc.h"
2009-10-17 14:43:12 +00:00
# include "net_stat.h"
2008-12-15 21:40:24 +00:00
# include "temphelper.h"
2009-09-03 21:53:20 +00:00
# include "template.h"
2009-10-03 15:46:59 +00:00
# include "timeinfo.h"
2008-12-15 21:40:24 +00:00
# include "top.h"
2010-04-18 15:52:41 +00:00
# ifdef BUILD_MYSQL
# include "mysql.h"
# endif /* BUILD_MYSQL */
2010-08-13 13:05:05 +00:00
# ifdef BUILD_NVIDIA
# include "nvidia.h"
# endif
2010-12-31 15:43:49 +00:00
# ifdef BUILD_CURL
# include "ccurl_thread.h"
# endif /* BUILD_CURL */
2011-01-06 10:14:24 +00:00
# ifdef BUILD_WEATHER_METAR
# include "weather.h"
# endif /* BUILD_WEATHER_METAR */
2008-12-15 21:40:24 +00:00
2010-02-12 17:39:01 +00:00
# include "lua-config.hh"
2010-02-17 21:52:19 +00:00
# include "setting.hh"
2010-02-12 17:39:01 +00:00
2008-12-15 21:40:24 +00:00
/* check for OS and include appropriate headers */
# if defined(__linux__)
# include "linux.h"
# elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
# include "freebsd.h"
2012-06-28 16:56:01 +00:00
# elif defined(__DragonFly__)
# include "dragonfly.h"
2008-12-15 21:40:24 +00:00
# elif defined(__OpenBSD__)
# include "openbsd.h"
# endif
2010-06-04 12:41:12 +00:00
# ifdef BUILD_HTTP
# include <microhttpd.h>
# endif
2008-12-15 21:40:24 +00:00
2009-05-29 15:12:12 +00:00
# if defined(__FreeBSD_kernel__)
# include <bsd/bsd.h>
# endif
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2008-12-12 14:33:25 +00:00
# include "defconfig.h"
2010-09-12 14:23:06 +00:00
namespace { const char builtin_config_magic [ ] = " ==builtin== " ; }
2008-12-14 13:36:44 +00:00
# endif
2008-12-12 14:33:25 +00:00
2010-11-19 13:27:18 +00:00
# ifdef BUILD_OLD_CONFIG
# include "convertconf.h"
# endif
2006-12-11 19:04:58 +00:00
# ifndef S_ISSOCK
# define S_ISSOCK(x) ((x & S_IFMT) == S_IFSOCK)
# endif
2005-07-20 00:30:40 +00:00
# define MAX_IF_BLOCK_DEPTH 5
2008-09-26 21:09:48 +00:00
//#define SIGNAL_BLOCKING
# undef SIGNAL_BLOCKING
2005-11-24 02:18:42 +00:00
2008-12-15 21:40:24 +00:00
/* debugging level, used by logging.h */
2008-11-30 20:53:20 +00:00
int global_debug_level = 0 ;
2010-01-02 21:31:09 +00:00
/* disable inotify auto reload feature if desired */
2010-03-05 20:00:25 +00:00
static conky : : simple_config_setting < bool > disable_auto_reload ( " disable_auto_reload " , false , false ) ;
2010-01-02 21:31:09 +00:00
2009-08-07 07:24:24 +00:00
/* two strings for internal use */
static char * tmpstring1 , * tmpstring2 ;
2009-12-11 16:58:25 +00:00
enum spacer_state {
2009-08-07 07:24:24 +00:00
NO_SPACER = 0 ,
LEFT_SPACER ,
RIGHT_SPACER
2010-03-05 20:05:05 +00:00
} ;
template < >
conky : : lua_traits < spacer_state > : : Map conky : : lua_traits < spacer_state > : : map = {
{ " none " , NO_SPACER } ,
{ " left " , LEFT_SPACER } ,
{ " right " , RIGHT_SPACER }
} ;
static conky : : simple_config_setting < spacer_state > use_spacer ( " use_spacer " , NO_SPACER , false ) ;
/* variables holding various config settings */
2010-03-07 12:36:40 +00:00
static conky : : simple_config_setting < bool > short_units ( " short_units " , false , true ) ;
2010-03-07 12:44:33 +00:00
static conky : : simple_config_setting < bool > format_human_readable ( " format_human_readable " ,
true , true ) ;
2010-04-30 17:06:17 +00:00
2010-10-31 17:17:22 +00:00
static conky : : simple_config_setting < bool > out_to_stdout ( " out_to_console " ,
// Default value is false, unless we are building without X
# ifdef BUILD_X11
false ,
# else
true ,
# endif
false ) ;
2010-04-30 17:06:17 +00:00
static conky : : simple_config_setting < bool > out_to_stderr ( " out_to_stderr " , false , false ) ;
2010-06-20 17:31:17 +00:00
2009-08-07 07:24:24 +00:00
int top_cpu , top_mem , top_time ;
2010-01-07 18:14:53 +00:00
# ifdef BUILD_IOSTATS
2009-08-07 07:24:24 +00:00
int top_io ;
# endif
2009-09-03 21:13:14 +00:00
int top_running ;
2010-03-05 19:58:39 +00:00
static conky : : simple_config_setting < bool > extra_newline ( " extra_newline " , false , false ) ;
2008-12-15 21:40:24 +00:00
static volatile int g_signal_pending ;
2010-09-11 12:25:19 +00:00
2009-08-07 07:24:24 +00:00
/* Update interval */
2010-09-11 12:25:19 +00:00
conky : : range_config_setting < double > update_interval ( " update_interval " , 0.0 ,
std : : numeric_limits < double > : : infinity ( ) , 3.0 , true ) ;
conky : : range_config_setting < double > update_interval_on_battery ( " update_interval_on_battery " , 0.0 ,
std : : numeric_limits < double > : : infinity ( ) , NOBATTERY , true ) ;
static bool on_battery = false ;
double active_update_interval ( )
{ return ( on_battery ? update_interval_on_battery : update_interval ) . get ( * state ) ; }
2010-09-11 12:45:19 +00:00
void music_player_interval_setting : : lua_setter ( lua : : state & l , bool init )
{
lua : : stack_sentry s ( l , - 2 ) ;
if ( l . isnil ( - 2 ) ) {
l . checkstack ( 1 ) ;
l . pushnumber ( update_interval . get ( l ) ) ;
l . replace ( - 3 ) ;
}
Base : : lua_setter ( l , init ) ;
+ + s ;
}
music_player_interval_setting music_player_interval ;
2009-08-07 07:24:24 +00:00
void * global_cpu = NULL ;
2010-08-25 16:51:29 +00:00
static conky : : range_config_setting < unsigned int > max_text_width ( " max_text_width " , 0 ,
std : : numeric_limits < unsigned int > : : max ( ) , 0 , true ) ;
2008-12-15 21:40:24 +00:00
2010-02-14 21:58:02 +00:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
extern kvm_t * kd ;
# endif
2009-07-17 16:01:41 +00:00
int argc_copy ;
char * * argv_copy ;
2008-12-15 21:40:24 +00:00
/* prototypes for internally used functions */
static void signal_handler ( int ) ;
2009-08-07 07:21:56 +00:00
static void reload_config ( void ) ;
2008-03-29 11:35:02 +00:00
2008-03-29 02:01:03 +00:00
static void print_version ( void )
2006-08-12 06:10:18 +00:00
{
2012-04-11 16:11:38 +00:00
std : : cout < < _ ( PACKAGE_NAME " " VERSION " compiled " BUILD_DATE " for " BUILD_ARCH " \n "
2010-11-13 19:17:46 +00:00
" \n Compiled in features: \n \n "
2012-04-11 16:06:47 +00:00
" System config file: " SYSTEM_CONFIG_FILE " \n "
" Package library path: " PACKAGE_LIBDIR " \n \n " )
2010-11-13 19:17:46 +00:00
< < _ ( " \n General: \n " )
2009-05-24 03:17:35 +00:00
# ifdef HAVE_OPENMP
2010-11-23 23:46:29 +00:00
< < _ ( " * OpenMP \n " )
2009-05-24 03:17:35 +00:00
# endif /* HAVE_OPENMP */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_MATH
2010-11-13 19:17:46 +00:00
< < _ ( " * math \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_MATH */
# ifdef BUILD_HDDTEMP
2010-11-23 23:46:29 +00:00
< < _ ( " * hddtemp \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_HDDTEMP */
# ifdef BUILD_PORT_MONITORS
2010-11-23 23:46:29 +00:00
< < _ ( " * portmon \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_PORT_MONITORS */
2010-06-04 12:41:12 +00:00
# ifdef BUILD_HTTP
2010-11-23 23:46:29 +00:00
< < _ ( " * HTTP \n " )
2010-06-04 12:41:12 +00:00
# endif
2011-02-11 12:05:00 +00:00
# ifdef BUILD_IPV6
< < _ ( " * IPv6 \n " )
# endif /* BUILD_IPV6 */
2010-04-30 17:32:42 +00:00
# ifdef BUILD_IRC
2010-11-23 23:46:29 +00:00
< < _ ( " * IRC \n " )
2010-04-30 17:32:42 +00:00
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_CURL
2010-11-23 23:46:29 +00:00
< < _ ( " * Curl \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_CURL */
# ifdef BUILD_RSS
2010-11-23 23:46:29 +00:00
< < _ ( " * RSS \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_RSS */
# ifdef BUILD_WEATHER_METAR
2010-11-13 19:17:46 +00:00
< < _ ( " * Weather (METAR) \n " )
2010-01-07 02:38:12 +00:00
# ifdef BUILD_WEATHER_XOAP
2010-11-13 19:17:46 +00:00
< < _ ( " * Weather (XOAP) \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_WEATHER_XOAP */
# endif /* BUILD_WEATHER_METAR */
2010-01-11 00:13:42 +00:00
# ifdef BUILD_WLAN
2010-11-13 19:17:46 +00:00
< < _ ( " * wireless \n " )
2010-01-11 00:13:42 +00:00
# endif /* BUILD_WLAN */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_IBM
2010-11-13 19:17:46 +00:00
< < _ ( " * support for IBM/Lenovo notebooks \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_IBM */
# ifdef BUILD_NVIDIA
2010-11-23 23:46:29 +00:00
< < _ ( " * nvidia \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_NVIDIA */
# ifdef BUILD_EVE
2010-11-13 19:17:46 +00:00
< < _ ( " * eve-online \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_EVE */
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2010-11-13 19:17:46 +00:00
< < _ ( " * builtin default configuration \n " )
2010-01-17 02:00:51 +00:00
# endif /* BUILD_BUILTIN_CONFIG */
2010-11-19 13:27:18 +00:00
# ifdef BUILD_OLD_CONFIG
< < _ ( " * old configuration syntax \n " )
# endif /* BUILD_OLD_CONFIG */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_IMLIB2
2010-11-23 23:46:29 +00:00
< < _ ( " * Imlib2 \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_IMLIB2 */
# ifdef BUILD_MIXER_ALSA
2010-11-13 19:17:46 +00:00
< < _ ( " * ALSA mixer support \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_MIXER_ALSA */
# ifdef BUILD_APCUPSD
2010-11-23 23:46:29 +00:00
< < _ ( " * apcupsd \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_APCUPSD */
# ifdef BUILD_IOSTATS
2010-11-23 23:46:29 +00:00
< < _ ( " * iostats \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_IOSTATS */
# ifdef BUILD_NCURSES
2010-11-23 23:46:29 +00:00
< < _ ( " * ncurses \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_NCURSES */
2010-11-23 23:46:29 +00:00
# ifdef BUILD_I18N
< < _ ( " * Internationalization support \n " )
# endif
# ifdef DEBUG
< < _ ( " * Debugging extensions \n " )
# endif
# if defined BUILD_LUA_CAIRO || defined BUILD_LUA_IMLIB2
< < _ ( " \n Lua bindings: \n " )
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_LUA_CAIRO
2010-11-23 23:46:29 +00:00
< < _ ( " * Cairo \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_LUA_CAIRO */
# ifdef BUILD_LUA_IMLIB2
2010-11-23 23:46:29 +00:00
< < _ ( " * Imlib2 \n " )
2010-01-07 02:38:12 +00:00
# endif /* BUILD_LUA_IMLIB2 */
2010-11-23 23:46:29 +00:00
# ifdef BUILD_X11
< < _ ( " X11: \n " )
# ifdef BUILD_XDAMAGE
< < _ ( " * Xdamage extension \n " )
# endif /* BUILD_XDAMAGE */
# ifdef BUILD_XDBE
< < _ ( " * XDBE (double buffer extension) \n " )
# endif /* BUILD_XDBE */
# ifdef BUILD_XFT
< < _ ( " * Xft \n " )
# endif /* BUILD_XFT */
# ifdef BUILD_ARGB
< < _ ( " * ARGB visual \n " )
# endif /* BUILD_ARGB */
# ifdef OWN_WINDOW
< < _ ( " * Own window \n " )
2010-11-13 18:45:04 +00:00
# endif
2010-11-23 23:46:29 +00:00
# endif /* BUILD_X11 */
2011-05-10 20:40:53 +00:00
# if defined BUILD_AUDACIOUS || defined BUILD_BMPX || defined BUILD_CMUS || defined BUILD_MPD || defined BUILD_MOC || defined BUILD_XMMS2
2010-11-23 23:46:29 +00:00
< < _ ( " \n Music detection: \n " )
2010-11-10 23:31:06 +00:00
# endif
2010-11-23 23:46:29 +00:00
# ifdef BUILD_AUDACIOUS
< < _ ( " * Audacious \n " )
# endif /* BUILD_AUDACIOUS */
# ifdef BUILD_BMPX
< < _ ( " * BMPx \n " )
# endif /* BUILD_BMPX */
2011-05-10 20:40:53 +00:00
# ifdef BUILD_CMUS
< < _ ( " * CMUS \n " )
# endif /* BUILD_CMUS */
2010-11-23 23:46:29 +00:00
# ifdef BUILD_MPD
< < _ ( " * MPD \n " )
# endif /* BUILD_MPD */
# ifdef BUILD_MOC
< < _ ( " * MOC \n " )
# endif /* BUILD_MOC */
# ifdef BUILD_XMMS2
< < _ ( " * XMMS2 \n " )
# endif /* BUILD_XMMS2 */
2010-11-24 17:17:53 +00:00
< < _ ( " \n Default values: \n " )
2012-04-11 16:06:47 +00:00
< < " * Netdevice: " DEFAULTNETDEV " \n "
< < " * Local configfile: " CONFIG_FILE " \n "
2010-11-24 17:17:53 +00:00
# ifdef BUILD_I18N
2012-04-11 16:06:47 +00:00
< < " * Localedir: " LOCALE_DIR " \n "
2010-11-24 17:17:53 +00:00
# endif
# ifdef BUILD_HTTP
< < " * HTTP-port: " < < HTTPPORT < < " \n "
# endif
< < " * Maximum netdevices: " < < MAX_NET_INTERFACES < < " \n "
< < " * Maximum text size: " < < MAX_USER_TEXT_DEFAULT < < " \n "
< < " * Size text buffer: " < < DEFAULT_TEXT_BUFFER_SIZE < < " \n "
2010-11-13 19:17:46 +00:00
;
2006-08-12 06:10:18 +00:00
}
2010-11-13 19:17:46 +00:00
2010-11-13 19:05:59 +00:00
static const char * suffixes [ ] = {
_nop ( " B " ) , _nop ( " KiB " ) , _nop ( " MiB " ) , _nop ( " GiB " ) , _nop ( " TiB " ) , _nop ( " PiB " ) , " "
} ;
2009-08-07 07:24:24 +00:00
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
static void X11_create_window ( void ) ;
struct _x11_stuff_s {
Region region ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2009-08-07 07:24:24 +00:00
Damage damage ;
XserverRegion region2 , part ;
int event_base , error_base ;
2009-05-20 03:34:43 +00:00
# endif
2009-08-07 07:24:24 +00:00
} x11_stuff ;
/* text size */
static int text_start_x , text_start_y ; /* text start position in window */
2010-01-10 21:07:52 +00:00
static int text_width = 1 , text_height = 1 ; /* initially 1 so no zero-sized window is created */
2009-08-07 07:24:24 +00:00
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
/* struct that has all info to be shared between
* instances of the same text object */
struct information info ;
/* path to config file */
2010-03-04 10:42:38 +00:00
std : : string current_config ;
2009-08-07 07:24:24 +00:00
/* set to 1 if you want all text to be in uppercase */
2010-03-07 12:46:58 +00:00
static conky : : simple_config_setting < bool > stuff_in_uppercase ( " uppercase " , false , true ) ;
2009-08-07 07:24:24 +00:00
/* Run how many times? */
2010-08-31 09:49:37 +00:00
static conky : : range_config_setting < unsigned long > total_run_times ( " total_run_times " , 0 ,
std : : numeric_limits < unsigned long > : : max ( ) , 0 , true ) ;
2009-08-07 07:24:24 +00:00
/* fork? */
2010-03-05 12:33:22 +00:00
static conky : : simple_config_setting < bool > fork_to_background ( " background " , false , false ) ;
2009-08-07 07:24:24 +00:00
2010-01-26 21:05:04 +00:00
/* set to 0 after the first time conky is run, so we don't fork again after the
* first forking */
static int first_pass = 1 ;
2010-08-22 10:24:26 +00:00
conky : : range_config_setting < int > cpu_avg_samples ( " cpu_avg_samples " , 1 , 14 , 2 , true ) ;
2010-08-22 10:28:04 +00:00
conky : : range_config_setting < int > net_avg_samples ( " net_avg_samples " , 1 , 14 , 2 , true ) ;
2010-08-22 10:31:11 +00:00
conky : : range_config_setting < int > diskio_avg_samples ( " diskio_avg_samples " , 1 , 14 , 2 , true ) ;
2009-08-07 07:24:24 +00:00
/* filenames for output */
2010-08-22 11:04:19 +00:00
static conky : : simple_config_setting < std : : string > overwrite_file ( " overwrite_file " ,
std : : string ( ) , true ) ;
static FILE * overwrite_fpointer = NULL ;
static conky : : simple_config_setting < std : : string > append_file ( " append_file " ,
std : : string ( ) , true ) ;
static FILE * append_fpointer = NULL ;
2009-08-07 07:24:24 +00:00
2010-06-04 12:41:12 +00:00
# ifdef BUILD_HTTP
std : : string webpage ;
struct MHD_Daemon * httpd ;
2010-06-20 17:15:56 +00:00
static conky : : simple_config_setting < bool > http_refresh ( " http_refresh " , false , true ) ;
2010-06-04 12:41:12 +00:00
int sendanswer ( void * cls , struct MHD_Connection * connection , const char * url , const char * method , const char * version , const char * upload_data , size_t * upload_data_size , void * * con_cls ) {
struct MHD_Response * response = MHD_create_response_from_data ( webpage . length ( ) , ( void * ) webpage . c_str ( ) , MHD_NO , MHD_NO ) ;
int ret = MHD_queue_response ( connection , MHD_HTTP_OK , response ) ;
MHD_destroy_response ( response ) ;
if ( cls | | url | | method | | version | | upload_data | | upload_data_size | | con_cls ) { } //make compiler happy
return ret ;
}
2010-06-20 17:31:17 +00:00
class out_to_http_setting : public conky : : simple_config_setting < bool > {
typedef conky : : simple_config_setting < bool > Base ;
protected :
virtual void lua_setter ( lua : : state & l , bool init )
{
lua : : stack_sentry s ( l , - 2 ) ;
Base : : lua_setter ( l , init ) ;
if ( init & & do_convert ( l , - 1 ) . first ) {
httpd = MHD_start_daemon ( MHD_USE_SELECT_INTERNALLY , HTTPPORT ,
NULL , NULL , & sendanswer , NULL , MHD_OPTION_END ) ;
}
+ + s ;
}
virtual void cleanup ( lua : : state & l )
{
lua : : stack_sentry s ( l , - 1 ) ;
if ( do_convert ( l , - 1 ) . first ) {
MHD_stop_daemon ( httpd ) ;
httpd = NULL ;
}
l . pop ( ) ;
}
public :
out_to_http_setting ( )
: Base ( " out_to_http " , false , false )
{ }
} ;
static out_to_http_setting out_to_http ;
2010-06-04 12:41:12 +00:00
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
2010-03-05 12:37:52 +00:00
static conky : : simple_config_setting < bool > show_graph_scale ( " show_graph_scale " , false , false ) ;
static conky : : simple_config_setting < bool > show_graph_range ( " show_graph_range " , false , false ) ;
2008-04-13 04:10:35 +00:00
2009-08-07 07:24:24 +00:00
/* Position on the screen */
2010-04-23 20:00:32 +00:00
static conky : : simple_config_setting < int > gap_x ( " gap_x " , 5 , true ) ;
static conky : : simple_config_setting < int > gap_y ( " gap_y " , 60 , true ) ;
2009-08-07 07:24:24 +00:00
/* border */
2010-03-05 13:06:15 +00:00
static conky : : simple_config_setting < bool > draw_borders ( " draw_borders " , false , false ) ;
static conky : : simple_config_setting < bool > draw_graph_borders ( " draw_graph_borders " , true , false ) ;
2009-08-07 07:24:24 +00:00
2010-08-25 17:26:15 +00:00
conky : : range_config_setting < char > stippled_borders ( " stippled_borders " , 0 ,
std : : numeric_limits < char > : : max ( ) , 0 , true ) ;
2009-08-07 07:24:24 +00:00
2010-03-05 13:10:47 +00:00
static conky : : simple_config_setting < bool > draw_shades ( " draw_shades " , true , false ) ;
static conky : : simple_config_setting < bool > draw_outline ( " draw_outline " , false , false ) ;
2009-08-07 07:24:24 +00:00
# ifdef OWN_WINDOW
/* fixed size/pos is set if wm/user changes them */
static int fixed_size = 0 , fixed_pos = 0 ;
2005-08-06 00:26:14 +00:00
# endif
2005-07-20 00:30:40 +00:00
2010-08-26 15:40:53 +00:00
static conky : : range_config_setting < int > minimum_height ( " minimum_height " , 0 ,
std : : numeric_limits < int > : : max ( ) , 5 , true ) ;
static conky : : range_config_setting < int > minimum_width ( " minimum_width " , 0 ,
std : : numeric_limits < int > : : max ( ) , 5 , true ) ;
2010-08-25 17:01:02 +00:00
static conky : : range_config_setting < int > maximum_width ( " maximum_width " , 0 ,
std : : numeric_limits < int > : : max ( ) , 0 , true ) ;
2006-05-13 19:51:26 +00:00
2010-04-30 15:51:30 +00:00
static bool isutf8 ( const char * envvar ) {
char * s = getenv ( envvar ) ;
if ( s ) {
std : : string temp = s ;
std : : transform ( temp . begin ( ) , temp . end ( ) , temp . begin ( ) , : : tolower ) ;
if ( ( temp . find ( " utf-8 " ) ! = std : : string : : npos ) | | ( temp . find ( " utf8 " ) ! = std : : string : : npos ) ) {
return true ;
}
}
return false ;
}
/* UTF-8 */
static conky : : simple_config_setting < bool > utf8_mode ( " override_utf8_locale " ,
isutf8 ( " LC_ALL " ) | | isutf8 ( " LC_CTYPE " ) | | isutf8 ( " LANG " ) , false ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
/* maximum size of config TEXT buffer, i.e. below TEXT line. */
2010-08-29 18:01:05 +00:00
conky : : range_config_setting < unsigned int > max_user_text ( " max_user_text " , 47 ,
std : : numeric_limits < unsigned int > : : max ( ) , MAX_USER_TEXT_DEFAULT , false ) ;
2009-08-07 07:24:24 +00:00
/* maximum size of individual text buffers, ie $exec buffer size */
2010-08-29 21:50:32 +00:00
conky : : range_config_setting < unsigned int > text_buffer_size ( " text_buffer_size " ,
DEFAULT_TEXT_BUFFER_SIZE , std : : numeric_limits < unsigned int > : : max ( ) ,
DEFAULT_TEXT_BUFFER_SIZE , false ) ;
2009-08-07 07:24:24 +00:00
/* pad percentages to decimals? */
2010-08-25 17:19:10 +00:00
static conky : : simple_config_setting < int > pad_percents ( " pad_percents " , 0 , false ) ;
2009-08-07 07:24:24 +00:00
static char * global_text = 0 ;
char * get_global_text ( void )
{
return global_text ;
}
long global_text_lines ;
static int total_updates ;
static int updatereset ;
2010-06-26 10:33:55 +00:00
std : : unique_ptr < lua : : state > state ;
2010-02-24 19:51:33 +00:00
2009-08-07 07:24:24 +00:00
void set_updatereset ( int i )
{
updatereset = i ;
}
int get_updatereset ( void )
{
return updatereset ;
}
2009-11-29 18:48:24 +00:00
int get_total_updates ( void )
{
return total_updates ;
}
2010-01-02 21:31:09 +00:00
int calc_text_width ( const char * s )
2009-08-07 07:24:24 +00:00
{
2009-09-20 01:02:56 +00:00
size_t slen = strlen ( s ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( not out_to_x . get ( * state ) ) {
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-09-20 01:02:56 +00:00
return slen ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XFT
2010-04-21 17:33:39 +00:00
if ( use_xft . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XGlyphInfo gi ;
2010-04-30 15:51:30 +00:00
if ( utf8_mode . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XftTextExtentsUtf8 ( display , fonts [ selected_font ] . xftfont ,
2010-01-02 19:43:29 +00:00
( const FcChar8 * ) s , slen , & gi ) ;
2009-08-07 07:24:24 +00:00
} else {
XftTextExtents8 ( display , fonts [ selected_font ] . xftfont ,
2010-01-02 19:43:29 +00:00
( const FcChar8 * ) s , slen , & gi ) ;
2005-07-25 01:13:26 +00:00
}
2009-08-07 07:24:24 +00:00
return gi . xOff ;
} else
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XFT */
2009-08-07 07:24:24 +00:00
{
2009-09-20 01:02:56 +00:00
return XTextWidth ( fonts [ selected_font ] . font , s , slen ) ;
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-11-07 11:21:48 +00:00
}
2005-07-20 00:30:40 +00:00
2009-08-07 07:24:24 +00:00
/* formatted text to render on screen, generated in generate_text(),
* drawn in draw_stuff ( ) */
2005-07-20 00:30:40 +00:00
2009-08-07 07:24:24 +00:00
static char * text_buffer ;
2005-07-20 00:30:40 +00:00
2009-08-07 07:24:24 +00:00
/* quite boring functions */
2005-07-20 00:30:40 +00:00
2009-08-07 07:24:24 +00:00
static inline void for_each_line ( char * b , int f ( char * , int ) )
{
char * ps , * pe ;
int special_index = 0 ; /* specials index */
2005-07-20 00:30:40 +00:00
2010-05-05 16:46:04 +00:00
if ( ! b ) return ;
2009-08-07 07:24:24 +00:00
for ( ps = b , pe = b ; * pe ; pe + + ) {
if ( * pe = = ' \n ' ) {
* pe = ' \0 ' ;
special_index = f ( ps , special_index ) ;
* pe = ' \n ' ;
ps = pe + 1 ;
}
}
2005-07-20 00:30:40 +00:00
2009-08-07 07:24:24 +00:00
if ( ps < pe ) {
f ( ps , special_index ) ;
}
}
static void convert_escapes ( char * buf )
{
char * p = buf , * s = buf ;
while ( * s ) {
if ( * s = = ' \\ ' ) {
s + + ;
if ( * s = = ' n ' ) {
* p + + = ' \n ' ;
} else if ( * s = = ' \\ ' ) {
* p + + = ' \\ ' ;
2008-02-20 20:30:45 +00:00
}
2009-08-07 07:24:24 +00:00
s + + ;
} else {
* p + + = * s + + ;
}
}
* p = ' \0 ' ;
}
2009-08-05 22:46:51 +00:00
2009-08-07 07:24:24 +00:00
/* Prints anything normally printed with snprintf according to the current value
* of use_spacer . Actually slightly more flexible than snprintf , as you can
* safely specify the destination buffer as one of your inputs . */
int spaced_print ( char * buf , int size , const char * format , int width , . . . )
{
int len = 0 ;
va_list argp ;
char * tempbuf ;
2008-11-29 01:34:54 +00:00
2009-08-07 07:24:24 +00:00
if ( size < 1 ) {
return 0 ;
}
2009-12-10 04:05:32 +00:00
tempbuf = ( char * ) malloc ( size * sizeof ( char ) ) ;
2008-11-29 01:34:54 +00:00
2009-08-07 07:24:24 +00:00
// Passes the varargs along to vsnprintf
va_start ( argp , width ) ;
vsnprintf ( tempbuf , size , format , argp ) ;
va_end ( argp ) ;
2008-11-29 01:34:54 +00:00
2010-03-05 20:05:05 +00:00
switch ( use_spacer . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
case NO_SPACER :
len = snprintf ( buf , size , " %s " , tempbuf ) ;
break ;
case LEFT_SPACER :
len = snprintf ( buf , size , " %*s " , width , tempbuf ) ;
break ;
case RIGHT_SPACER :
len = snprintf ( buf , size , " %-*s " , width , tempbuf ) ;
break ;
}
free ( tempbuf ) ;
return len ;
}
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
/* print percentage values
*
* - i . e . , unsigned values between 0 and 100
* - respect the value of pad_percents */
2009-10-04 14:53:21 +00:00
int percent_print ( char * buf , int size , unsigned value )
2009-08-07 07:24:24 +00:00
{
2010-08-25 17:19:10 +00:00
return spaced_print ( buf , size , " %u " , pad_percents . get ( * state ) , value ) ;
2009-08-07 07:24:24 +00:00
}
2008-12-08 23:07:32 +00:00
2010-02-14 13:00:26 +00:00
# if defined(__FreeBSD__)
unsigned long long llabs ( long long num ) {
if ( num < 0 ) return - num ;
else return num ;
}
# endif
2009-08-07 07:24:24 +00:00
/* converts from bytes to human readable format (K, M, G, T)
*
* The algorithm always divides by 1024 , as unit - conversion of byte
* counts suggests . But for output length determination we need to
* compare with 1000 here , as we print in decimal form . */
2009-10-04 14:53:21 +00:00
void human_readable ( long long num , char * buf , int size )
2009-08-07 07:24:24 +00:00
{
const char * * suffix = suffixes ;
float fnum ;
int precision ;
int width ;
const char * format ;
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
/* Possibly just output as usual, for example for stdout usage */
2010-03-07 12:44:33 +00:00
if ( not format_human_readable . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
spaced_print ( buf , size , " %d " , 6 , round_to_int ( num ) ) ;
return ;
}
2011-09-18 17:16:14 +00:00
if ( short_units . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
width = 5 ;
format = " %.*f%.1s " ;
} else {
width = 7 ;
format = " %.*f%-3s " ;
}
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
if ( llabs ( num ) < 1000LL ) {
2010-10-31 19:01:20 +00:00
spaced_print ( buf , size , format , width , 0 , ( float ) num , _ ( * suffix ) ) ;
2009-08-07 07:24:24 +00:00
return ;
}
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
while ( llabs ( num / 1024 ) > = 1000LL & & * * ( suffix + 2 ) ) {
num / = 1024 ;
suffix + + ;
}
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
suffix + + ;
fnum = num / 1024.0 ;
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
/* fnum should now be < 1000, so looks like 'AAA.BBBBB'
*
* The goal is to always have a significance of 3 , by
* adjusting the decimal part of the number . Sample output :
* 123 MiB
* 23.4 GiB
2009-12-28 20:21:28 +00:00
* 5.12 B
2009-08-07 07:24:24 +00:00
* so the point of alignment resides between number and unit . The
* upside of this is that there is minimal padding necessary , though
* there should be a way to make alignment take place at the decimal
2009-12-28 20:21:28 +00:00
* dot ( then with fixed width decimal part ) .
2009-08-07 07:24:24 +00:00
*
* Note the repdigits below : when given a precision value , printf ( )
* rounds the float to it , not just cuts off the remaining digits . So
* e . g . 99.95 with a precision of 1 gets 100.0 , which again should be
* printed with a precision of 0. Yay . */
2008-11-29 01:34:54 +00:00
2009-08-07 07:24:24 +00:00
precision = 0 ; /* print 100-999 without decimal part */
if ( fnum < 99.95 )
precision = 1 ; /* print 10-99 with one decimal place */
if ( fnum < 9.995 )
precision = 2 ; /* print 0-9 with two decimal places */
2009-05-13 00:05:51 +00:00
2010-10-31 19:01:20 +00:00
spaced_print ( buf , size , format , width , precision , fnum , _ ( * suffix ) ) ;
2009-08-07 07:24:24 +00:00
}
2009-05-13 00:05:51 +00:00
2009-08-07 07:24:24 +00:00
/* global object list root element */
static struct text_object global_root_object ;
2008-12-08 23:07:32 +00:00
2009-08-07 07:24:24 +00:00
static long current_text_color ;
void set_current_text_color ( long colour )
{
current_text_color = colour ;
}
long get_current_text_color ( void )
{
return current_text_color ;
}
static void extract_variable_text ( const char * p )
{
2009-11-29 20:24:03 +00:00
free_text_objects ( & global_root_object ) ;
2010-02-20 14:28:05 +00:00
free_and_zero ( tmpstring1 ) ;
free_and_zero ( tmpstring2 ) ;
free_and_zero ( text_buffer ) ;
2009-08-07 07:24:24 +00:00
extract_variable_text_internal ( & global_root_object , p ) ;
}
2009-11-16 01:15:13 +00:00
void parse_conky_vars ( struct text_object * root , const char * txt ,
2009-11-29 19:43:46 +00:00
char * p , int p_max_size )
2009-08-07 07:24:24 +00:00
{
extract_variable_text_internal ( root , txt ) ;
2009-11-29 19:43:46 +00:00
generate_text_internal ( p , p_max_size , * root ) ;
2009-08-07 07:24:24 +00:00
}
2009-11-29 19:34:23 +00:00
/* IFBLOCK jumping algorithm
*
* This is easier as it looks like :
* - each IF checks it ' s condition
* - on FALSE : jump
* - on TRUE : don ' t care
* - each ELSE jumps unconditionally
* - each ENDIF is silently being ignored
*
* Why this works ( or : how jumping works ) :
* Jumping means to overwrite the " obj " variable of the loop and set it to the
* target ( i . e . the corresponding ELSE or ENDIF ) . After that , the for - loop does
* the rest : as regularly , " obj " is being updated to point to obj - > next , so
* object parsing continues right after the corresponding ELSE or ENDIF . This
* means that if we find an ELSE , it ' s corresponding IF must not have jumped ,
* so we need to jump always . If we encounter an ENDIF , it ' s corresponding IF
* or ELSE has not jumped , and there is nothing to do .
*/
2009-11-29 19:43:46 +00:00
void generate_text_internal ( char * p , int p_max_size , struct text_object root )
2009-08-07 07:24:24 +00:00
{
struct text_object * obj ;
2009-11-29 19:34:23 +00:00
size_t a ;
2010-05-05 16:46:04 +00:00
if ( ! p ) return ;
2010-01-20 17:17:30 +00:00
# ifdef BUILD_ICONV
2009-12-17 21:19:58 +00:00
char * buff_in ;
buff_in = ( char * ) malloc ( p_max_size ) ;
memset ( buff_in , 0 , p_max_size ) ;
2010-01-20 17:17:30 +00:00
# endif /* BUILD_ICONV */
2009-08-07 07:24:24 +00:00
p [ 0 ] = 0 ;
obj = root . next ;
while ( obj & & p_max_size > 0 ) {
2009-11-29 19:34:23 +00:00
/* check callbacks for existence and act accordingly */
2009-11-19 23:25:45 +00:00
if ( obj - > callbacks . print ) {
( * obj - > callbacks . print ) ( obj , p , p_max_size ) ;
2009-11-29 19:34:23 +00:00
} else if ( obj - > callbacks . iftest ) {
if ( ! ( * obj - > callbacks . iftest ) ( obj ) ) {
DBGP2 ( " jumping " ) ;
if ( obj - > ifblock_next )
obj = obj - > ifblock_next ;
}
} else if ( obj - > callbacks . barval ) {
2009-11-19 23:25:45 +00:00
new_bar ( obj , p , p_max_size , ( * obj - > callbacks . barval ) ( obj ) ) ;
2009-11-29 19:34:23 +00:00
} else if ( obj - > callbacks . gaugeval ) {
2009-11-19 23:25:45 +00:00
new_gauge ( obj , p , p_max_size , ( * obj - > callbacks . gaugeval ) ( obj ) ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-11-29 19:34:23 +00:00
} else if ( obj - > callbacks . graphval ) {
2009-11-19 23:25:45 +00:00
new_graph ( obj , p , p_max_size , ( * obj - > callbacks . graphval ) ( obj ) ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-11-29 19:34:23 +00:00
} else if ( obj - > callbacks . percentage ) {
2009-11-19 23:25:45 +00:00
percent_print ( p , p_max_size , ( * obj - > callbacks . percentage ) ( obj ) ) ;
}
2009-11-29 19:34:23 +00:00
a = strlen ( p ) ;
2010-01-20 17:17:30 +00:00
# ifdef BUILD_ICONV
2009-11-29 19:34:23 +00:00
iconv_convert ( & a , buff_in , p , p_max_size ) ;
2010-01-20 17:17:30 +00:00
# endif /* BUILD_ICONV */
2009-11-29 19:34:23 +00:00
p + = a ;
p_max_size - = a ;
( * p ) = 0 ;
2009-08-07 07:24:24 +00:00
obj = obj - > next ;
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
/* load any new fonts we may have had */
2010-11-26 16:59:07 +00:00
load_fonts ( utf8_mode . get ( * state ) ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-01-20 17:17:30 +00:00
# ifdef BUILD_ICONV
2009-12-17 21:19:58 +00:00
free ( buff_in ) ;
2010-01-20 17:17:30 +00:00
# endif /* BUILD_ICONV */
2009-08-07 07:24:24 +00:00
}
2009-11-16 01:15:13 +00:00
void evaluate ( const char * text , char * p , int p_max_size )
2009-08-07 07:24:24 +00:00
{
struct text_object subroot ;
2009-11-29 19:43:46 +00:00
parse_conky_vars ( & subroot , text , p , p_max_size ) ;
2010-01-03 07:59:24 +00:00
DBGP2 ( " evaluated '%s' to '%s' " , text , p ) ;
2009-08-07 07:24:24 +00:00
2009-11-29 20:24:03 +00:00
free_text_objects ( & subroot ) ;
2009-08-07 07:24:24 +00:00
}
double current_update_time , next_update_time , last_update_time ;
static void generate_text ( void )
{
char * p ;
2009-11-25 15:04:49 +00:00
unsigned int i , j , k ;
2009-08-07 07:24:24 +00:00
special_count = 0 ;
/* update info */
current_update_time = get_time ( ) ;
update_stuff ( ) ;
/* add things to the buffer */
/* generate text */
p = text_buffer ;
2010-08-29 18:01:05 +00:00
generate_text_internal ( p , max_user_text . get ( * state ) , global_root_object ) ;
2010-08-22 11:04:19 +00:00
unsigned int mw = max_text_width . get ( * state ) ;
2010-08-29 21:50:32 +00:00
unsigned int tbs = text_buffer_size . get ( * state ) ;
2010-08-22 10:49:31 +00:00
if ( mw > 0 ) {
2009-11-25 15:04:49 +00:00
for ( i = 0 , j = 0 ; p [ i ] ! = 0 ; i + + ) {
if ( p [ i ] = = ' \n ' ) j = 0 ;
2010-08-22 10:49:31 +00:00
else if ( j = = mw ) {
2009-11-25 15:04:49 +00:00
k = i + strlen ( p + i ) + 1 ;
2010-08-29 21:50:32 +00:00
if ( k < tbs ) {
2009-11-25 15:04:49 +00:00
while ( k ! = i ) {
p [ k ] = p [ k - 1 ] ;
k - - ;
}
p [ k ] = ' \n ' ;
j = 0 ;
} else NORM_ERR ( " The end of the text_buffer is reached, increase \" text_buffer_size \" " ) ;
} else j + + ;
}
}
2009-08-07 07:24:24 +00:00
2010-03-07 12:46:58 +00:00
if ( stuff_in_uppercase . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
char * tmp_p ;
tmp_p = text_buffer ;
while ( * tmp_p ) {
* tmp_p = toupper ( * tmp_p ) ;
tmp_p + + ;
}
}
2010-09-11 12:25:19 +00:00
double ui = active_update_interval ( ) ;
next_update_time + = ui ;
2009-08-07 07:24:24 +00:00
if ( next_update_time < get_time ( ) ) {
2010-09-11 12:25:19 +00:00
next_update_time = get_time ( ) + ui ;
} else if ( next_update_time > get_time ( ) + ui ) {
next_update_time = get_time ( ) + ui ;
2009-08-07 07:24:24 +00:00
}
last_update_time = current_update_time ;
total_updates + + ;
}
2010-01-02 21:31:09 +00:00
int get_string_width ( const char * s )
2009-08-07 07:24:24 +00:00
{
2009-09-20 01:02:56 +00:00
return * s ? calc_text_width ( s ) : 0 ;
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-04-22 23:22:22 +00:00
static inline int get_border_total ( )
{
return border_inner_margin . get ( * state ) + border_outer_margin . get ( * state ) +
border_width . get ( * state ) ;
}
2009-08-07 07:24:24 +00:00
static int get_string_width_special ( char * s , int special_index )
{
char * p , * final ;
2010-04-21 16:03:53 +00:00
special_t * current = specials ;
2009-08-07 07:24:24 +00:00
int idx = 1 ;
int width = 0 ;
long i ;
2009-09-20 01:17:55 +00:00
if ( ! s )
2009-08-07 07:24:24 +00:00
return 0 ;
2009-09-20 01:17:55 +00:00
2010-02-25 21:28:34 +00:00
if ( not out_to_x . get ( * state ) )
2009-09-20 01:17:55 +00:00
return strlen ( s ) ;
2009-08-07 07:24:24 +00:00
2010-08-29 21:50:32 +00:00
p = strndup ( s , text_buffer_size . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
final = p ;
2010-04-21 16:03:53 +00:00
for ( i = 0 ; i < special_index ; i + + )
current = current - > next ;
for ( i = 0 ; i < idx ; i + + )
current = current - > next ;
2009-08-07 07:24:24 +00:00
while ( * p ) {
if ( * p = = SPECIAL_CHAR ) {
/* shift everything over by 1 so that the special char
* doesn ' t mess up the size calculation */
for ( i = 0 ; i < ( long ) strlen ( p ) ; i + + ) {
* ( p + i ) = * ( p + i + 1 ) ;
}
2010-04-21 16:03:53 +00:00
if ( current - > type = = GRAPH
| | current - > type = = GAUGE
| | current - > type = = BAR ) {
width + = current - > width ;
2009-08-07 07:24:24 +00:00
}
2012-01-12 19:55:11 +00:00
if ( current - > type = = FONT ) {
//put all following text until the next fontchange/stringend in influenced_by_font but do not include specials
char * influenced_by_font = strdup ( p ) ;
special_t * current_after_font = current ;
for ( i = 0 ; influenced_by_font [ i ] ! = 0 ; i + + ) {
if ( influenced_by_font [ i ] = = SPECIAL_CHAR ) {
//remove specials and stop at fontchange
current_after_font = current_after_font - > next ;
if ( current_after_font - > type = = FONT ) {
influenced_by_font [ i ] = 0 ;
break ;
} else strcpy ( & influenced_by_font [ i ] , & influenced_by_font [ i + 1 ] ) ;
}
}
//add the length of influenced_by_font in the new font to width
int orig_font = selected_font ;
selected_font = current - > font_added ;
width + = calc_text_width ( influenced_by_font ) ;
selected_font = orig_font ;
free ( influenced_by_font ) ;
//make sure there chars counted in the new font are not again counted in the old font
int specials_skipped = 0 ;
while ( i > 0 ) {
if ( p [ specials_skipped ] ! = 1 ) strcpy ( & p [ specials_skipped ] , & p [ specials_skipped + 1 ] ) ; else specials_skipped + + ;
i - - ;
}
}
2009-08-07 07:24:24 +00:00
idx + + ;
2010-04-21 16:03:53 +00:00
current = current - > next ;
2009-08-07 07:24:24 +00:00
} else {
p + + ;
}
}
if ( strlen ( final ) > 1 ) {
2009-09-20 01:02:56 +00:00
width + = calc_text_width ( final ) ;
2009-08-07 07:24:24 +00:00
}
free ( final ) ;
return width ;
}
static int text_size_updater ( char * s , int special_index ) ;
int last_font_height ;
static void update_text_area ( void )
{
int x = 0 , y = 0 ;
2010-02-25 21:28:34 +00:00
if ( not out_to_x . get ( * state ) )
2009-08-07 07:24:24 +00:00
return ;
/* update text size if it isn't fixed */
# ifdef OWN_WINDOW
if ( ! fixed_size )
# endif
{
2010-08-26 15:40:53 +00:00
text_width = minimum_width . get ( * state ) ;
2009-08-07 07:24:24 +00:00
text_height = 0 ;
last_font_height = font_height ( ) ;
for_each_line ( text_buffer , text_size_updater ) ;
text_width + = 1 ;
2010-08-26 15:40:53 +00:00
if ( text_height < minimum_height . get ( * state ) ) {
text_height = minimum_height . get ( * state ) ;
2009-08-07 07:24:24 +00:00
}
2010-08-25 17:01:02 +00:00
int mw = maximum_width . get ( * state ) ;
if ( text_width > mw & & mw > 0 ) {
text_width = mw ;
2009-08-07 07:24:24 +00:00
}
}
2010-02-24 19:51:33 +00:00
alignment align = text_alignment . get ( * state ) ;
2009-08-07 07:24:24 +00:00
/* get text position on workarea */
2010-02-24 19:51:33 +00:00
switch ( align ) {
2009-11-13 20:35:49 +00:00
case TOP_LEFT : case TOP_RIGHT : case TOP_MIDDLE :
2010-04-23 20:00:32 +00:00
y = gap_y . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
case BOTTOM_LEFT : case BOTTOM_RIGHT : case BOTTOM_MIDDLE : default :
2010-04-23 20:00:32 +00:00
y = workarea [ 3 ] - text_height - gap_y . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
case MIDDLE_LEFT : case MIDDLE_RIGHT : case MIDDLE_MIDDLE :
2010-04-23 20:00:32 +00:00
y = workarea [ 3 ] / 2 - text_height / 2 - gap_y . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
}
2010-02-24 19:51:33 +00:00
switch ( align ) {
2009-11-13 20:35:49 +00:00
case TOP_LEFT : case BOTTOM_LEFT : case MIDDLE_LEFT : default :
2010-04-23 20:00:32 +00:00
x = gap_x . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
case TOP_RIGHT : case BOTTOM_RIGHT : case MIDDLE_RIGHT :
2010-04-23 20:00:32 +00:00
x = workarea [ 2 ] - text_width - gap_x . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
case TOP_MIDDLE : case BOTTOM_MIDDLE : case MIDDLE_MIDDLE :
2010-04-23 20:00:32 +00:00
x = workarea [ 2 ] / 2 - text_width / 2 - gap_x . get ( * state ) ;
2009-08-07 07:24:24 +00:00
break ;
2009-11-13 20:35:49 +00:00
}
2009-08-07 07:24:24 +00:00
# ifdef OWN_WINDOW
2010-02-24 19:51:33 +00:00
if ( align = = NONE ) { // Let the WM manage the window
2009-08-07 07:24:24 +00:00
x = window . x ;
y = window . y ;
fixed_pos = 1 ;
fixed_size = 1 ;
}
2009-11-13 20:35:49 +00:00
# endif /* OWN_WINDOW */
2009-08-07 07:24:24 +00:00
# ifdef OWN_WINDOW
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) & & ! fixed_pos ) {
2009-08-07 07:24:24 +00:00
x + = workarea [ 0 ] ;
y + = workarea [ 1 ] ;
2010-03-12 18:27:07 +00:00
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2010-03-12 18:27:07 +00:00
text_start_x = text_start_y = border_total ;
window . x = x - border_total ;
window . y = y - border_total ;
2009-08-07 07:24:24 +00:00
} else
# endif
{
/* If window size doesn't match to workarea's size,
* then window probably includes panels ( gnome ) .
* Blah , doesn ' t work on KDE . */
if ( workarea [ 2 ] ! = window . width | | workarea [ 3 ] ! = window . height ) {
y + = workarea [ 1 ] ;
x + = workarea [ 0 ] ;
}
text_start_x = x ;
text_start_y = y ;
}
/* update lua window globals */
llua_update_window_table ( text_start_x , text_start_y , text_width , text_height ) ;
}
/* drawing stuff */
static int cur_x , cur_y ; /* current x and y for drawing */
# endif
2010-01-07 02:38:12 +00:00
//draw_mode also without BUILD_X11 because we only need to print to stdout with FG
2009-08-07 07:24:24 +00:00
static int draw_mode ; /* FG, BG or OUTLINE */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
static long current_color ;
static int text_size_updater ( char * s , int special_index )
{
int w = 0 ;
char * p ;
2010-04-21 16:03:53 +00:00
special_t * current = specials ;
for ( int i = 0 ; i < special_index ; i + + )
current = current - > next ;
2009-08-07 07:24:24 +00:00
2010-02-25 21:28:34 +00:00
if ( not out_to_x . get ( * state ) )
2009-08-07 07:24:24 +00:00
return 0 ;
/* get string widths and skip specials */
p = s ;
while ( * p ) {
if ( * p = = SPECIAL_CHAR ) {
* p = ' \0 ' ;
w + = get_string_width ( s ) ;
* p = SPECIAL_CHAR ;
2010-04-21 16:03:53 +00:00
if ( current - > type = = BAR
| | current - > type = = GAUGE
| | current - > type = = GRAPH ) {
w + = current - > width ;
if ( current - > height > last_font_height ) {
last_font_height = current - > height ;
2009-08-07 07:24:24 +00:00
last_font_height + = font_height ( ) ;
}
2010-04-21 16:03:53 +00:00
} else if ( current - > type = = OFFSET ) {
if ( current - > arg > 0 ) {
w + = current - > arg ;
2009-08-07 07:24:24 +00:00
}
2010-04-21 16:03:53 +00:00
} else if ( current - > type = = VOFFSET ) {
last_font_height + = current - > arg ;
} else if ( current - > type = = GOTO ) {
if ( current - > arg > cur_x ) {
w = ( int ) current - > arg ;
2009-08-07 07:24:24 +00:00
}
2010-04-21 16:03:53 +00:00
} else if ( current - > type = = TAB ) {
int start = current - > arg ;
int step = current - > width ;
2009-08-07 07:24:24 +00:00
if ( ! step | | step < 0 ) {
step = 10 ;
}
w + = step - ( cur_x - text_start_x - start ) % step ;
2010-04-21 16:03:53 +00:00
} else if ( current - > type = = FONT ) {
selected_font = current - > font_added ;
2009-08-07 07:24:24 +00:00
if ( font_height ( ) > last_font_height ) {
last_font_height = font_height ( ) ;
}
}
special_index + + ;
2010-04-21 16:03:53 +00:00
current = current - > next ;
2009-08-07 07:24:24 +00:00
s = p + 1 ;
}
p + + ;
}
2011-10-10 18:51:35 +00:00
w + = get_string_width ( s ) ;
2009-08-07 07:24:24 +00:00
if ( w > text_width ) {
text_width = w ;
}
2010-08-25 17:01:02 +00:00
int mw = maximum_width . get ( * state ) ;
if ( text_width > mw & & mw > 0 ) {
text_width = mw ;
2009-08-07 07:24:24 +00:00
}
text_height + = last_font_height ;
last_font_height = font_height ( ) ;
return special_index ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
static inline void set_foreground_color ( long c )
{
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2010-01-07 02:38:12 +00:00
# ifdef BUILD_ARGB
2010-01-01 23:01:51 +00:00
if ( have_argb_visual ) {
2010-02-27 21:28:33 +00:00
current_color = c | ( own_window_argb_value . get ( * state ) < < 24 ) ;
2010-01-01 23:01:51 +00:00
} else {
2010-01-07 02:38:12 +00:00
# endif /* BUILD_ARGB */
2010-01-01 23:01:51 +00:00
current_color = c ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_ARGB
2010-01-01 23:01:51 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_ARGB */
2010-01-01 23:01:51 +00:00
XSetForeground ( display , window . gc , current_color ) ;
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2010-04-30 17:33:21 +00:00
if ( out_to_ncurses . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
attron ( COLOR_PAIR ( c ) ) ;
}
2010-02-16 16:00:33 +00:00
# endif /* BUILD_NCURSES */
2009-08-07 07:24:24 +00:00
UNUSED ( c ) ;
return ;
}
2010-06-05 12:05:08 +00:00
std : : string string_replace_all ( std : : string original , std : : string oldpart , std : : string newpart , std : : string : : size_type start ) {
std : : string : : size_type i = start ;
int oldpartlen = oldpart . length ( ) ;
while ( 1 ) {
i = original . find ( oldpart , i ) ;
if ( i = = std : : string : : npos ) break ;
original . replace ( i , oldpartlen , newpart ) ;
}
return original ;
}
2009-08-07 07:24:24 +00:00
static void draw_string ( const char * s )
{
int i , i2 , pos , width_of_s ;
int max = 0 ;
int added ;
if ( s [ 0 ] = = ' \0 ' ) {
return ;
}
width_of_s = get_string_width ( s ) ;
2010-04-30 17:06:17 +00:00
if ( out_to_stdout . get ( * state ) & & draw_mode = = FG ) {
2011-10-10 18:51:35 +00:00
printf ( " %s \n " , s ) ;
2010-03-05 19:58:39 +00:00
if ( extra_newline . get ( * state ) ) fputc ( ' \n ' , stdout ) ;
2009-08-07 07:24:24 +00:00
fflush ( stdout ) ; /* output immediately, don't buffer */
}
2010-04-30 17:06:17 +00:00
if ( out_to_stderr . get ( * state ) & & draw_mode = = FG ) {
2011-10-10 18:51:35 +00:00
fprintf ( stderr , " %s \n " , s ) ;
2009-08-07 07:24:24 +00:00
fflush ( stderr ) ; /* output immediately, don't buffer */
}
2010-08-22 11:04:19 +00:00
if ( draw_mode = = FG & & overwrite_fpointer ) {
2011-10-10 18:51:35 +00:00
fprintf ( overwrite_fpointer , " %s \n " , s ) ;
2009-08-07 07:24:24 +00:00
}
2010-08-22 11:04:19 +00:00
if ( draw_mode = = FG & & append_fpointer ) {
2011-10-10 18:51:35 +00:00
fprintf ( append_fpointer , " %s \n " , s ) ;
2009-08-07 07:24:24 +00:00
}
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2010-04-30 17:33:21 +00:00
if ( out_to_ncurses . get ( * state ) & & draw_mode = = FG ) {
2011-10-10 18:51:35 +00:00
printw ( " %s " , s ) ;
2009-08-07 07:24:24 +00:00
}
2010-06-04 12:41:12 +00:00
# endif
# ifdef BUILD_HTTP
2010-06-20 17:31:17 +00:00
if ( out_to_http . get ( * state ) & & draw_mode = = FG ) {
2010-06-05 12:05:08 +00:00
std : : string : : size_type origlen = webpage . length ( ) ;
2011-10-10 18:51:35 +00:00
webpage . append ( s ) ;
2010-06-05 12:05:08 +00:00
webpage = string_replace_all ( webpage , " \n " , " <br /> " , origlen ) ;
webpage = string_replace_all ( webpage , " " , " " , origlen ) ;
webpage = string_replace_all ( webpage , " " , " " , origlen ) ;
2010-06-04 12:41:12 +00:00
webpage . append ( " <br /> " ) ;
}
2009-08-07 07:24:24 +00:00
# endif
2010-08-29 21:50:32 +00:00
int tbs = text_buffer_size . get ( * state ) ;
memset ( tmpstring1 , 0 , tbs ) ;
memset ( tmpstring2 , 0 , tbs ) ;
strncpy ( tmpstring1 , s , tbs - 1 ) ;
2009-08-07 07:24:24 +00:00
pos = 0 ;
added = 0 ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
max = ( ( text_width - width_of_s ) / get_string_width ( " " ) ) ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
/* This code looks for tabs in the text and coverts them to spaces.
* The trick is getting the correct number of spaces , and not going
* over the window ' s size without forcing the window larger . */
2010-08-29 21:50:32 +00:00
for ( i = 0 ; i < tbs ; i + + ) {
2009-08-07 07:24:24 +00:00
if ( tmpstring1 [ i ] = = ' \t ' ) {
i2 = 0 ;
for ( i2 = 0 ; i2 < ( 8 - ( 1 + pos ) % 8 ) & & added < = max ; i2 + + ) {
/* guard against overrun */
2010-08-29 21:50:32 +00:00
tmpstring2 [ MIN ( pos + i2 , tbs - 1 ) ] = ' ' ;
2009-08-07 07:24:24 +00:00
added + + ;
}
pos + = i2 ;
} else {
/* guard against overrun */
2010-08-29 21:50:32 +00:00
tmpstring2 [ MIN ( pos , tbs - 1 ) ] = tmpstring1 [ i ] ;
2009-08-07 07:24:24 +00:00
pos + + ;
}
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2010-08-25 17:01:02 +00:00
int mw = maximum_width . get ( * state ) ;
if ( text_width = = mw ) {
2009-08-07 07:24:24 +00:00
/* this means the text is probably pushing the limit,
* so we ' ll chop it */
2010-08-25 17:01:02 +00:00
while ( cur_x + get_string_width ( tmpstring2 ) - text_start_x > mw
& & strlen ( tmpstring2 ) > 0 ) {
2009-08-07 07:24:24 +00:00
tmpstring2 [ strlen ( tmpstring2 ) - 1 ] = ' \0 ' ;
}
}
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
s = tmpstring2 ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XFT
2010-04-21 17:33:39 +00:00
if ( use_xft . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XColor c ;
XftColor c2 ;
c . pixel = current_color ;
2010-01-01 23:01:51 +00:00
// query color on custom colormap
XQueryColor ( display , window . colourmap , & c ) ;
2009-08-07 07:24:24 +00:00
c2 . pixel = c . pixel ;
c2 . color . red = c . red ;
c2 . color . green = c . green ;
c2 . color . blue = c . blue ;
c2 . color . alpha = fonts [ selected_font ] . font_alpha ;
2010-04-30 15:51:30 +00:00
if ( utf8_mode . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XftDrawStringUtf8 ( window . xftdraw , & c2 , fonts [ selected_font ] . xftfont ,
cur_x , cur_y , ( const XftChar8 * ) s , strlen ( s ) ) ;
} else {
XftDrawString8 ( window . xftdraw , & c2 , fonts [ selected_font ] . xftfont ,
cur_x , cur_y , ( const XftChar8 * ) s , strlen ( s ) ) ;
}
} else
# endif
{
2010-11-26 16:59:07 +00:00
if ( utf8_mode . get ( * state ) ) {
Xutf8DrawString ( display , window . drawable , fonts [ selected_font ] . fontset , window . gc , cur_x , cur_y , s ,
strlen ( s ) ) ;
} else {
XDrawString ( display , window . drawable , window . gc , cur_x , cur_y , s ,
strlen ( s ) ) ;
}
2009-08-07 07:24:24 +00:00
}
cur_x + = width_of_s ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-08-29 21:50:32 +00:00
memcpy ( tmpstring1 , s , tbs ) ;
2009-08-07 07:24:24 +00:00
}
int draw_each_line_inner ( char * s , int special_index , int last_special_applied )
{
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-12-17 21:32:28 +00:00
int font_h = 0 ;
2009-08-07 07:24:24 +00:00
int cur_y_add = 0 ;
2010-08-25 17:01:02 +00:00
int mw = maximum_width . get ( * state ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
char * p = s ;
int last_special_needed = - 1 ;
int orig_special_index = special_index ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-09-20 01:48:00 +00:00
font_h = font_height ( ) ;
cur_y + = font_ascent ( ) ;
}
2009-08-07 07:24:24 +00:00
cur_x = text_start_x ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
while ( * p ) {
if ( * p = = SPECIAL_CHAR | | last_special_applied > - 1 ) {
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
int w = 0 ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
/* draw string before special, unless we're dealing multiline
* specials */
if ( last_special_applied > - 1 ) {
special_index = last_special_applied ;
} else {
* p = ' \0 ' ;
draw_string ( s ) ;
* p = SPECIAL_CHAR ;
s = p + 1 ;
}
/* draw special */
2010-04-21 16:03:53 +00:00
special_t * current = specials ;
for ( int i = 0 ; i < special_index ; i + + )
current = current - > next ;
switch ( current - > type ) {
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
case HORIZONTAL_LINE :
{
2010-04-21 16:03:53 +00:00
int h = current - > height ;
2009-08-07 07:24:24 +00:00
int mid = font_ascent ( ) / 2 ;
w = text_start_x + text_width - cur_x ;
XSetLineAttributes ( display , window . gc , h , LineSolid ,
CapButt , JoinMiter ) ;
XDrawLine ( display , window . drawable , window . gc , cur_x ,
cur_y - mid / 2 , cur_x + w , cur_y - mid / 2 ) ;
break ;
}
case STIPPLED_HR :
{
2010-04-21 16:03:53 +00:00
int h = current - > height ;
char tmp_s = current - > arg ;
2009-08-07 07:24:24 +00:00
int mid = font_ascent ( ) / 2 ;
char ss [ 2 ] = { tmp_s , tmp_s } ;
w = text_start_x + text_width - cur_x - 1 ;
XSetLineAttributes ( display , window . gc , h , LineOnOffDash ,
CapButt , JoinMiter ) ;
XSetDashes ( display , window . gc , 0 , ss , 2 ) ;
XDrawLine ( display , window . drawable , window . gc , cur_x ,
cur_y - mid / 2 , cur_x + w , cur_y - mid / 2 ) ;
break ;
}
case BAR :
{
2009-12-04 00:11:57 +00:00
int h , by ;
double bar_usage , scale ;
2010-08-25 17:01:02 +00:00
if ( cur_x - text_start_x > mw & & mw > 0 ) {
2009-08-07 07:24:24 +00:00
break ;
}
2010-04-21 16:03:53 +00:00
h = current - > height ;
bar_usage = current - > arg ;
scale = current - > scale ;
2009-08-07 07:24:24 +00:00
by = cur_y - ( font_ascent ( ) / 2 ) - 1 ;
if ( h < font_h ) {
by - = h / 2 - 1 ;
}
2010-04-21 16:03:53 +00:00
w = current - > width ;
2009-08-07 07:24:24 +00:00
if ( w = = 0 ) {
w = text_start_x + text_width - cur_x - 1 ;
}
if ( w < 0 ) {
w = 0 ;
}
XSetLineAttributes ( display , window . gc , 1 , LineSolid ,
CapButt , JoinMiter ) ;
XDrawRectangle ( display , window . drawable , window . gc , cur_x ,
by , w , h ) ;
XFillRectangle ( display , window . drawable , window . gc , cur_x ,
2009-12-01 23:21:38 +00:00
by , w * bar_usage / scale , h ) ;
2009-08-07 07:24:24 +00:00
if ( h > cur_y_add
& & h > font_h ) {
cur_y_add = h ;
}
break ;
}
case GAUGE : /* new GAUGE */
{
int h , by = 0 ;
unsigned long last_colour = current_color ;
# ifdef MATH
float angle , px , py ;
2009-12-04 00:11:57 +00:00
double usage , scale ;
2009-08-07 07:24:24 +00:00
# endif /* MATH */
2010-08-25 17:01:02 +00:00
if ( cur_x - text_start_x > mw & & mw > 0 ) {
2009-08-07 07:24:24 +00:00
break ;
}
2010-04-21 16:03:53 +00:00
h = current - > height ;
2009-08-07 07:24:24 +00:00
by = cur_y - ( font_ascent ( ) / 2 ) - 1 ;
if ( h < font_h ) {
by - = h / 2 - 1 ;
}
2010-04-21 16:03:53 +00:00
w = current - > width ;
2009-08-07 07:24:24 +00:00
if ( w = = 0 ) {
w = text_start_x + text_width - cur_x - 1 ;
}
if ( w < 0 ) {
w = 0 ;
}
XSetLineAttributes ( display , window . gc , 1 , LineSolid ,
CapButt , JoinMiter ) ;
XDrawArc ( display , window . drawable , window . gc ,
cur_x , by , w , h * 2 , 0 , 180 * 64 ) ;
# ifdef MATH
2010-04-21 16:03:53 +00:00
usage = current - > arg ;
scale = current - > scale ;
2009-12-04 00:11:57 +00:00
angle = M_PI * usage / scale ;
2009-08-07 07:24:24 +00:00
px = ( float ) ( cur_x + ( w / 2. ) ) - ( float ) ( w / 2. ) * cos ( angle ) ;
py = ( float ) ( by + ( h ) ) - ( float ) ( h ) * sin ( angle ) ;
XDrawLine ( display , window . drawable , window . gc ,
cur_x + ( w / 2. ) , by + ( h ) , ( int ) ( px ) , ( int ) ( py ) ) ;
# endif /* MATH */
if ( h > cur_y_add
& & h > font_h ) {
cur_y_add = h ;
}
set_foreground_color ( last_colour ) ;
break ;
}
case GRAPH :
{
int h , by , i = 0 , j = 0 ;
int colour_idx = 0 ;
unsigned long last_colour = current_color ;
2010-08-25 17:01:02 +00:00
if ( cur_x - text_start_x > mw & & mw > 0 ) {
2009-08-07 07:24:24 +00:00
break ;
}
2010-04-21 16:03:53 +00:00
h = current - > height ;
2009-08-07 07:24:24 +00:00
by = cur_y - ( font_ascent ( ) / 2 ) - 1 ;
if ( h < font_h ) {
by - = h / 2 - 1 ;
}
2010-04-21 16:03:53 +00:00
w = current - > width ;
2009-08-07 07:24:24 +00:00
if ( w = = 0 ) {
w = text_start_x + text_width - cur_x - 1 ;
2012-06-26 20:43:12 +00:00
current - > graph_width = MAX ( w - 1 , 0 ) ;
2011-10-25 22:32:52 +00:00
if ( current - > graph_width ! = current - > graph_allocated ) {
w = current - > graph_allocated + 1 ;
}
2009-08-07 07:24:24 +00:00
}
if ( w < 0 ) {
w = 0 ;
}
2010-03-05 13:06:15 +00:00
if ( draw_graph_borders . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XSetLineAttributes ( display , window . gc , 1 , LineSolid ,
CapButt , JoinMiter ) ;
XDrawRectangle ( display , window . drawable , window . gc ,
cur_x , by , w , h ) ;
}
XSetLineAttributes ( display , window . gc , 1 , LineSolid ,
CapButt , JoinMiter ) ;
2011-10-25 22:19:45 +00:00
/* in case we don't have a graph yet */
if ( current - > graph ) {
2011-11-01 18:10:37 +00:00
unsigned long * tmpcolour = 0 ;
2011-10-25 22:19:45 +00:00
if ( current - > last_colour ! = 0 | | current - > first_colour ! = 0 ) {
tmpcolour = do_gradient ( w - 1 ,
current - > last_colour , current - > first_colour ) ;
}
colour_idx = 0 ;
for ( i = w - 2 ; i > - 1 ; i - - ) {
if ( current - > last_colour ! = 0 | | current - > first_colour ! = 0 ) {
if ( current - > tempgrad ) {
2009-08-07 07:24:24 +00:00
# ifdef DEBUG_lol
assert (
2010-04-21 16:03:53 +00:00
( int ) ( ( float ) ( w - 2 ) - current - > graph [ j ] *
( w - 2 ) / ( float ) current - > scale )
2011-10-25 22:19:45 +00:00
< w - 1
2009-08-07 07:24:24 +00:00
) ;
2011-10-25 22:19:45 +00:00
assert (
( int ) ( ( float ) ( w - 2 ) - current - > graph [ j ] *
( w - 2 ) / ( float ) current - > scale )
> - 1
) ;
if ( current - > graph [ j ] = = current - > scale ) {
assert (
( int ) ( ( float ) ( w - 2 ) - current - > graph [ j ] *
( w - 2 ) / ( float ) current - > scale )
= = 0
) ;
}
2009-08-07 07:24:24 +00:00
# endif /* DEBUG_lol */
2011-10-25 22:19:45 +00:00
set_foreground_color ( tmpcolour [
( int ) ( ( float ) ( w - 2 ) -
current - > graph [ j ] * ( w - 2 ) /
2012-06-28 16:26:49 +00:00
std : : max ( ( float ) current - > scale , 1.0f ) )
2011-10-25 22:19:45 +00:00
] ) ;
} else {
set_foreground_color ( tmpcolour [ colour_idx + + ] ) ;
}
2009-08-07 07:24:24 +00:00
}
2011-10-25 22:19:45 +00:00
/* this is mugfugly, but it works */
XDrawLine ( display , window . drawable , window . gc ,
cur_x + i + 1 , by + h , cur_x + i + 1 ,
round_to_int ( ( double ) by + h - current - > graph [ j ] *
( h - 1 ) / current - > scale ) ) ;
+ + j ;
2009-08-07 07:24:24 +00:00
}
2011-11-01 18:06:41 +00:00
free_and_zero ( tmpcolour ) ;
2009-08-07 07:24:24 +00:00
}
if ( h > cur_y_add
& & h > font_h ) {
cur_y_add = h ;
}
2010-03-05 12:37:52 +00:00
if ( show_graph_range . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
int tmp_x = cur_x ;
int tmp_y = cur_y ;
2010-09-11 12:25:19 +00:00
unsigned short int seconds = active_update_interval ( ) * w ;
2009-08-07 07:24:24 +00:00
char * tmp_day_str ;
char * tmp_hour_str ;
char * tmp_min_str ;
char * tmp_sec_str ;
char * tmp_str ;
unsigned short int timeunits ;
if ( seconds ! = 0 ) {
timeunits = seconds / 86400 ; seconds % = 86400 ;
2009-12-17 21:30:00 +00:00
if ( timeunits < = 0 | |
2010-10-31 19:01:20 +00:00
asprintf ( & tmp_day_str , _ ( " %dd " ) , timeunits ) = = - 1 ) {
2009-08-07 07:24:24 +00:00
tmp_day_str = strdup ( " " ) ;
}
timeunits = seconds / 3600 ; seconds % = 3600 ;
2009-12-17 21:30:00 +00:00
if ( timeunits < = 0 | |
2010-10-31 19:01:20 +00:00
asprintf ( & tmp_hour_str , _ ( " %dh " ) , timeunits ) = = - 1 ) {
2009-08-07 07:24:24 +00:00
tmp_hour_str = strdup ( " " ) ;
}
timeunits = seconds / 60 ; seconds % = 60 ;
2009-12-17 21:30:00 +00:00
if ( timeunits < = 0 | |
2010-10-31 19:01:20 +00:00
asprintf ( & tmp_min_str , _ ( " %dm " ) , timeunits ) = = - 1 ) {
2009-08-07 07:24:24 +00:00
tmp_min_str = strdup ( " " ) ;
}
2009-12-17 21:30:00 +00:00
if ( seconds < = 0 | |
2010-10-31 19:01:20 +00:00
asprintf ( & tmp_sec_str , _ ( " %ds " ) , seconds ) = = - 1 ) {
2009-08-07 07:24:24 +00:00
tmp_sec_str = strdup ( " " ) ;
}
2009-12-17 21:30:00 +00:00
if ( asprintf ( & tmp_str , " %s%s%s%s " , tmp_day_str , tmp_hour_str , tmp_min_str , tmp_sec_str ) = = - 1 )
tmp_str = strdup ( " " ) ;
2009-08-07 07:24:24 +00:00
free ( tmp_day_str ) ; free ( tmp_hour_str ) ; free ( tmp_min_str ) ; free ( tmp_sec_str ) ;
} else {
2010-10-31 19:01:20 +00:00
tmp_str = strdup ( _ ( " Range not possible " ) ) ; // should never happen, but better safe then sorry
2009-08-07 07:24:24 +00:00
}
cur_x + = ( w / 2 ) - ( font_ascent ( ) * ( strlen ( tmp_str ) / 2 ) ) ;
cur_y + = font_h / 2 ;
draw_string ( tmp_str ) ;
free ( tmp_str ) ;
cur_x = tmp_x ;
cur_y = tmp_y ;
}
# ifdef MATH
2010-04-21 18:35:35 +00:00
if ( show_graph_scale . get ( * state ) & & ( current - > show_scale = = 1 ) ) {
2009-08-07 07:24:24 +00:00
int tmp_x = cur_x ;
int tmp_y = cur_y ;
char * tmp_str ;
cur_x + = font_ascent ( ) / 2 ;
cur_y + = font_h / 2 ;
tmp_str = ( char * )
2010-04-21 16:03:53 +00:00
calloc ( log10 ( floor ( current - > scale ) ) + 4 ,
2009-08-07 07:24:24 +00:00
sizeof ( char ) ) ;
2010-04-21 16:03:53 +00:00
sprintf ( tmp_str , " %.1f " , current - > scale ) ;
2009-08-07 07:24:24 +00:00
draw_string ( tmp_str ) ;
free ( tmp_str ) ;
cur_x = tmp_x ;
cur_y = tmp_y ;
}
# endif
set_foreground_color ( last_colour ) ;
break ;
}
case FONT :
{
int old = font_ascent ( ) ;
cur_y - = font_ascent ( ) ;
2010-04-21 16:03:53 +00:00
selected_font = current - > font_added ;
2009-08-07 07:24:24 +00:00
set_font ( ) ;
if ( cur_y + font_ascent ( ) < cur_y + old ) {
cur_y + = old ;
} else {
cur_y + = font_ascent ( ) ;
}
font_h = font_height ( ) ;
break ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
case FG :
if ( draw_mode = = FG ) {
2010-04-21 16:03:53 +00:00
set_foreground_color ( current - > arg ) ;
2009-08-07 07:24:24 +00:00
}
break ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
case BG :
if ( draw_mode = = BG ) {
2010-04-21 16:03:53 +00:00
set_foreground_color ( current - > arg ) ;
2009-08-07 07:24:24 +00:00
}
break ;
case OUTLINE :
if ( draw_mode = = OUTLINE ) {
2010-04-21 16:03:53 +00:00
set_foreground_color ( current - > arg ) ;
2009-08-07 07:24:24 +00:00
}
break ;
case OFFSET :
2010-04-21 16:03:53 +00:00
w + = current - > arg ;
2009-08-07 07:24:24 +00:00
last_special_needed = special_index ;
break ;
case VOFFSET :
2010-04-21 16:03:53 +00:00
cur_y + = current - > arg ;
2009-08-07 07:24:24 +00:00
break ;
case GOTO :
2010-04-21 16:03:53 +00:00
if ( current - > arg > = 0 ) {
cur_x = ( int ) current - > arg ;
2010-11-24 15:47:29 +00:00
# ifdef BUILD_X11
//make sure shades are 1 pixel to the right of the text
if ( draw_mode = = BG ) cur_x + + ;
# endif
2009-08-07 07:24:24 +00:00
}
last_special_needed = special_index ;
break ;
case TAB :
{
2010-04-21 16:03:53 +00:00
int start = current - > arg ;
int step = current - > width ;
2009-08-07 07:24:24 +00:00
if ( ! step | | step < 0 ) {
step = 10 ;
}
w = step - ( cur_x - text_start_x - start ) % step ;
last_special_needed = special_index ;
break ;
}
case ALIGNR :
{
/* TODO: add back in "+ window.border_inner_margin" to the end of
* this line ? */
int pos_x = text_start_x + text_width -
get_string_width_special ( s , special_index ) ;
/* printf("pos_x %i text_start_x %i text_width %i cur_x %i "
" get_string_width(p) %i gap_x %i "
2010-04-21 16:03:53 +00:00
" current->arg %i window.border_inner_margin %i "
2009-08-07 07:24:24 +00:00
" window.border_width %i \n " , pos_x , text_start_x , text_width ,
cur_x , get_string_width_special ( s ) , gap_x ,
2010-04-21 16:03:53 +00:00
current - > arg , window . border_inner_margin ,
2009-08-07 07:24:24 +00:00
window . border_width ) ; */
2010-04-21 16:03:53 +00:00
if ( pos_x > current - > arg & & pos_x > cur_x ) {
cur_x = pos_x - current - > arg ;
2009-08-07 07:24:24 +00:00
}
last_special_needed = special_index ;
break ;
}
case ALIGNC :
{
int pos_x = ( text_width ) / 2 - get_string_width_special ( s ,
special_index ) / 2 - ( cur_x -
text_start_x ) ;
/* int pos_x = text_start_x + text_width / 2 -
get_string_width_special ( s ) / 2 ; */
/* printf("pos_x %i text_start_x %i text_width %i cur_x %i "
" get_string_width(p) %i gap_x %i "
2010-04-21 16:03:53 +00:00
" current->arg %i \n " , pos_x , text_start_x ,
2009-08-07 07:24:24 +00:00
text_width , cur_x , get_string_width ( s ) , gap_x ,
2010-04-21 16:03:53 +00:00
current - > arg ) ; */
if ( pos_x > current - > arg ) {
w = pos_x - current - > arg ;
2009-08-07 07:24:24 +00:00
}
last_special_needed = special_index ;
break ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
cur_x + = w ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
if ( special_index ! = last_special_applied ) {
special_index + + ;
} else {
special_index = orig_special_index ;
last_special_applied = - 1 ;
}
}
p + + ;
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
cur_y + = cur_y_add ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
draw_string ( s ) ;
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2010-04-30 17:33:21 +00:00
if ( out_to_ncurses . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
printw ( " \n " ) ;
}
2010-02-16 16:00:33 +00:00
# endif /* BUILD_NCURSES */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) )
2009-09-20 01:48:00 +00:00
cur_y + = font_descent ( ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
return special_index ;
}
static int draw_line ( char * s , int special_index )
{
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
return draw_each_line_inner ( s , special_index , - 1 ) ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2010-04-30 17:33:21 +00:00
if ( out_to_ncurses . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
return draw_each_line_inner ( s , special_index , - 1 ) ;
}
2010-02-16 16:00:33 +00:00
# endif /* BUILD_NCURSES */
2009-08-07 07:24:24 +00:00
draw_string ( s ) ;
UNUSED ( special_index ) ;
return 0 ;
}
static void draw_text ( void )
{
2010-06-04 12:41:12 +00:00
# ifdef BUILD_HTTP
2010-06-04 13:47:01 +00:00
# define WEBPAGE_START1 "<!DOCTYPE html PUBLIC \"- //W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />"
2010-06-05 12:27:20 +00:00
# define WEBPAGE_START2 "<title>Conky< / title>< / head><body style=\"font-family: monospace\"><p>"
2010-06-04 12:41:12 +00:00
# define WEBPAGE_END "< / p>< / body>< / html>"
2010-06-20 17:31:17 +00:00
if ( out_to_http . get ( * state ) ) {
2010-06-04 13:47:01 +00:00
webpage = WEBPAGE_START1 ;
2010-06-20 17:15:56 +00:00
if ( http_refresh . get ( * state ) ) {
2010-06-04 13:47:01 +00:00
webpage . append ( " <meta http-equiv= \" refresh \" content= \" " ) ;
std : : stringstream update_interval_str ;
2012-06-04 21:29:27 +00:00
update_interval_str < < update_interval . get ( * state ) ;
2010-06-04 13:47:01 +00:00
webpage . append ( update_interval_str . str ( ) ) ;
webpage . append ( " \" /> " ) ;
}
webpage . append ( WEBPAGE_START2 ) ;
2010-06-04 12:41:12 +00:00
}
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
cur_y = text_start_y ;
2010-04-22 23:22:22 +00:00
int bw = border_width . get ( * state ) ;
2009-08-07 07:24:24 +00:00
/* draw borders */
2010-04-22 23:22:22 +00:00
if ( draw_borders . get ( * state ) & & bw > 0 ) {
2010-08-25 17:26:15 +00:00
if ( stippled_borders . get ( * state ) ) {
char ss [ 2 ] = { stippled_borders . get ( * state ) , stippled_borders . get ( * state ) } ;
2010-04-22 23:22:22 +00:00
XSetLineAttributes ( display , window . gc , bw , LineOnOffDash ,
2009-08-07 07:24:24 +00:00
CapButt , JoinMiter ) ;
XSetDashes ( display , window . gc , 0 , ss , 2 ) ;
} else {
2010-04-22 23:22:22 +00:00
XSetLineAttributes ( display , window . gc , bw , LineSolid ,
2009-08-07 07:24:24 +00:00
CapButt , JoinMiter ) ;
}
2010-04-22 23:22:22 +00:00
int offset = border_inner_margin . get ( * state ) + bw ;
2009-08-07 07:24:24 +00:00
XDrawRectangle ( display , window . drawable , window . gc ,
2010-04-22 23:22:22 +00:00
text_start_x - offset , text_start_y - offset ,
text_width + 2 * offset , text_height + 2 * offset ) ;
2009-08-07 07:24:24 +00:00
}
/* draw text */
}
setup_fonts ( ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2009-08-07 07:24:24 +00:00
init_pair ( COLOR_WHITE , COLOR_WHITE , COLOR_BLACK ) ;
attron ( COLOR_PAIR ( COLOR_WHITE ) ) ;
2010-02-16 16:00:33 +00:00
# endif /* BUILD_NCURSES */
2009-08-07 07:24:24 +00:00
for_each_line ( text_buffer , draw_line ) ;
2010-06-04 12:41:12 +00:00
# ifdef BUILD_HTTP
2010-06-20 17:31:17 +00:00
if ( out_to_http . get ( * state ) ) {
2010-06-04 12:41:12 +00:00
webpage . append ( WEBPAGE_END ) ;
}
# endif
2009-08-07 07:24:24 +00:00
}
static void draw_stuff ( void )
{
2010-01-10 23:35:22 +00:00
# ifdef BUILD_IMLIB2
2009-08-07 07:24:24 +00:00
cimlib_render ( text_start_x , text_start_y , window . width , window . height ) ;
2010-01-10 23:35:22 +00:00
# endif /* BUILD_IMLIB2 */
2010-08-22 11:04:19 +00:00
if ( overwrite_file . get ( * state ) . size ( ) ) {
overwrite_fpointer = fopen ( overwrite_file . get ( * state ) . c_str ( ) , " w " ) ;
2009-08-07 07:24:24 +00:00
if ( ! overwrite_fpointer )
2010-08-22 11:04:19 +00:00
NORM_ERR ( " Cannot overwrite '%s' " , overwrite_file . get ( * state ) . c_str ( ) ) ;
2009-08-07 07:24:24 +00:00
}
2010-08-22 11:04:19 +00:00
if ( append_file . get ( * state ) . size ( ) ) {
append_fpointer = fopen ( append_file . get ( * state ) . c_str ( ) , " a " ) ;
2009-08-07 07:24:24 +00:00
if ( ! append_fpointer )
2010-08-22 11:04:19 +00:00
NORM_ERR ( " Cannot append to '%s' " , append_file . get ( * state ) . c_str ( ) ) ;
2009-08-07 07:24:24 +00:00
}
2012-06-03 14:20:17 +00:00
llua_draw_pre_hook ( ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
selected_font = 0 ;
2010-03-05 13:10:47 +00:00
if ( draw_shades . get ( * state ) & & ! draw_outline . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
text_start_x + + ;
text_start_y + + ;
2010-03-11 11:08:55 +00:00
set_foreground_color ( default_shade_color . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
draw_mode = BG ;
draw_text ( ) ;
text_start_x - - ;
text_start_y - - ;
}
2010-03-05 13:10:47 +00:00
if ( draw_outline . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
int i , j ;
selected_font = 0 ;
for ( i = - 1 ; i < 2 ; i + + ) {
for ( j = - 1 ; j < 2 ; j + + ) {
if ( i = = 0 & & j = = 0 ) {
continue ;
}
text_start_x + = i ;
text_start_y + = j ;
2010-03-11 11:08:55 +00:00
set_foreground_color ( default_outline_color . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
draw_mode = OUTLINE ;
draw_text ( ) ;
text_start_x - = i ;
text_start_y - = j ;
}
}
}
2010-03-11 11:08:55 +00:00
set_foreground_color ( default_color . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
draw_mode = FG ;
draw_text ( ) ;
2012-06-03 14:20:17 +00:00
llua_draw_post_hook ( ) ;
2012-04-11 16:06:47 +00:00
# if defined(BUILD_X11)
# if defined(BUILD_XDBE)
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-09-20 01:23:46 +00:00
xdbe_swap_buffers ( ) ;
2009-08-07 07:24:24 +00:00
}
2012-04-11 16:06:47 +00:00
# else
if ( out_to_x . get ( * state ) ) {
xpmdb_swap_buffers ( ) ;
}
# endif
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 && BUILD_XDBE */
2009-08-07 07:24:24 +00:00
if ( overwrite_fpointer ) {
fclose ( overwrite_fpointer ) ;
overwrite_fpointer = 0 ;
}
2009-12-10 04:05:32 +00:00
if ( append_fpointer ) {
2009-08-07 07:24:24 +00:00
fclose ( append_fpointer ) ;
append_fpointer = 0 ;
}
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
static void clear_text ( int exposures )
{
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDBE
2010-04-23 19:54:40 +00:00
if ( use_xdbe . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
/* The swap action is XdbeBackground, which clears */
return ;
} else
2012-04-11 16:06:47 +00:00
# else
if ( use_xpmdb . get ( * state ) ) {
return ;
} else
2009-08-07 07:24:24 +00:00
# endif
if ( display & & window . window ) { // make sure these are !null
/* there is some extra space for borders and outlines */
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2010-03-12 18:27:07 +00:00
XClearArea ( display , window . window , text_start_x - border_total ,
text_start_y - border_total , text_width + 2 * border_total ,
text_height + 2 * border_total , exposures ? True : 0 ) ;
2009-08-07 07:24:24 +00:00
}
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
static int need_to_update ;
/* update_text() generates new text and clears old text area */
static void update_text ( void )
{
2010-01-10 23:35:22 +00:00
# ifdef BUILD_IMLIB2
2009-08-07 07:24:24 +00:00
cimlib_cleanup ( ) ;
2010-01-10 23:35:22 +00:00
# endif /* BUILD_IMLIB2 */
2009-08-07 07:24:24 +00:00
generate_text ( ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) )
2009-08-07 07:24:24 +00:00
clear_text ( 1 ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
need_to_update = 1 ;
2010-09-11 12:25:19 +00:00
llua_update_info ( & info , active_update_interval ( ) ) ;
2009-08-07 07:24:24 +00:00
}
# ifdef HAVE_SYS_INOTIFY_H
int inotify_fd ;
# endif
static void main_loop ( void )
{
int terminate = 0 ;
# ifdef SIGNAL_BLOCKING
sigset_t newmask , oldmask ;
# endif
double t ;
# ifdef HAVE_SYS_INOTIFY_H
int inotify_config_wd = - 1 ;
# define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
2010-11-23 16:33:26 +00:00
# define INOTIFY_BUF_LEN (20 * (INOTIFY_EVENT_SIZE + 16)) + 1
2009-08-07 07:24:24 +00:00
char inotify_buff [ INOTIFY_BUF_LEN ] ;
# endif /* HAVE_SYS_INOTIFY_H */
# ifdef SIGNAL_BLOCKING
sigemptyset ( & newmask ) ;
sigaddset ( & newmask , SIGINT ) ;
sigaddset ( & newmask , SIGTERM ) ;
sigaddset ( & newmask , SIGUSR1 ) ;
# endif
last_update_time = 0.0 ;
next_update_time = get_time ( ) ;
info . looped = 0 ;
2010-08-31 09:49:37 +00:00
while ( terminate = = 0
& & ( total_run_times . get ( * state ) = = 0 | | info . looped < total_run_times . get ( * state ) ) ) {
2010-09-11 12:25:19 +00:00
if ( update_interval_on_battery . get ( * state ) ! = NOBATTERY ) {
2009-12-17 21:19:58 +00:00
char buf [ 64 ] ;
2009-08-07 07:24:24 +00:00
2009-12-17 21:19:58 +00:00
get_battery_short_status ( buf , 64 , " BAT0 " ) ;
2010-09-11 12:25:19 +00:00
on_battery = ( buf [ 0 ] = = ' D ' ) ;
2009-08-07 07:24:24 +00:00
}
info . looped + + ;
# ifdef SIGNAL_BLOCKING
/* block signals. we will inspect for pending signals later */
if ( sigprocmask ( SIG_BLOCK , & newmask , & oldmask ) < 0 ) {
CRIT_ERR ( NULL , NULL , " unable to sigprocmask() " ) ;
}
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XFlush ( display ) ;
/* wait for X event or timeout */
if ( ! XPending ( display ) ) {
fd_set fdsr ;
struct timeval tv ;
int s ;
t = next_update_time - get_time ( ) ;
2010-09-11 12:25:19 +00:00
t = std : : min ( std : : max ( t , 0.0 ) , active_update_interval ( ) ) ;
2009-08-07 07:24:24 +00:00
tv . tv_sec = ( long ) t ;
tv . tv_usec = ( long ) ( t * 1000000 ) % 1000000 ;
FD_ZERO ( & fdsr ) ;
FD_SET ( ConnectionNumber ( display ) , & fdsr ) ;
s = select ( ConnectionNumber ( display ) + 1 , & fdsr , 0 , 0 , & tv ) ;
if ( s = = - 1 ) {
if ( errno ! = EINTR ) {
NORM_ERR ( " can't select(): %s " , strerror ( errno ) ) ;
}
} else {
/* timeout */
if ( s = = 0 ) {
update_text ( ) ;
}
}
}
if ( need_to_update ) {
# ifdef OWN_WINDOW
int wx = window . x , wy = window . y ;
# endif
need_to_update = 0 ;
selected_font = 0 ;
update_text_area ( ) ;
2010-03-12 18:27:07 +00:00
2009-08-07 07:24:24 +00:00
# ifdef OWN_WINDOW
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
int changed = 0 ;
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2009-08-07 07:24:24 +00:00
/* resize window if it isn't right size */
if ( ! fixed_size
2010-03-12 18:27:07 +00:00
& & ( text_width + 2 * border_total ! = window . width
| | text_height + 2 * border_total ! = window . height ) ) {
window . width = text_width + 2 * border_total ;
window . height = text_height + 2 * border_total ;
2009-08-07 07:24:24 +00:00
draw_stuff ( ) ; /* redraw everything in our newly sized window */
XResizeWindow ( display , window . window , window . width ,
window . height ) ; /* resize window */
2010-02-27 21:28:33 +00:00
set_transparent_background ( window . window ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDBE
2009-08-07 07:24:24 +00:00
/* swap buffers */
xdbe_swap_buffers ( ) ;
2012-04-11 16:06:47 +00:00
# else
if ( use_xpmdb . get ( * state ) ) {
XFreePixmap ( display , window . back_buffer ) ;
window . back_buffer = XCreatePixmap ( display ,
window . window , window . width , window . height , DefaultDepth ( display , screen ) ) ;
if ( window . back_buffer ! = None ) {
window . drawable = window . back_buffer ;
} else {
// this is probably reallllly bad
NORM_ERR ( " Failed to allocate back buffer " ) ;
}
XSetForeground ( display , window . gc , 0 ) ;
XFillRectangle ( display , window . drawable , window . gc , 0 , 0 , window . width , window . height ) ;
}
2009-08-07 07:24:24 +00:00
# endif
changed + + ;
/* update lua window globals */
llua_update_window_table ( text_start_x , text_start_y , text_width , text_height ) ;
}
/* move window if it isn't in right position */
if ( ! fixed_pos & & ( window . x ! = wx | | window . y ! = wy ) ) {
XMoveWindow ( display , window . window , window . x , window . y ) ;
changed + + ;
}
/* update struts */
2010-02-26 17:48:57 +00:00
if ( changed & & own_window_type . get ( * state ) = = TYPE_PANEL ) {
2009-08-07 07:24:24 +00:00
int sidenum = - 1 ;
2010-10-31 19:01:20 +00:00
fprintf ( stderr , _ ( PACKAGE_NAME " : defining struts \n " ) ) ;
2009-08-07 07:24:24 +00:00
fflush ( stderr ) ;
2010-02-24 19:51:33 +00:00
switch ( text_alignment . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
case TOP_LEFT :
case TOP_RIGHT :
case TOP_MIDDLE :
{
sidenum = 2 ;
break ;
}
case BOTTOM_LEFT :
case BOTTOM_RIGHT :
case BOTTOM_MIDDLE :
{
sidenum = 3 ;
break ;
}
case MIDDLE_LEFT :
{
sidenum = 0 ;
break ;
}
case MIDDLE_RIGHT :
{
sidenum = 1 ;
break ;
}
2010-02-24 19:51:33 +00:00
case NONE : case MIDDLE_MIDDLE : /* XXX What about these? */ ;
2009-08-07 07:24:24 +00:00
}
set_struts ( sidenum ) ;
}
}
# endif
clear_text ( 1 ) ;
2012-04-11 16:06:47 +00:00
# if defined(BUILD_XDBE)
2010-04-23 19:54:40 +00:00
if ( use_xdbe . get ( * state ) ) {
2012-04-11 16:06:47 +00:00
# else
if ( use_xpmdb . get ( * state ) ) {
# endif
2009-08-07 07:24:24 +00:00
XRectangle r ;
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2009-08-07 07:24:24 +00:00
2010-03-12 18:27:07 +00:00
r . x = text_start_x - border_total ;
r . y = text_start_y - border_total ;
r . width = text_width + 2 * border_total ;
r . height = text_height + 2 * border_total ;
2009-08-07 07:24:24 +00:00
XUnionRectWithRegion ( & r , x11_stuff . region , x11_stuff . region ) ;
}
}
/* handle X events */
while ( XPending ( display ) ) {
XEvent ev ;
XNextEvent ( display , & ev ) ;
switch ( ev . type ) {
case Expose :
{
XRectangle r ;
r . x = ev . xexpose . x ;
r . y = ev . xexpose . y ;
r . width = ev . xexpose . width ;
r . height = ev . xexpose . height ;
XUnionRectWithRegion ( & r , x11_stuff . region , x11_stuff . region ) ;
break ;
}
case PropertyNotify :
{
2009-09-20 01:32:07 +00:00
if ( ev . xproperty . state = = PropertyNewValue ) {
get_x11_desktop_info ( ev . xproperty . display , ev . xproperty . atom ) ;
2009-08-07 07:24:24 +00:00
}
break ;
}
# ifdef OWN_WINDOW
case ReparentNotify :
2010-01-01 23:01:51 +00:00
/* make background transparent */
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
2010-02-27 21:28:33 +00:00
set_transparent_background ( window . window ) ;
2009-08-07 07:24:24 +00:00
}
break ;
case ConfigureNotify :
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
/* if window size isn't what expected, set fixed size */
if ( ev . xconfigure . width ! = window . width
| | ev . xconfigure . height ! = window . height ) {
if ( window . width ! = 0 & & window . height ! = 0 ) {
fixed_size = 1 ;
}
/* clear old stuff before screwing up
* size and pos */
clear_text ( 1 ) ;
{
XWindowAttributes attrs ;
if ( XGetWindowAttributes ( display ,
window . window , & attrs ) ) {
window . width = attrs . width ;
window . height = attrs . height ;
}
}
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2010-04-22 19:59:12 +00:00
text_width = window . width - 2 * border_total ;
text_height = window . height - 2 * border_total ;
2010-08-25 17:01:02 +00:00
int mw = maximum_width . get ( * state ) ;
if ( text_width > mw & & mw > 0 ) {
text_width = mw ;
2009-08-07 07:24:24 +00:00
}
}
/* if position isn't what expected, set fixed pos
* total_updates avoids setting fixed_pos when window
* is set to weird locations when started */
/* // this is broken
if ( total_updates > = 2 & & ! fixed_pos
& & ( window . x ! = ev . xconfigure . x
| | window . y ! = ev . xconfigure . y )
& & ( ev . xconfigure . x ! = 0
| | ev . xconfigure . y ! = 0 ) ) {
fixed_pos = 1 ;
} */
}
break ;
case ButtonPress :
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
/* if an ordinary window with decorations */
2010-02-26 17:48:57 +00:00
if ( ( own_window_type . get ( * state ) = = TYPE_NORMAL & &
2010-03-02 19:30:15 +00:00
not TEST_HINT ( own_window_hints . get ( * state ) ,
HINT_UNDECORATED ) ) | |
2010-02-26 17:48:57 +00:00
own_window_type . get ( * state ) = = TYPE_DESKTOP ) {
2009-08-07 07:24:24 +00:00
/* allow conky to hold input focus. */
break ;
} else {
/* forward the click to the desktop window */
XUngrabPointer ( display , ev . xbutton . time ) ;
ev . xbutton . window = window . desktop ;
ev . xbutton . x = ev . xbutton . x_root ;
ev . xbutton . y = ev . xbutton . y_root ;
XSendEvent ( display , ev . xbutton . window , False ,
ButtonPressMask , & ev ) ;
XSetInputFocus ( display , ev . xbutton . window ,
RevertToParent , ev . xbutton . time ) ;
}
}
break ;
case ButtonRelease :
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
/* if an ordinary window with decorations */
2010-03-02 19:30:15 +00:00
if ( ( own_window_type . get ( * state ) = = TYPE_NORMAL ) & &
not TEST_HINT ( own_window_hints . get ( * state ) , HINT_UNDECORATED ) ) {
2009-08-07 07:24:24 +00:00
/* allow conky to hold input focus. */
break ;
} else {
/* forward the release to the desktop window */
ev . xbutton . window = window . desktop ;
ev . xbutton . x = ev . xbutton . x_root ;
ev . xbutton . y = ev . xbutton . y_root ;
XSendEvent ( display , ev . xbutton . window , False ,
ButtonReleaseMask , & ev ) ;
}
}
break ;
# endif
default :
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2009-08-07 07:24:24 +00:00
if ( ev . type = = x11_stuff . event_base + XDamageNotify ) {
XDamageNotifyEvent * dev = ( XDamageNotifyEvent * ) & ev ;
XFixesSetRegion ( display , x11_stuff . part , & dev - > area , 1 ) ;
XFixesUnionRegion ( display , x11_stuff . region2 , x11_stuff . region2 , x11_stuff . part ) ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XDAMAGE */
2009-08-07 07:24:24 +00:00
break ;
}
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2009-08-07 07:24:24 +00:00
XDamageSubtract ( display , x11_stuff . damage , x11_stuff . region2 , None ) ;
XFixesSetRegion ( display , x11_stuff . region2 , 0 , 0 ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XDAMAGE */
2009-08-07 07:24:24 +00:00
/* XDBE doesn't seem to provide a way to clear the back buffer
* without interfering with the front buffer , other than passing
* XdbeBackground to XdbeSwapBuffers . That means that if we ' re
* using XDBE , we need to redraw the text even if it wasn ' t part of
* the exposed area . OTOH , if we ' re not going to call draw_stuff at
* all , then no swap happens and we can safely do nothing . */
if ( ! XEmptyRegion ( x11_stuff . region ) ) {
2012-04-11 16:06:47 +00:00
# if defined(BUILD_XDBE)
2010-04-23 19:54:40 +00:00
if ( use_xdbe . get ( * state ) ) {
2012-04-11 16:06:47 +00:00
# else
if ( use_xpmdb . get ( * state ) ) {
# endif
2009-08-07 07:24:24 +00:00
XRectangle r ;
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2009-08-07 07:24:24 +00:00
2010-03-12 18:27:07 +00:00
r . x = text_start_x - border_total ;
r . y = text_start_y - border_total ;
r . width = text_width + 2 * border_total ;
r . height = text_height + 2 * border_total ;
2009-08-07 07:24:24 +00:00
XUnionRectWithRegion ( & r , x11_stuff . region , x11_stuff . region ) ;
}
XSetRegion ( display , window . gc , x11_stuff . region ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XFT
2010-04-21 17:33:39 +00:00
if ( use_xft . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XftDrawSetClip ( window . xftdraw , x11_stuff . region ) ;
}
# endif
draw_stuff ( ) ;
XDestroyRegion ( x11_stuff . region ) ;
x11_stuff . region = XCreateRegion ( ) ;
}
} else {
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
t = ( next_update_time - get_time ( ) ) * 1000000 ;
if ( t > 0 ) usleep ( ( useconds_t ) t ) ;
update_text ( ) ;
draw_stuff ( ) ;
2010-02-16 16:00:33 +00:00
# ifdef BUILD_NCURSES
2010-04-30 17:33:21 +00:00
if ( out_to_ncurses . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
refresh ( ) ;
clear ( ) ;
}
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
# ifdef SIGNAL_BLOCKING
/* unblock signals of interest and let handler fly */
if ( sigprocmask ( SIG_SETMASK , & oldmask , NULL ) < 0 ) {
CRIT_ERR ( NULL , NULL , " unable to sigprocmask() " ) ;
}
# endif
switch ( g_signal_pending ) {
case SIGHUP :
case SIGUSR1 :
NORM_ERR ( " received SIGHUP or SIGUSR1. reloading the config file. " ) ;
reload_config ( ) ;
break ;
case SIGINT :
case SIGTERM :
NORM_ERR ( " received SIGINT or SIGTERM to terminate. bye! " ) ;
terminate = 1 ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
XDestroyRegion ( x11_stuff . region ) ;
x11_stuff . region = NULL ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2009-08-07 07:24:24 +00:00
XDamageDestroy ( display , x11_stuff . damage ) ;
XFixesDestroyRegion ( display , x11_stuff . region2 ) ;
XFixesDestroyRegion ( display , x11_stuff . part ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XDAMAGE */
2009-08-07 07:24:24 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
break ;
default :
/* Reaching here means someone set a signal
* ( SIGXXXX , signal_handler ) , but didn ' t write any code
* to deal with it .
* If you don ' t want to handle a signal , don ' t set a handler on
* it in the first place . */
if ( g_signal_pending ) {
NORM_ERR ( " ignoring signal (%d) " , g_signal_pending ) ;
}
break ;
}
# ifdef HAVE_SYS_INOTIFY_H
2010-03-05 20:00:25 +00:00
if ( ! disable_auto_reload . get ( * state ) & & inotify_fd ! = - 1
2010-03-04 10:42:38 +00:00
& & inotify_config_wd = = - 1 & & ! current_config . empty ( ) ) {
2009-08-07 07:24:24 +00:00
inotify_config_wd = inotify_add_watch ( inotify_fd ,
2010-03-04 10:42:38 +00:00
current_config . c_str ( ) ,
2009-08-07 07:24:24 +00:00
IN_MODIFY ) ;
}
2010-03-05 20:00:25 +00:00
if ( ! disable_auto_reload . get ( * state ) & & inotify_fd ! = - 1
2010-03-04 10:42:38 +00:00
& & inotify_config_wd ! = - 1 & & ! current_config . empty ( ) ) {
2009-08-07 07:24:24 +00:00
int len = 0 , idx = 0 ;
fd_set descriptors ;
struct timeval time_to_wait ;
FD_ZERO ( & descriptors ) ;
FD_SET ( inotify_fd , & descriptors ) ;
time_to_wait . tv_sec = time_to_wait . tv_usec = 0 ;
select ( inotify_fd + 1 , & descriptors , NULL , NULL , & time_to_wait ) ;
if ( FD_ISSET ( inotify_fd , & descriptors ) ) {
/* process inotify events */
2010-11-23 16:33:26 +00:00
len = read ( inotify_fd , inotify_buff , INOTIFY_BUF_LEN - 1 ) ;
2010-11-23 16:40:53 +00:00
inotify_buff [ len ] = 0 ;
2009-08-07 07:24:24 +00:00
while ( len > 0 & & idx < len ) {
struct inotify_event * ev = ( struct inotify_event * ) & inotify_buff [ idx ] ;
if ( ev - > wd = = inotify_config_wd & & ( ev - > mask & IN_MODIFY | | ev - > mask & IN_IGNORED ) ) {
/* current_config should be reloaded */
2010-03-04 10:42:38 +00:00
NORM_ERR ( " '%s' modified, reloading... " , current_config . c_str ( ) ) ;
2009-08-07 07:24:24 +00:00
reload_config ( ) ;
if ( ev - > mask & IN_IGNORED ) {
/* for some reason we get IN_IGNORED here
* sometimes , so we need to re - add the watch */
inotify_config_wd = inotify_add_watch ( inotify_fd ,
2010-03-04 10:42:38 +00:00
current_config . c_str ( ) ,
2009-08-07 07:24:24 +00:00
IN_MODIFY ) ;
}
2010-01-02 22:22:46 +00:00
break ;
2009-08-07 07:24:24 +00:00
}
else {
llua_inotify_query ( ev - > wd , ev - > mask ) ;
}
idx + = INOTIFY_EVENT_SIZE + ev - > len ;
}
}
2010-03-05 20:00:25 +00:00
} else if ( disable_auto_reload . get ( * state ) & & inotify_fd ! = - 1 ) {
2010-01-02 21:31:09 +00:00
inotify_rm_watch ( inotify_fd , inotify_config_wd ) ;
close ( inotify_fd ) ;
inotify_fd = inotify_config_wd = 0 ;
2009-08-07 07:24:24 +00:00
}
# endif /* HAVE_SYS_INOTIFY_H */
2010-09-11 12:25:19 +00:00
llua_update_info ( & info , active_update_interval ( ) ) ;
2009-08-07 07:24:24 +00:00
g_signal_pending = 0 ;
}
2010-08-26 21:07:21 +00:00
clean_up ( NULL , NULL ) ;
2009-08-07 07:24:24 +00:00
# ifdef HAVE_SYS_INOTIFY_H
if ( inotify_fd ! = - 1 ) {
inotify_rm_watch ( inotify_fd , inotify_config_wd ) ;
close ( inotify_fd ) ;
inotify_fd = inotify_config_wd = 0 ;
}
# endif /* HAVE_SYS_INOTIFY_H */
}
void initialisation ( int argc , char * * argv ) ;
/* reload the config file */
static void reload_config ( void )
{
2010-11-21 15:56:50 +00:00
struct stat sb ;
if ( stat ( current_config . c_str ( ) , & sb ) | | ( ! S_ISREG ( sb . st_mode ) & & ! S_ISLNK ( sb . st_mode ) ) ) {
NORM_ERR ( _ ( " Config file '%s' is gone, continuing with config from memory. \n If you recreate this file sent me a SIGUSR1 to tell me about it. ( kill -s USR1 %d ) " ) , current_config . c_str ( ) , getpid ( ) ) ;
return ;
}
2009-08-07 07:24:24 +00:00
clean_up ( NULL , NULL ) ;
2010-11-21 13:32:59 +00:00
state . reset ( new lua : : state ) ;
conky : : export_symbols ( * state ) ;
2010-01-02 21:31:09 +00:00
sleep ( 1 ) ; /* slight pause */
2009-08-07 07:24:24 +00:00
initialisation ( argc_copy , argv_copy ) ;
}
2010-04-14 19:50:50 +00:00
# ifdef BUILD_X11
2010-07-29 14:29:11 +00:00
void clean_up_x11 ( void )
{
2010-04-14 19:50:50 +00:00
if ( window_created = = 1 ) {
2010-04-22 23:22:22 +00:00
int border_total = get_border_total ( ) ;
2010-04-14 19:50:50 +00:00
XClearArea ( display , window . window , text_start_x - border_total ,
text_start_y - border_total , text_width + 2 * border_total ,
text_height + 2 * border_total , 0 ) ;
}
destroy_window ( ) ;
2010-11-26 16:59:07 +00:00
free_fonts ( utf8_mode . get ( * state ) ) ;
2010-04-14 19:50:50 +00:00
if ( x11_stuff . region ) {
XDestroyRegion ( x11_stuff . region ) ;
x11_stuff . region = NULL ;
}
}
# endif
2010-11-14 13:34:39 +00:00
void free_specials ( special_t * & current ) {
2010-04-21 16:03:53 +00:00
if ( current ) {
free_specials ( current - > next ) ;
if ( current - > type = = GRAPH )
free ( current - > graph ) ;
delete current ;
current = NULL ;
}
}
2010-06-20 17:09:13 +00:00
void clean_up_without_threads ( void * memtofree1 , void * memtofree2 )
2009-08-07 07:24:24 +00:00
{
2010-02-23 21:06:04 +00:00
free_and_zero ( memtofree1 ) ;
free_and_zero ( memtofree2 ) ;
2010-11-13 15:36:43 +00:00
2010-02-20 14:28:05 +00:00
free_and_zero ( info . cpu_usage ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2010-11-13 18:40:43 +00:00
if ( out_to_x . get ( * state ) )
2010-04-14 19:50:50 +00:00
clean_up_x11 ( ) ;
2010-11-13 18:40:43 +00:00
else
2010-09-08 15:30:04 +00:00
fonts . clear ( ) ; //in set_default_configurations a font is set but not loaded
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
2009-11-29 20:13:26 +00:00
if ( info . first_process ) {
free_all_processes ( ) ;
info . first_process = NULL ;
}
2009-11-29 20:24:03 +00:00
free_text_objects ( & global_root_object ) ;
2010-02-20 14:28:05 +00:00
free_and_zero ( tmpstring1 ) ;
free_and_zero ( tmpstring2 ) ;
free_and_zero ( text_buffer ) ;
free_and_zero ( global_text ) ;
2009-08-07 07:24:24 +00:00
2010-01-07 02:38:12 +00:00
# ifdef BUILD_PORT_MONITORS
2009-08-07 07:24:24 +00:00
tcp_portmon_clear ( ) ;
# endif
llua_shutdown_hook ( ) ;
2010-05-06 15:29:09 +00:00
# if defined BUILD_WEATHER_XOAP || defined BUILD_RSS
2009-08-07 07:24:24 +00:00
xmlCleanupParser ( ) ;
2010-05-06 15:29:09 +00:00
# endif
2009-08-07 07:24:24 +00:00
2010-04-21 16:03:53 +00:00
free_specials ( specials ) ;
2009-08-07 07:24:24 +00:00
clear_net_stats ( ) ;
clear_diskio_stats ( ) ;
2010-02-20 14:28:05 +00:00
free_and_zero ( global_cpu ) ;
2010-03-10 19:01:26 +00:00
conky : : cleanup_config_settings ( * state ) ;
state . reset ( ) ;
2009-08-07 07:24:24 +00:00
}
2010-05-05 16:46:04 +00:00
void clean_up ( void * memtofree1 , void * memtofree2 )
{
2010-12-31 12:39:54 +00:00
/* free_update_callbacks(); XXX: some new equivalent of this? */
2010-05-05 16:46:04 +00:00
clean_up_without_threads ( memtofree1 , memtofree2 ) ;
}
2009-08-07 07:24:24 +00:00
static void set_default_configurations ( void )
{
update_uname ( ) ;
info . memmax = 0 ;
top_cpu = 0 ;
top_mem = 0 ;
top_time = 0 ;
2010-01-07 18:14:53 +00:00
# ifdef BUILD_IOSTATS
2009-08-07 07:24:24 +00:00
top_io = 0 ;
# endif
2009-09-03 21:13:14 +00:00
top_running = 0 ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XMMS2
2009-08-07 07:24:24 +00:00
info . xmms2 . artist = NULL ;
info . xmms2 . album = NULL ;
info . xmms2 . title = NULL ;
info . xmms2 . genre = NULL ;
info . xmms2 . comment = NULL ;
info . xmms2 . url = NULL ;
info . xmms2 . status = NULL ;
info . xmms2 . playlist = NULL ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XMMS2 */
2010-02-25 21:28:34 +00:00
state - > pushboolean ( true ) ;
2010-11-21 13:32:59 +00:00
# ifdef BUILD_X11
2010-02-25 21:28:34 +00:00
out_to_x . lua_set ( * state ) ;
2009-08-07 07:24:24 +00:00
# else
2010-04-30 17:06:17 +00:00
out_to_stdout . lua_set ( * state ) ;
2009-08-07 07:24:24 +00:00
# endif
info . users . number = 1 ;
}
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
static void X11_create_window ( void )
{
2010-02-25 21:28:34 +00:00
if ( out_to_x . get ( * state ) ) {
2009-08-07 07:24:24 +00:00
setup_fonts ( ) ;
2010-11-26 16:59:07 +00:00
load_fonts ( utf8_mode . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
update_text_area ( ) ; /* to position text/window on screen */
# ifdef OWN_WINDOW
2010-02-26 13:37:34 +00:00
if ( own_window . get ( * state ) ) {
if ( not fixed_pos )
XMoveWindow ( display , window . window , window . x , window . y ) ;
2010-02-27 21:28:33 +00:00
set_transparent_background ( window . window ) ;
2009-08-07 07:24:24 +00:00
}
# endif
create_gc ( ) ;
draw_stuff ( ) ;
x11_stuff . region = XCreateRegion ( ) ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDAMAGE
2009-08-07 07:24:24 +00:00
if ( ! XDamageQueryExtension ( display , & x11_stuff . event_base , & x11_stuff . error_base ) ) {
NORM_ERR ( " Xdamage extension unavailable " ) ;
}
x11_stuff . damage = XDamageCreate ( display , window . window , XDamageReportNonEmpty ) ;
x11_stuff . region2 = XFixesCreateRegionFromWindow ( display , window . window , 0 ) ;
x11_stuff . part = XFixesCreateRegionFromWindow ( display , window . window , 0 ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_XDAMAGE */
2009-08-07 07:24:24 +00:00
selected_font = 0 ;
update_text_area ( ) ; /* to get initial size of the window */
}
/* setup lua window globals */
llua_setup_window_table ( text_start_x , text_start_y , text_width , text_height ) ;
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-08-07 07:24:24 +00:00
2010-09-15 21:37:13 +00:00
void load_config_file ( )
2009-08-07 07:24:24 +00:00
{
2010-11-21 22:39:35 +00:00
DBGP ( _ ( " reading contents from config file '%s' " ) , current_config . c_str ( ) ) ;
2010-09-15 21:37:13 +00:00
lua : : state & l = * state ;
lua : : stack_sentry s ( l ) ;
l . checkstack ( 2 ) ;
2010-11-17 23:36:36 +00:00
try {
2010-11-14 00:25:11 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2010-11-17 23:36:36 +00:00
if ( current_config = = builtin_config_magic )
l . loadstring ( defconfig ) ;
else
2010-11-14 00:25:11 +00:00
# endif
2010-11-17 23:36:36 +00:00
l . loadfile ( current_config . c_str ( ) ) ;
}
2010-11-21 21:26:35 +00:00
catch ( lua : : syntax_error & e ) {
2010-11-22 22:45:38 +00:00
# define SYNTAX_ERR_READ_CONF "Syntax error (%s) while reading config file. "
# ifdef BUILD_OLD_CONFIG
2010-11-23 15:45:42 +00:00
NORM_ERR ( _ ( SYNTAX_ERR_READ_CONF ) , e . what ( ) ) ;
NORM_ERR ( _ ( " Assuming it's in old syntax and attempting conversion. " ) ) ;
2010-11-21 21:26:35 +00:00
// the strchr thingy skips the first line (#! /usr/bin/lua)
l . loadstring ( strchr ( convertconf , ' \n ' ) ) ;
l . pushstring ( current_config . c_str ( ) ) ;
2010-11-19 13:27:18 +00:00
l . call ( 1 , 1 ) ;
2010-11-22 22:45:38 +00:00
# else
char * syntaxerr ;
asprintf ( & syntaxerr , _ ( SYNTAX_ERR_READ_CONF ) , e . what ( ) ) ;
std : : string syntaxerrobj ( syntaxerr ) ;
free ( syntaxerr ) ;
throw conky : : error ( syntaxerrobj ) ;
2010-11-21 21:26:35 +00:00
# endif
2010-11-22 22:45:38 +00:00
}
2010-09-15 21:37:13 +00:00
l . call ( 0 , 0 ) ;
l . getglobal ( " conky " ) ;
l . getfield ( - 1 , " text " ) ;
l . replace ( - 2 ) ;
if ( l . type ( - 1 ) ! = lua : : TSTRING )
2010-11-21 21:44:04 +00:00
throw conky : : error ( _ ( " missing text block in configuration " ) ) ;
2010-09-15 21:37:13 +00:00
/* Remove \\-\n. */
l . gsub ( l . tocstring ( - 1 ) , " \\ \n " , " " ) ;
l . replace ( - 2 ) ;
global_text = strdup ( l . tocstring ( - 1 ) ) ;
l . pop ( ) ;
// XXX: what does this do?
// global_text_lines = line + 1;
2008-12-16 04:17:56 +00:00
2010-09-15 21:37:13 +00:00
#if 0
2010-02-16 16:00:33 +00:00
# if defined(BUILD_NCURSES)
2010-01-07 02:38:12 +00:00
# if defined(BUILD_X11)
2010-04-30 17:33:21 +00:00
if ( out_to_x . get ( * state ) & & out_to_ncurses . get ( * state ) ) {
2009-09-20 01:48:00 +00:00
NORM_ERR ( " out_to_x and out_to_ncurses are incompatible, turning out_to_ncurses off " ) ;
2010-04-30 17:33:21 +00:00
state - > pushboolean ( false ) ;
out_to_ncurses . lua_set ( * state ) ;
2009-09-20 01:48:00 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-04-30 17:06:17 +00:00
if ( ( out_to_stdout . get ( * state ) | | out_to_stderr . get ( * state ) )
2010-04-30 17:33:21 +00:00
& & out_to_ncurses . get ( * state ) ) {
2009-09-20 01:48:00 +00:00
NORM_ERR ( " out_to_ncurses conflicts with out_to_console and out_to_stderr, disabling the later ones " ) ;
2010-04-30 17:06:17 +00:00
// XXX: this will need some rethinking
state - > pushboolean ( false ) ;
out_to_stdout . lua_set ( * state ) ;
state - > pushboolean ( false ) ;
out_to_stderr . lua_set ( * state ) ;
2009-09-20 01:48:00 +00:00
}
2010-02-16 16:00:33 +00:00
# endif /* BUILD_NCURSES */
2010-09-15 21:37:13 +00:00
# endif
2009-08-07 07:24:24 +00:00
}
2008-06-19 19:59:30 +00:00
static void print_help ( const char * prog_name ) {
printf ( " Usage: %s [OPTION]... \n "
2012-04-11 16:06:47 +00:00
PACKAGE_NAME " is a system monitor that renders text on desktop or to own transparent \n "
2009-08-07 07:24:24 +00:00
" window. Command line options will override configurations defined in config \n "
2008-06-19 19:59:30 +00:00
" file. \n "
" -v, --version version \n "
" -q, --quiet quiet mode \n "
2009-06-07 00:10:20 +00:00
" -D, --debug increase debugging output, ie. -DD for more debugging \n "
2008-06-19 19:59:30 +00:00
" -c, --config=FILE config file to load \n "
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2009-02-22 17:55:39 +00:00
" -C, --print-config print the builtin default config to stdout \n "
" e.g. 'conky -C > ~/.conkyrc' will create a new default config \n "
# endif
2008-06-19 19:59:30 +00:00
" -d, --daemonize daemonize, fork to background \n "
" -h, --help help \n "
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2008-06-19 19:59:30 +00:00
" -a, --alignment=ALIGNMENT text alignment on screen, {top,bottom,middle}_{left,right,middle} \n "
" -f, --font=FONT font to use \n "
2010-01-13 09:49:36 +00:00
" -X, --display=DISPLAY X11 display to use \n "
2008-06-19 19:59:30 +00:00
# ifdef OWN_WINDOW
2009-08-07 07:24:24 +00:00
" -o, --own-window create own window to draw \n "
2008-06-19 19:59:30 +00:00
# endif
" -b, --double-buffer double buffer (prevents flickering) \n "
2009-08-07 07:24:24 +00:00
" -w, --window-id=WIN_ID window id to draw \n "
2008-06-19 19:59:30 +00:00
" -x X x position \n "
" -y Y y position \n "
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2008-06-19 19:59:30 +00:00
" -t, --text=TEXT text to render, remember single quotes, like -t '$uptime' \n "
" -u, --interval=SECS update interval \n "
2012-04-11 16:06:47 +00:00
" -i COUNT number of times to update " PACKAGE_NAME " (and quit) \n "
2009-10-03 21:26:39 +00:00
" -p, --pause=SECS pause for SECS seconds at startup before doing anything \n " ,
2008-06-19 19:59:30 +00:00
prog_name
) ;
}
2010-02-20 13:34:40 +00:00
inline void reset_optind ( ) {
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) \
2012-06-28 16:56:01 +00:00
| | defined ( __NetBSD__ ) | | defined ( __DragonFly__ )
2010-02-20 13:34:40 +00:00
optind = optreset = 1 ;
# else
optind = 0 ;
# endif
}
2008-02-20 10:01:13 +00:00
/* : means that character before that takes an argument */
2010-04-13 15:02:39 +00:00
static const char * getopt_string = " vVqdDSs:t:u:i:hc:p: "
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-04-01 17:06:31 +00:00
" x:y:w:a:f:X: "
2005-07-20 00:30:40 +00:00
# ifdef OWN_WINDOW
2008-02-20 20:30:45 +00:00
" o "
2005-07-20 00:30:40 +00:00
# endif
2008-02-20 20:30:45 +00:00
" b "
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2008-12-12 14:33:25 +00:00
" C "
# endif
2008-01-06 01:35:14 +00:00
;
2008-02-20 20:30:45 +00:00
static const struct option longopts [ ] = {
{ " help " , 0 , NULL , ' h ' } ,
{ " version " , 0 , NULL , ' V ' } ,
2010-03-02 19:26:59 +00:00
{ " quiet " , 0 , NULL , ' q ' } ,
2008-11-30 20:53:20 +00:00
{ " debug " , 0 , NULL , ' D ' } ,
2008-02-20 20:30:45 +00:00
{ " config " , 1 , NULL , ' c ' } ,
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2008-12-12 14:33:25 +00:00
{ " print-config " , 0 , NULL , ' C ' } ,
# endif
2008-02-20 20:30:45 +00:00
{ " daemonize " , 0 , NULL , ' d ' } ,
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2008-02-20 20:30:45 +00:00
{ " alignment " , 1 , NULL , ' a ' } ,
{ " font " , 1 , NULL , ' f ' } ,
2009-04-01 17:06:31 +00:00
{ " display " , 1 , NULL , ' X ' } ,
2008-01-06 01:35:14 +00:00
# ifdef OWN_WINDOW
2009-08-07 07:24:24 +00:00
{ " own-window " , 0 , NULL , ' o ' } ,
2008-01-06 01:35:14 +00:00
# endif
2008-02-20 20:30:45 +00:00
{ " double-buffer " , 0 , NULL , ' b ' } ,
2009-08-07 07:24:24 +00:00
{ " window-id " , 1 , NULL , ' w ' } ,
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2008-02-20 20:30:45 +00:00
{ " text " , 1 , NULL , ' t ' } ,
2010-03-02 19:26:59 +00:00
{ " interval " , 1 , NULL , ' u ' } ,
{ " pause " , 1 , NULL , ' p ' } ,
2008-02-20 20:30:45 +00:00
{ 0 , 0 , 0 , 0 }
} ;
2005-07-30 22:59:01 +00:00
2010-02-23 01:58:44 +00:00
void set_current_config ( ) {
/* load current_config, CONFIG_FILE or SYSTEM_CONFIG_FILE */
2010-09-12 12:01:34 +00:00
struct stat s ;
2010-02-23 01:58:44 +00:00
2010-03-04 10:42:38 +00:00
if ( current_config . empty ( ) ) {
2010-02-23 01:58:44 +00:00
/* Try to use personal config file first */
2010-03-04 10:42:38 +00:00
std : : string buf = to_real_path ( CONFIG_FILE ) ;
2010-09-12 12:01:34 +00:00
if ( stat ( buf . c_str ( ) , & s ) = = 0 )
2010-03-04 10:42:38 +00:00
current_config = buf ;
2010-09-12 12:01:34 +00:00
}
2010-02-23 01:58:44 +00:00
2010-09-12 12:01:34 +00:00
/* Try to use system config file if personal config does not exist */
if ( current_config . empty ( ) & & ( stat ( SYSTEM_CONFIG_FILE , & s ) = = 0 ) )
current_config = SYSTEM_CONFIG_FILE ;
2010-02-23 01:58:44 +00:00
2010-09-12 12:01:34 +00:00
/* No readable config found */
if ( current_config . empty ( ) ) {
# define NOCFGFILEFOUND "no personal or system-wide config file found"
2010-02-23 01:58:44 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2010-09-12 14:23:06 +00:00
current_config = builtin_config_magic ;
2010-09-12 12:01:34 +00:00
NORM_ERR ( NOCFGFILEFOUND " , using builtin default " ) ;
2010-02-23 01:58:44 +00:00
# else
2010-11-21 21:44:04 +00:00
throw conky : : error ( NOCFGFILEFOUND ) ;
2010-09-12 12:01:34 +00:00
# endif
2010-02-23 01:58:44 +00:00
}
2010-09-12 12:01:34 +00:00
// "-" stands for "read from stdin"
if ( current_config = = " - " )
current_config = " /dev/stdin " ;
2010-02-23 01:58:44 +00:00
}
2009-08-07 07:24:24 +00:00
void initialisation ( int argc , char * * argv ) {
2005-11-23 19:05:23 +00:00
struct sigaction act , oact ;
2009-08-07 07:24:24 +00:00
set_default_configurations ( ) ;
2010-02-20 01:25:38 +00:00
2010-11-21 14:46:42 +00:00
set_current_config ( ) ;
2010-09-15 21:37:13 +00:00
load_config_file ( ) ;
2007-10-23 21:52:11 +00:00
2005-07-30 22:59:01 +00:00
/* handle other command line arguments */
2010-02-20 13:34:40 +00:00
reset_optind ( ) ;
2006-03-22 19:27:31 +00:00
2007-12-31 00:00:35 +00:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2008-02-20 20:30:45 +00:00
if ( ( kd = kvm_open ( " /dev/null " , " /dev/null " , " /dev/null " , O_RDONLY ,
" kvm_open " ) ) = = NULL ) {
2009-07-16 18:28:23 +00:00
CRIT_ERR ( NULL , NULL , " cannot read kvm " ) ;
2008-02-20 20:30:45 +00:00
}
2006-03-22 19:27:31 +00:00
# endif
2008-02-20 20:30:45 +00:00
2005-07-30 22:59:01 +00:00
while ( 1 ) {
2008-01-06 01:35:14 +00:00
int c = getopt_long ( argc , argv , getopt_string , longopts , NULL ) ;
2010-01-26 21:05:04 +00:00
int startup_pause ;
2012-07-16 22:05:54 +00:00
char * conv_end ;
2008-01-06 01:35:14 +00:00
2008-02-20 20:30:45 +00:00
if ( c = = - 1 ) {
2005-07-30 22:59:01 +00:00
break ;
2008-01-06 01:35:14 +00:00
}
2005-07-30 22:59:01 +00:00
switch ( c ) {
2008-02-20 20:30:45 +00:00
case ' d ' :
2010-03-05 12:33:22 +00:00
state - > pushboolean ( true ) ;
fork_to_background . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2005-08-08 01:18:52 +00:00
case ' f ' :
2010-09-08 15:30:04 +00:00
state - > pushstring ( optarg ) ;
font . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2005-08-08 01:18:52 +00:00
case ' a ' :
2010-02-24 19:51:33 +00:00
state - > pushstring ( optarg ) ;
text_alignment . lua_set ( * state ) ;
2005-08-08 01:18:52 +00:00
break ;
2010-03-04 17:31:28 +00:00
case ' X ' :
state - > pushstring ( optarg ) ;
display_name . lua_set ( * state ) ;
break ;
2005-07-20 00:30:40 +00:00
# ifdef OWN_WINDOW
2008-02-20 20:30:45 +00:00
case ' o ' :
2010-02-26 13:37:34 +00:00
state - > pushboolean ( true ) ;
own_window . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2005-07-20 00:30:40 +00:00
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_XDBE
2008-02-20 20:30:45 +00:00
case ' b ' :
2010-04-23 19:54:40 +00:00
state - > pushboolean ( true ) ;
use_xdbe . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2012-04-11 16:06:47 +00:00
# else
case ' b ' :
state - > pushboolean ( true ) ;
use_xpmdb . lua_set ( * state ) ;
break ;
2005-07-20 00:30:40 +00:00
# endif
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2008-02-20 20:30:45 +00:00
case ' t ' :
2010-02-20 14:28:05 +00:00
free_and_zero ( global_text ) ;
2010-08-29 18:01:05 +00:00
global_text = strndup ( optarg , max_user_text . get ( * state ) ) ;
2009-08-07 07:24:24 +00:00
convert_escapes ( global_text ) ;
2008-02-20 20:30:45 +00:00
break ;
2005-07-30 22:59:01 +00:00
2008-02-20 20:30:45 +00:00
case ' u ' :
2012-07-16 22:05:54 +00:00
state - > pushinteger ( strtol ( optarg , & conv_end , 10 ) ) ;
if ( * conv_end ! = 0 ) { CRIT_ERR ( NULL , NULL , " '%s' is a wrong update-interval " , optarg ) ; }
2010-09-11 12:25:19 +00:00
update_interval . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2005-07-30 22:59:01 +00:00
2008-02-20 20:30:45 +00:00
case ' i ' :
2012-07-16 22:05:54 +00:00
state - > pushinteger ( strtol ( optarg , & conv_end , 10 ) ) ;
if ( * conv_end ! = 0 ) { CRIT_ERR ( NULL , NULL , " '%s' is a wrong number of update-times " , optarg ) ; }
2010-08-31 09:49:37 +00:00
total_run_times . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2008-02-20 20:30:45 +00:00
case ' x ' :
2012-07-16 22:05:54 +00:00
state - > pushinteger ( strtol ( optarg , & conv_end , 10 ) ) ;
if ( * conv_end ! = 0 ) { CRIT_ERR ( NULL , NULL , " '%s' is a wrong value for the X-position " , optarg ) ; }
2010-04-23 20:00:32 +00:00
gap_x . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2005-07-30 22:59:01 +00:00
2008-02-20 20:30:45 +00:00
case ' y ' :
2012-07-16 22:05:54 +00:00
state - > pushinteger ( strtol ( optarg , & conv_end , 10 ) ) ;
if ( * conv_end ! = 0 ) { CRIT_ERR ( NULL , NULL , " '%s' is a wrong value for the Y-position " , optarg ) ; }
2010-04-23 20:00:32 +00:00
gap_y . lua_set ( * state ) ;
2008-02-20 20:30:45 +00:00
break ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-10-03 21:26:39 +00:00
case ' p ' :
2010-01-26 21:05:04 +00:00
if ( first_pass ) {
2010-01-26 20:37:16 +00:00
startup_pause = atoi ( optarg ) ;
sleep ( startup_pause ) ;
}
2009-10-03 21:26:39 +00:00
break ;
2005-07-30 22:59:01 +00:00
2008-02-20 20:30:45 +00:00
case ' ? ' :
2010-11-15 16:07:38 +00:00
throw unknown_arg_throw ( ) ;
2005-07-30 22:59:01 +00:00
}
}
2010-09-15 21:37:13 +00:00
conky : : set_config_settings ( * state ) ;
2010-11-13 22:59:31 +00:00
# ifdef BUILD_X11
2010-10-31 17:17:22 +00:00
if ( out_to_x . get ( * state ) ) {
current_text_color = default_color . get ( * state ) ;
}
2010-11-13 22:59:31 +00:00
# endif
2010-10-31 17:17:22 +00:00
2005-07-30 22:59:01 +00:00
/* generate text and get initial size */
2009-08-07 07:24:24 +00:00
extract_variable_text ( global_text ) ;
2010-02-20 14:28:05 +00:00
free_and_zero ( global_text ) ;
2006-03-06 06:57:30 +00:00
/* fork */
2010-03-05 12:33:22 +00:00
if ( fork_to_background . get ( * state ) & & first_pass ) {
2006-03-07 20:35:11 +00:00
int pid = fork ( ) ;
2008-02-20 20:30:45 +00:00
2006-03-07 20:35:11 +00:00
switch ( pid ) {
2008-02-20 20:30:45 +00:00
case - 1 :
2009-08-01 18:45:43 +00:00
NORM_ERR ( PACKAGE_NAME " : couldn't fork() to background: %s " ,
2008-02-20 20:30:45 +00:00
strerror ( errno ) ) ;
break ;
2006-03-06 06:57:30 +00:00
2008-02-20 20:30:45 +00:00
case 0 :
/* child process */
usleep ( 25000 ) ;
fprintf ( stderr , " \n " ) ;
fflush ( stderr ) ;
break ;
2006-03-06 06:57:30 +00:00
2008-02-20 20:30:45 +00:00
default :
/* parent process */
2008-07-12 10:25:05 +00:00
fprintf ( stderr , PACKAGE_NAME " : forked to background, pid is %d \n " ,
2008-02-20 20:30:45 +00:00
pid ) ;
fflush ( stderr ) ;
2010-11-15 16:07:38 +00:00
throw fork_throw ( ) ;
2006-03-06 06:57:30 +00:00
}
}
2005-07-30 22:59:01 +00:00
2010-08-29 18:01:05 +00:00
text_buffer = ( char * ) malloc ( max_user_text . get ( * state ) ) ;
memset ( text_buffer , 0 , max_user_text . get ( * state ) ) ;
2010-08-29 21:50:32 +00:00
tmpstring1 = ( char * ) malloc ( text_buffer_size . get ( * state ) ) ;
memset ( tmpstring1 , 0 , text_buffer_size . get ( * state ) ) ;
tmpstring2 = ( char * ) malloc ( text_buffer_size . get ( * state ) ) ;
memset ( tmpstring2 , 0 , text_buffer_size . get ( * state ) ) ;
2008-03-19 22:28:23 +00:00
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-08-07 07:24:24 +00:00
X11_create_window ( ) ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2010-09-11 12:25:19 +00:00
llua_setup_info ( & info , active_update_interval ( ) ) ;
2010-01-07 18:14:53 +00:00
# ifdef BUILD_WEATHER_XOAP
2009-08-03 17:58:21 +00:00
xmlInitParser ( ) ;
2010-01-07 18:14:53 +00:00
# endif /* BUILD_WEATHER_XOAP */
2005-07-30 22:59:01 +00:00
2005-11-01 06:51:48 +00:00
/* Set signal handlers */
2005-11-23 19:05:23 +00:00
act . sa_handler = signal_handler ;
sigemptyset ( & act . sa_mask ) ;
act . sa_flags = 0 ;
2005-11-24 02:18:42 +00:00
# ifdef SA_RESTART
2005-11-23 19:05:23 +00:00
act . sa_flags | = SA_RESTART ;
2005-11-24 02:18:42 +00:00
# endif
2005-11-23 19:05:23 +00:00
2008-09-24 06:59:45 +00:00
if ( sigaction ( SIGINT , & act , & oact ) < 0
2009-07-26 00:26:22 +00:00
| | sigaction ( SIGALRM , & act , & oact ) < 0
2008-09-24 06:59:45 +00:00
| | sigaction ( SIGUSR1 , & act , & oact ) < 0
| | sigaction ( SIGHUP , & act , & oact ) < 0
| | sigaction ( SIGTERM , & act , & oact ) < 0 ) {
2009-08-01 18:45:43 +00:00
NORM_ERR ( " error setting signal handler: %s " , strerror ( errno ) ) ;
2005-07-30 22:59:01 +00:00
}
2005-11-01 06:51:48 +00:00
2009-08-01 20:36:38 +00:00
llua_startup_hook ( ) ;
2009-07-17 16:01:41 +00:00
}
2010-02-25 06:07:00 +00:00
int main ( int argc , char * * argv )
{
2010-11-13 18:45:04 +00:00
# ifdef BUILD_I18N
2010-10-30 22:02:02 +00:00
setlocale ( LC_ALL , " " ) ;
bindtextdomain ( PACKAGE_NAME , LOCALE_DIR ) ;
textdomain ( PACKAGE_NAME ) ;
2010-11-13 18:45:04 +00:00
# endif
2009-07-17 16:01:41 +00:00
argc_copy = argc ;
argv_copy = argv ;
g_signal_pending = 0 ;
clear_net_stats ( ) ;
2010-08-29 11:31:18 +00:00
# ifdef BUILD_CURL
2010-09-12 13:42:20 +00:00
struct curl_global_initializer {
curl_global_initializer ( )
{
if ( curl_global_init ( CURL_GLOBAL_ALL ) )
NORM_ERR ( " curl_global_init() failed, you may not be able to use curl variables " ) ;
}
~ curl_global_initializer ( )
{ curl_global_cleanup ( ) ; }
} ;
curl_global_initializer curl_global ;
2010-08-29 11:31:18 +00:00
# endif
2009-07-17 16:01:41 +00:00
/* handle command line parameters that don't change configs */
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-07-17 16:01:41 +00:00
if ( ! setlocale ( LC_CTYPE , " " ) ) {
2009-08-01 18:45:43 +00:00
NORM_ERR ( " Can't set the specified locale! \n Check LANG, LC_CTYPE, LC_ALL. " ) ;
2009-07-17 16:01:41 +00:00
}
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-07-17 16:01:41 +00:00
while ( 1 ) {
int c = getopt_long ( argc , argv , getopt_string , longopts , NULL ) ;
if ( c = = - 1 ) {
break ;
}
switch ( c ) {
2009-12-28 23:18:12 +00:00
case ' D ' :
global_debug_level + + ;
break ;
2009-07-17 16:01:41 +00:00
case ' v ' :
case ' V ' :
2010-09-12 13:42:20 +00:00
print_version ( ) ;
return EXIT_SUCCESS ;
2009-07-17 16:01:41 +00:00
case ' c ' :
2010-03-04 10:42:38 +00:00
current_config = optarg ;
2009-07-17 16:01:41 +00:00
break ;
case ' q ' :
2010-01-02 19:48:50 +00:00
if ( ! freopen ( " /dev/null " , " w " , stderr ) )
2009-12-17 21:30:00 +00:00
CRIT_ERR ( 0 , 0 , " could not open /dev/null as stderr! " ) ;
2009-07-17 16:01:41 +00:00
break ;
case ' h ' :
print_help ( argv [ 0 ] ) ;
return 0 ;
2010-01-17 02:00:51 +00:00
# ifdef BUILD_BUILTIN_CONFIG
2009-07-17 16:01:41 +00:00
case ' C ' :
2010-09-12 14:23:06 +00:00
std : : cout < < defconfig ;
2009-07-17 16:01:41 +00:00
return 0 ;
# endif
2010-01-07 02:38:12 +00:00
# ifdef BUILD_X11
2009-07-17 16:01:41 +00:00
case ' w ' :
2009-08-07 07:24:24 +00:00
window . window = strtol ( optarg , 0 , 0 ) ;
2009-07-17 16:01:41 +00:00
break ;
2010-01-07 02:38:12 +00:00
# endif /* BUILD_X11 */
2009-07-17 16:01:41 +00:00
case ' ? ' :
2010-09-12 13:42:20 +00:00
return EXIT_FAILURE ;
2009-07-17 16:01:41 +00:00
}
}
2010-10-31 17:17:22 +00:00
try {
2010-11-20 23:23:27 +00:00
set_current_config ( ) ;
state . reset ( new lua : : state ) ;
2010-10-31 17:17:22 +00:00
conky : : export_symbols ( * state ) ;
2010-09-15 21:37:13 +00:00
2010-01-07 18:14:53 +00:00
# ifdef BUILD_WEATHER_XOAP
2010-11-16 21:45:06 +00:00
/* Load xoap keys, if existing */
load_xoap_keys ( ) ;
2010-01-07 18:14:53 +00:00
# endif /* BUILD_WEATHER_XOAP */
Revert "Undid last 3 commits, see rest of the comment for the reason:"
First of all, we may or may not agree, but I consider reverting my
commits without prior discussion as a minimum unpolite.
I also don't like sites that oblige to register, thats the very reason
why I went with noaa first (and why I use that myself).
Howver, weather.com has a couple of nice features forom an user
viewpoint:
1. Their icons can be used to add a visual quality to the weather
report.
2. They have forecast data, which is not possible to have with noaa
(using TAF its an option, but its going to be very difficult and will
be limited in time and scope).
Nobody is obliged to do anything, people who likes noaa will use noaa,
people that don't mind register or wants the additional benefit will use
weather.com.
Having libxms2 as a dragged depends is, first of all, also with other
options (rss and eve), second we can try to work around it with an
additional compilation flag if really deemed necessary.
This reverts commit d872562942812a7c71245acf7cc5f028bd4b7b4d.
2009-07-18 17:13:37 +00:00
2009-07-17 16:01:41 +00:00
# ifdef HAVE_SYS_INOTIFY_H
2010-11-16 21:45:06 +00:00
// the file descriptor will be automatically closed on exit
inotify_fd = inotify_init ( ) ;
if ( inotify_fd ! = - 1 ) {
fcntl ( inotify_fd , F_SETFL , fcntl ( inotify_fd , F_GETFL ) | O_NONBLOCK ) ;
2010-04-12 20:40:16 +00:00
2010-11-16 21:45:06 +00:00
fcntl ( inotify_fd , F_SETFD , fcntl ( inotify_fd , F_GETFD ) | FD_CLOEXEC ) ;
}
2009-07-17 16:01:41 +00:00
# endif /* HAVE_SYS_INOTIFY_H */
2010-10-31 17:17:22 +00:00
initialisation ( argc , argv ) ;
2010-09-15 21:37:13 +00:00
2010-10-31 17:17:22 +00:00
first_pass = 0 ; /* don't ever call fork() again */
2010-09-15 21:37:13 +00:00
2010-11-15 16:07:38 +00:00
main_loop ( ) ;
2010-02-12 17:39:01 +00:00
}
2010-11-15 16:07:38 +00:00
catch ( fork_throw & e ) { return EXIT_SUCCESS ; }
catch ( unknown_arg_throw & e ) { return EXIT_FAILURE ; }
2010-11-16 12:41:44 +00:00
catch ( obj_create_error & e ) {
std : : cerr < < e . what ( ) < < std : : endl ;
clean_up ( NULL , NULL ) ;
return EXIT_FAILURE ;
2010-04-12 20:40:16 +00:00
}
2010-11-21 21:44:04 +00:00
catch ( std : : exception & e ) {
std : : cerr < < PACKAGE_NAME " : " < < e . what ( ) < < std : : endl ;
2010-11-17 23:36:36 +00:00
return EXIT_FAILURE ;
}
2006-01-07 07:01:22 +00:00
2007-12-31 00:00:35 +00:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2006-03-22 19:27:31 +00:00
kvm_close ( kd ) ;
# endif
2008-02-20 20:30:45 +00:00
2010-02-19 12:21:40 +00:00
# ifdef LEAKFREE_NCURSES
2010-02-18 23:09:24 +00:00
_nc_free_and_exit ( 0 ) ; //hide false memleaks
# endif
2005-07-30 22:59:01 +00:00
return 0 ;
2009-07-27 20:47:19 +00:00
2005-07-30 22:59:01 +00:00
}
2005-11-01 06:51:48 +00:00
2008-12-15 21:40:24 +00:00
static void signal_handler ( int sig )
2005-11-01 06:51:48 +00:00
{
2009-08-07 07:24:24 +00:00
/* signal handler is light as a feather, as it should be.
* we will poll g_signal_pending with each loop of conky
2011-02-26 17:54:48 +00:00
* and do any signal processing there , NOT here */
g_signal_pending = sig ;
2005-11-01 06:51:48 +00:00
}