Logo Search packages:      
Sourcecode: yacpi version File versions  Download package

yacpi.c

/* acpi application yacpi
 * Copyright (C) 2005-2006 Nico Golde <nico@ngolde.de>
 *
 * 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 2 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
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-13007, USA.
 */

#define TRUE "1"
#define FALSE "0"
#define _GNU_SOURCE

#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <getopt.h>
#include <sys/types.h>
#include "libacpi.h"
#include "get_cpu.h"

#define ACPI_VER "2.0"

global_t *globals;

/* options */
static struct option long_options[] = {
  {"help", 0, NULL, 'h'},
  {"version", 0, NULL, 'v'},
  {"samples", 1, NULL, 's'},
  {"text", 0, NULL, 't'},
  {"loop", 0, NULL, 'l'},
  {"delay", 1, NULL, 'd'},
  {"multiple", 0, NULL, 'm'},
  {NULL, 0, NULL, 0}
};


void helpbox (int x1, int y1, int x2, int y2)
{
  int i, j;

  attron (WA_REVERSE);
  for (i = y1; i <= y2; i++) {
    for (j = x1; j <= x2; j++) {
      mvaddch (i, j, ' ');
    }
  }
  attroff (WA_REVERSE);
}

int monitor_help (void)
{
  int rval;

  attrset (WA_REVERSE);
  curs_set (2);
  echo ();
  mvprintw (LINES - 2, 0, "Seconds before refresh: ");
  move (LINES - 2, 24);
  scanw ("%d", &rval);
  if (rval <= 0 || rval > 1000) {
    clear();
    mvprintw (LINES - 4, 0, "Specify a valid value");
    monitor_help ();
  }
  curs_set (0);
  noecho ();
  return rval;
}

int samples_help (void)
{
  int rval;

  attrset (WA_REVERSE);
  curs_set (2);
  echo ();
  mvprintw (LINES - 2, 0, "Number of samples: ");
  refresh();
  move (LINES - 2, 19);
  rval = 1;
  scanw ("%d", &rval);
  if (rval <= 0 || rval > 1000) {
    clear();
    mvprintw (LINES - 4, 0, "Specify a valid value");
    samples_help ();
  }
  curs_set (0);
  noecho ();

  return rval;
}

void help (void)
{
  int centerx, centery;
  int userinput;
  int offset = 13;
  int offsetstr = 11;
  char *helptext = "Press any[tm] key to continue.";

  centerx = COLS / 2;
  centery = LINES / 2;

  helpbox (centerx - 15, centery, centerx + 14, centery + 6);

  attron (WA_REVERSE);
  /* Keys */
  mvprintw (centery + 1, centerx - offset, "q");
  mvprintw (centery + 2, centerx - offset, "r");
  mvprintw (centery + 3, centerx - offset, "h");
  mvprintw (centery + 4, centerx - offset, "s");
  mvprintw (centery + 5, centerx - offset, "m");

  /* Descriptions */
  mvaddstr (centery + 1, centerx - offsetstr, "End Yacpi ...");
  mvaddstr (centery + 2, centerx - offsetstr, "Reload ACPI data ...");
  mvaddstr (centery + 3, centerx - offsetstr, "Show this help ...");
  mvaddstr (centery + 4, centerx - offsetstr, "Specify samples ...");
  mvaddstr (centery + 5, centerx - offsetstr, "Monitor (loop) mode ...");
  mvprintw (LINES - 1, COLS - strlen (helptext), "%s", helptext);
  attroff (WA_REVERSE);

  userinput = getch ();

  /* Return input back into input queue so it gets automatically
     executed. */
  if ((userinput != '\n') && (userinput != 'h') && (userinput != 'q'))
    ungetch (userinput);
}

/* change colors in the ncurses interface */
void color_change (int pct, int tmp)
{
  if (tmp == 0) {
    if (pct >= 70)
      attron (COLOR_PAIR (1));
    else if (pct >= 50 && pct <= 74)
      attron (COLOR_PAIR (2));
    else if (pct >= 0 && pct <= 49)
      attron (COLOR_PAIR (3));
  }
  else {
    if (pct <= 59)
      attron (COLOR_PAIR (1));
    else if (pct <= 69 && pct >= 60)
      attron (COLOR_PAIR (2));
    else if (pct >= 70)
      attron (COLOR_PAIR (3));
  }
}

/* get acpi version number */
int get_acpi_version (void)
{
  FILE *acpi;
  int acpi_ver = 0;
  char buffer[512];

  if (!(acpi = fopen ("/proc/acpi/info", "r"))) {
    endwin ();
    printf ("This system does not support ACPI\n");
    exit (1);
  }
  fread (buffer, 512, 1, acpi);
  acpi_ver = strtol (buffer + 25, NULL, 10);
  fclose (acpi);
  if (acpi_ver < 20020214) {
    endwin ();
    printf ("This version requires ACPI subsystem version 20020214\n");
    return 1;
  }

  return acpi_ver;
}

/* make the window border etc. */
void print_window (void)
{
  int i;

  attron (WA_REVERSE);
  clear();
  /* print white lines and version numbers */
  for (i = 0; i < COLS; i++) {
    mvaddch (0, i, ' ');
    mvaddch (LINES - 1, i, ' ');
  }
  mvaddstr (0, 0, "* YACPI " VERSION " by Nico Golde");
  mvaddstr (LINES - 1, 0, "ACPI version detected: ");
  mvprintw (LINES - 1, 23, "%d", get_acpi_version ());

  attroff (WA_REVERSE);
  move (2, 0);
}

/* main acpi handling */

char *chargestate(battery_t *binfo){
  if(!binfo) return NULL;
  if (binfo->charge_state == CHARGE)
    return (strdup("charging")); 
  else if (binfo->charge_state == DISCHARGE)
    return (strdup("discharging")); 
  else if (binfo->charge_state == CHARGED)
    return (strdup("charged"));
  else if (binfo->charge_state == NOINFO)
    return (strdup("not supported"));
  return NULL;
}


int acpi_text_handling (int samplef, int samplev, int mflag)
{
  int i, j;
  int sleep_time = 0;
  int sampleflag = samplef, samples = samplev;
  adapter_t *ap;
  battery_t *binfo;
  temperature_t *temperature;

  binfo = NULL;
  globals = (global_t *) malloc (sizeof (global_t));    /* checked */
  power_init (globals);
  get_temp (globals);
  ap = &globals->adapter;

  if (sampleflag)
    sleep_time = 1000000 / samples;

  /* we want to acquire samples over some period of time, so . . . */
  for (i = 0; i < samples + globals->battery_count; i++) {
    if (mflag)
      for (j = 0; j < globals->battery_count; j++)
        acquire_batt_info (globals, j);
    if (i<1)
      acquire_batt_info (globals, 0);
    acquire_global_info (globals);
    usleep (sleep_time);
  }                             /* this line too */
  temperature = &globals->temperature;
  for (i = 0; i < globals->battery_count; i++) {
    binfo = &batteries[i];
    if (binfo && binfo->present){
       printf ("| %s %3d%% ", binfo->name, binfo->percentage);
       if (!ap->power == AC)
         printf ("| rtime: %02d:%02d h ", globals->rtime / 60,
                 globals->rtime % 60);
       if (ap->power == AC && binfo->charge_time > 0)
         printf ("| rctime: %02d:%02d h ", binfo->charge_time / 60,
                 binfo->charge_time % 60);
       printf("| state: %s ", chargestate(binfo)); 
    }
    if(i<1){
      if (ap->power == AC)
        printf ("| ac=on | ");
      else
        printf ("| ac=off | ");
      printf ("thermal %dc | ", temperature->temp);
      if(get_cpu_cur() && get_cpu_max ())
        printf ("cpu: %d/%d mhz | ", get_cpu_cur () / 1000, get_cpu_max () / 1000);   /* get cpu frequency */
      else
        printf ("cpu: not supported | ");   /* get cpu frequency */
      {
        char *cpu_gov = get_cpu_gov ();
        printf ("gov: %s", cpu_gov);    /* get cpu governor */
        free (cpu_gov);
      }
    }
  }
  free(globals);
  return 0;
}

void acpi_handling (int samplef, int samplev, int mflag)
{
  int i, j;
  int sleep_time = 0;
  int line = 2;
  int sampleflag = samplef, samples = samplev, battery_loops = 0;

  attrset (WA_NORMAL);
  adapter_t *ap;
  battery_t *binfo;
  temperature_t *temperature;

  binfo = NULL;
  globals = (global_t *) malloc (sizeof (global_t));    /* checked */
  power_init (globals);
  get_temp (globals);
  ap = &globals->adapter;

  /* make the window */
  print_window ();

  if (sampleflag)
    sleep_time = 1000000 / samples;

  /* we want to acquire samples over some period of time, so . . . */
  for (i = 0; i < samples + globals->battery_count; i++) {
    if (mflag)
      for (j = 0; j < globals->battery_count; j++)
        acquire_batt_info (globals, j);
    if (i<1)
      acquire_batt_info (globals, 0);
    acquire_global_info (globals);
    usleep (sleep_time);
  }                             /* this line too */
  temperature = &globals->temperature;


  /* if the terminal width isnt big enough */
  if (COLS <= 88) {
    for (i = 0; i < globals->battery_count; i++) {
      binfo = &batteries[i];
      if (i<1){
        mvprintw (line, 0, "AC:");
        if (ap->power == AC) {
          attron (COLOR_PAIR (1));
          mvprintw (line, 4, "on");
          attroff (COLOR_PAIR (1));
        }
        else {
          attron (COLOR_PAIR (3));
          mvprintw (line, 4, "off");
          attroff (COLOR_PAIR (3));
        }
        line = line + 2;
      }

      if (binfo && binfo->present) {
        if (COLS > 48){
          mvprintw (line, 0, "%s Capacity [", binfo->name);
          color_change (binfo->percentage, 0);
          for (battery_loops = 1; battery_loops <= (binfo->percentage / 4); battery_loops++)
            printw ("|");
          attrset (WA_NORMAL);

          for (battery_loops = 1; battery_loops <= 25 - (binfo->percentage / 4); battery_loops++)
            printw (" ");
          printw ("]");
          printw (" %2d%%", binfo->percentage);
        }
        else
          mvprintw (line, 0, "Battery %s on %2d%%", binfo->name,
                              binfo->percentage);
        line = line + 2;
        move (line,0); clrtoeol();
        mvprintw (line, 0, "Battery %s: %s", binfo->name, chargestate(binfo));
        line = line + 2;
        if (globals->rtime >= 0 && ap->power != AC) {
          mvprintw (line, 0, "Remaining time: %02d:%02d h        ",
                    globals->rtime / 60, globals->rtime % 60);
          line = line + 2;
        }

        if (ap->power == AC && binfo && binfo->charge_time > 0) {
          mvprintw (line, 0, "Rem. charge time: %02d:%02d h",
                    binfo->charge_time / 60, binfo->charge_time % 60);
          line = line + 2;
        }
      }
    }
  }
  else {
    for (i = 0; i < globals->battery_count; i++) {
      binfo = &batteries[i];
      if (binfo && binfo->present) {
        mvprintw (line, 0, "%s Capacity [", binfo->name);
        color_change (binfo->percentage, 0);
        for (battery_loops = 1; battery_loops <= (binfo->percentage / 2); battery_loops++)
          printw ("|");
        attrset(WA_NORMAL);

        for (battery_loops = 1; battery_loops <= (50 - binfo->percentage / 2); battery_loops++)
          printw (" ");
        printw ("]");
        printw (" %2d%%", binfo->percentage);
        attroff (COLOR_PAIR (4));
        line = line + 2;
        if(i<1){
          if (ap->power == AC) {
            printw (" - AC status: ");
            attron (COLOR_PAIR (1));
            printw ("on\n");
            attroff (COLOR_PAIR (1));
          }
          else {
            printw (" - AC status: ");
            attron (COLOR_PAIR (3));
            printw ("off\n");
            attroff (COLOR_PAIR (3));
         }
        }
        if(binfo){
            if (binfo->charge_state == CHARGE)
              mvprintw (line, 0, "Battery %s Status: charging   ", binfo->name);
            else if (binfo->charge_state == DISCHARGE)
              mvprintw (line, 0, "Battery %s Status: discharging", binfo->name);
            else if (binfo->charge_state == CHARGED)
              mvprintw (line, 0, "Battery %s Status: charged    ", binfo->name);
            else if (binfo->charge_state == NOINFO)
              mvprintw (line, 0, "Battery %s Status: not supported", binfo->name);
        }
        line = line + 2;
        if (globals->rtime >= 0 && ap->power != AC) {
          mvprintw (line, 0, "Remaining time: %02d:%02d h       ",
                    globals->rtime / 60, globals->rtime % 60);
          line = line + 2;
        }
        if (ap->power == AC && binfo && binfo->charge_time > 0) {
          mvprintw (line, 0, "Remaining charge time: %02d:%02d h",
                    binfo->charge_time / 60, binfo->charge_time % 60);
          line = line + 2;
        }
      }
    }
  }
  mvprintw (line, 0, "cpu frequency: %d/%d MHz", get_cpu_cur () / 1000, get_cpu_max () / 1000);       /* get cpu frequency */
  line = line + 2;

  {
    char *cpu_gov = get_cpu_gov ();
    mvprintw (line, 0, "cpu governor: %s", get_cpu_gov ());   /* get cpu governor */
    free (cpu_gov);
    curs_set (0);
  }
  line = line + 2;

  mvaddstr (line, 0, "Temperature:");
  color_change (temperature->temp, 1);
  move (line, 13);
  printw ("%d", temperature->temp);
  attrset (WA_NORMAL);
  move (line, 16);
  printw ("degrees C");
  refresh ();
  free(globals);

}

void show_error (void)
{
  char *help_string = "Unknown key, use 'h' for help.";

  attron (WA_REVERSE);
  mvprintw (LINES - 1, COLS - strlen (help_string), "%s", help_string);
  attroff (WA_REVERSE);
}

void usage (void)
{
  puts ("YACPI " VERSION " by Nico Golde <nico@ngolde.de>");
  puts ("usage: yacpi [options]\n"
        "short options:\n"
        "-v    print version number + release date.\n"
        "-h    print this help.\n"
        "-t    text only output.\n"
        "-l    loop every second\n"
        "-s    number of samples\n"
        "-m    more than one battery enabled (see README for details)\n"
        "-d    refresh delay (seconds before refresh)\n\n"
        "long options:\n" "--samples=value between 1 and 1000\n--delay=value refresh delay\n");
  exit (0);
}

int main (int argc, char *argv[]) {
  char ch;
  int sample_number = 0, sample_flag = FALSE,
      text_flag = FALSE, loop_flag = FALSE, delay_flag=FALSE,
      multi_flag = FALSE;
  int option, akt_optind, option_index = 0, refresh_delay=1;

  akt_optind = optind;

  /* parse command line arguments */
  while ((option = getopt_long (argc, argv, "s:d:hvtlm", long_options, &option_index)) != -1) {
    if (option == EOF)
      break;
    switch (option) {
    case 'h':
      usage ();
      break;
    case 'm':
      multi_flag = TRUE;
      break;
    case 'v':
      puts ("YACPI " VERSION " by Nico Golde - Released: 24.05.2006\n");
      exit (0);
      break;
    case 's':
      sample_number = atoi (optarg);
      if (sample_number <= 0 || sample_number > 1000) {
        printf ("\nUse a correct sample number (1-1000) ...\n");
        exit (1);
      }
      sample_flag = TRUE;
      break;
    case 't':
      text_flag = TRUE;
      break;
    case 'l':
      loop_flag = TRUE;
      break;
    case 'd':
      if (atoi(optarg)>=1 && atoi(optarg) <=1000){
        refresh_delay = atoi(optarg);
        delay_flag = TRUE;
      }else{
        printf ("\nThe delay has to be between 1 and 1000 seconds....\n");
        return 0;
      }
      break;
    default:
      usage ();
      break;
    }
  }
  if (!text_flag) {
    initscr ();
    cbreak ();
    noecho ();
    curs_set (0);
    start_color ();             /* initialize colors */
    use_default_colors ();
    init_pair (1, COLOR_GREEN, -1);
    init_pair (2, COLOR_YELLOW, -1);
    init_pair (3, COLOR_RED, -1);
    init_pair (4, COLOR_WHITE, -1);

    acpi_handling (sample_flag, sample_number, multi_flag);
    while (1) {
      if (loop_flag){
          while (1){
            acpi_handling (sample_flag, sample_number, multi_flag);
            halfdelay(5);
            if (delay_flag)
              sleep(refresh_delay);
            else
              sleep(1);
            ch=getch();
            switch(ch){
              case 'q':
                endwin();
                puts("");
                return 0;
                break;
              default:
                break;
            }
         }
      }
      /* move (2, 0); */
      ch = getch ();
      switch (ch) {
      case 'q':
        endwin ();
        puts("");
        return 0;
        break;
      case 'r':
        acpi_handling (sample_flag, sample_number, multi_flag);
        break;
      case 'h':
        help ();
        acpi_handling (sample_flag, sample_number, multi_flag);
        break;
      case 's':
        sample_number = samples_help ();
        sample_flag = TRUE;
        acpi_handling (sample_flag, sample_number, multi_flag);
        break;
      case 'm' :
           refresh_delay=monitor_help();
           delay_flag = TRUE;
           loop_flag = TRUE;
           acpi_handling(sample_flag,sample_number, multi_flag);
           break; 
      default:
        show_error ();
        break;
      }
    }
    getch ();
    endwin ();
  }
  else {
    do {
      acpi_text_handling (sample_flag, sample_number, multi_flag);
      if (loop_flag)
        sleep (refresh_delay);
    } while (loop_flag);
  }

  return 0;
}

Generated by  Doxygen 1.6.0   Back to index