/*
 *  Copyright (c) 2006, Lars Engels <lars.engels@0x20.net>
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation and/or
 *       other materials provided with the distribution.
 *     * Neither the name of the Free Software Foundation nor the names of its 
 *       contributors may be used to endorse or promote products derived from this
 *       software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/sysctl.h>

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xosd.h>

#include "nbosd.h"


int
main(int argc, char *argv[]) {
	char *p;
	int ch;

	SYSCTL_INFO sysctl_info;
	CONFIG config;

	config.font = FONT;
	config.color = COLOR;
	config.pos_x = POS_X;
	config.pos_y = POS_Y;
	config.sleeptime = SLEEP;

	while ((ch = getopt(argc, argv, "c:f:hx:y:t:")) != -1)
		switch (ch) {
		case 'c':
			config.color = optarg;
			break;
		case 'f':
			config.font = optarg;
			break;
		case 'h':
			usage();
			break;
		case 't':
			if (config.sleeptime != 0) {
				config.sleeptime = atoi(optarg) * 1000;
			}
			break;
		case 'x':
			config.pos_x = strtol(optarg, &p, 10);
			break;
		case 'y':
			config.pos_y = strtol(optarg, &p, 10);
			break;
		case '?':
		default:
			usage();
			break;
		}
	argc -= optind;
	argv += optind;

	get_sysctls(&sysctl_info);
	show_bars(&sysctl_info, &config);

	return(0);
}

static void
get_sysctls(SYSCTL_INFO *sysctl_info) {
	sysctl_info->len_int = sizeof(int);
	sysctl_info->len_freq = sizeof(sysctl_info->freq_levels);
	sysctl_info->cpu_freq_avail = sysctlbyname(SYSCTL_CPU_FREQ,
			&sysctl_info->cpu_freq, &sysctl_info->len_int, NULL, 0);
	sysctl_info->freq_levels_avail = sysctlbyname(SYSCTL_CPU_FREQ_LEVELS,
			sysctl_info->freq_levels, &sysctl_info->len_freq, NULL, 0);
	sysctl_info->battery_life_avail = sysctlbyname(SYSCTL_BATTERY_LIFE,
			&sysctl_info->battery_life, &sysctl_info->len_int, NULL, 0);
	sysctl_info->battery_state_avail = sysctlbyname(SYSCTL_BATTERY_STATE,
			&sysctl_info->battery_state, &sysctl_info->len_int, NULL, 0);
}

static void
show_bars(SYSCTL_INFO *sysctl_info, CONFIG *config) {
	char *cpu_title = "CPU Frequency: ";
	char *battery_title = "Battery Life: ";
	char *state_prefix = "AC state: ";
	char state[100];
	int frequency;

	osd = xosd_create(5);	/* create a four lined xosd */

	if (osd == NULL) {
		perror ("Could not create \"osd\"");
		exit(1);
	}

	/* set how the osd should look like */
	xosd_set_font (osd, config->font);
	xosd_set_colour (osd, config->color);
	xosd_set_outline_offset (osd, 2);
	xosd_set_outline_colour (osd, "black");
	xosd_set_align (osd, XOSD_left);
	xosd_set_pos (osd, XOSD_bottom);
	xosd_set_horizontal_offset (osd, config->pos_x);
	xosd_set_vertical_offset (osd, config->pos_y);
	xosd_set_bar_length(osd, 50);

	/* show the OSD */ 
	if (sysctl_info->freq_levels_avail >= 0 && sysctl_info->cpu_freq_avail >= 0) {
		/* display CPU frequency */
		xosd_display(osd, 0, XOSD_printf, "%s    %i MHz",cpu_title, 
				sysctl_info->cpu_freq);
		frequency = sysctl_info->cpu_freq / (strtoq(sysctl_info->freq_levels, 
					NULL, 10)/100);
		xosd_display(osd, 1, XOSD_percentage, sysctl_info->cpu_freq 
				/ (strtoq(sysctl_info->freq_levels, NULL, 10)/100));
	}
	if (sysctl_info->battery_life_avail >= 0 && sysctl_info->battery_life >= 0) { 
		/* display Battery Life */
		xosd_display(osd, 2, XOSD_printf, "%s    %i %%", battery_title, 
				sysctl_info->battery_life);
		xosd_display(osd, 3, XOSD_percentage, sysctl_info->battery_life);
	}
	else xosd_display (osd, 2, XOSD_printf, "No Battery");

	 /*  states: 
	  * 	0 fully charged
	  * 	1 discharging
	  *	2 charging
	  *	5 critical
	  *	7 no battery
	  */
	if (sysctl_info->battery_state_avail >= 0) {
		switch (sysctl_info->battery_state) {
		case 0:
			strlcpy(state, "Fully charged", sizeof(state));
			break;
		case 1:
			strlcpy(state, "Discharging", sizeof(state));
			break;
		case 2:
			strlcpy(state, "Loading", sizeof(state));
			break;
		case 5:
			strlcpy(state, "CRITICAL!", sizeof(state));
			break;
		case 7:
			strlcpy(state, "No Battery", sizeof(state));
			break;
		default:
			strlcpy(state, "Unknown", sizeof(state));
			break;
		}
		/* display AC state */
		xosd_display(osd, 4, XOSD_printf, "%s %s", state_prefix, state);
	}

	/* nothing usable found */
	if (sysctl_info->freq_levels_avail != 0 && sysctl_info->cpu_freq_avail != 0 &&
		sysctl_info->battery_life_avail != 0)
		xosd_display(osd, 0, XOSD_printf, "No compatible hardware found!");


	usleep(config->sleeptime);
	xosd_destroy(osd);
}

static void
usage(void) {
	fprintf(stderr,
		"Usage: nbosd [-h] [-c color] [-f font] [-t time (ms)] [-x x-position] [-y y-position]\n");
	exit (1);
}



syntax highlighted by Code2HTML, v. 0.9.1