Logo Search packages:      
Sourcecode: yacpi version File versions

yacpi.c

/* acpi application yacpi
 * Copyright (C) 2005-2007 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 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;
      globals->samplef=samplev;
      if (globals->samplef)
            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 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 ();
      globals->samplef=samplev;
      if (globals->samplef)
            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: 18.03.2007\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