root/tools/thermal/tmon/tui.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. close_panel
  2. close_window
  3. close_windows
  4. write_status_bar
  5. diag_dev_rows
  6. setup_windows
  7. resize_handler
  8. show_cooling_device
  9. show_dialogue
  10. write_dialogue_win
  11. show_control_w
  12. initialize_curses
  13. show_title_bar
  14. handle_input_val
  15. handle_input_choice
  16. handle_tui_events
  17. draw_hbar
  18. trip_type_to_char
  19. draw_tp_line
  20. show_data_w
  21. show_sensors_w
  22. disable_tui

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * tui.c ncurses text user interface for TMON program
   4  *
   5  * Copyright (C) 2013 Intel Corporation. All rights reserved.
   6  *
   7  * Author: Jacob Pan <jacob.jun.pan@linux.intel.com>
   8  */
   9 
  10 #include <unistd.h>
  11 #include <stdio.h>
  12 #include <stdlib.h>
  13 #include <string.h>
  14 #include <stdint.h>
  15 #include <ncurses.h>
  16 #include <time.h>
  17 #include <syslog.h>
  18 #include <panel.h>
  19 #include <pthread.h>
  20 #include <signal.h>
  21 
  22 #include "tmon.h"
  23 
  24 #define min(x, y) ({                            \
  25         typeof(x) _min1 = (x);                  \
  26         typeof(y) _min2 = (y);                  \
  27         (void) (&_min1 == &_min2);              \
  28         _min1 < _min2 ? _min1 : _min2; })
  29 
  30 #define max(x, y) ({                            \
  31         typeof(x) _max1 = (x);                  \
  32         typeof(y) _max2 = (y);                  \
  33         (void) (&_max1 == &_max2);              \
  34         _max1 > _max2 ? _max1 : _max2; })
  35 
  36 static PANEL *data_panel;
  37 static PANEL *dialogue_panel;
  38 static PANEL *top;
  39 
  40 static WINDOW *title_bar_window;
  41 static WINDOW *tz_sensor_window;
  42 static WINDOW *cooling_device_window;
  43 static WINDOW *control_window;
  44 static WINDOW *status_bar_window;
  45 static WINDOW *thermal_data_window;
  46 static WINDOW *dialogue_window;
  47 
  48 char status_bar_slots[10][40];
  49 static void draw_hbar(WINDOW *win, int y, int start, int len,
  50                 unsigned long pattern, bool end);
  51 
  52 static int maxx, maxy;
  53 static int maxwidth = 200;
  54 
  55 #define TITLE_BAR_HIGHT 1
  56 #define SENSOR_WIN_HIGHT 4 /* one row for tz name, one for trip points */
  57 
  58 
  59 /* daemon mode flag (set by startup parameter -d) */
  60 static int  tui_disabled;
  61 
  62 static void close_panel(PANEL *p)
  63 {
  64         if (p) {
  65                 del_panel(p);
  66                 p = NULL;
  67         }
  68 }
  69 
  70 static void close_window(WINDOW *win)
  71 {
  72         if (win) {
  73                 delwin(win);
  74                 win = NULL;
  75         }
  76 }
  77 
  78 void close_windows(void)
  79 {
  80         if (tui_disabled)
  81                 return;
  82         /* must delete panels before their attached windows */
  83         if (dialogue_window)
  84                 close_panel(dialogue_panel);
  85         if (cooling_device_window)
  86                 close_panel(data_panel);
  87 
  88         close_window(title_bar_window);
  89         close_window(tz_sensor_window);
  90         close_window(status_bar_window);
  91         close_window(cooling_device_window);
  92         close_window(control_window);
  93         close_window(thermal_data_window);
  94         close_window(dialogue_window);
  95 
  96 }
  97 
  98 void write_status_bar(int x, char *line)
  99 {
 100         mvwprintw(status_bar_window, 0, x, "%s", line);
 101         wrefresh(status_bar_window);
 102 }
 103 
 104 /* wrap at 5 */
 105 #define DIAG_DEV_ROWS  5
 106 /*
 107  * list cooling devices + "set temp" entry; wraps after 5 rows, if they fit
 108  */
 109 static int diag_dev_rows(void)
 110 {
 111         int entries = ptdata.nr_cooling_dev + 1;
 112         int rows = max(DIAG_DEV_ROWS, (entries + 1) / 2);
 113         return min(rows, entries);
 114 }
 115 
 116 void setup_windows(void)
 117 {
 118         int y_begin = 1;
 119 
 120         if (tui_disabled)
 121                 return;
 122 
 123         getmaxyx(stdscr, maxy, maxx);
 124         resizeterm(maxy, maxx);
 125 
 126         title_bar_window = subwin(stdscr, TITLE_BAR_HIGHT, maxx, 0, 0);
 127         y_begin += TITLE_BAR_HIGHT;
 128 
 129         tz_sensor_window = subwin(stdscr, SENSOR_WIN_HIGHT, maxx, y_begin, 0);
 130         y_begin += SENSOR_WIN_HIGHT;
 131 
 132         cooling_device_window = subwin(stdscr, ptdata.nr_cooling_dev + 3, maxx,
 133                                 y_begin, 0);
 134         y_begin += ptdata.nr_cooling_dev + 3; /* 2 lines for border */
 135         /* two lines to show borders, one line per tz show trip point position
 136          * and value.
 137          * dialogue window is a pop-up, when needed it lays on top of cdev win
 138          */
 139 
 140         dialogue_window = subwin(stdscr, diag_dev_rows() + 5, maxx-50,
 141                                 DIAG_Y, DIAG_X);
 142 
 143         thermal_data_window = subwin(stdscr, ptdata.nr_tz_sensor *
 144                                 NR_LINES_TZDATA + 3, maxx, y_begin, 0);
 145         y_begin += ptdata.nr_tz_sensor * NR_LINES_TZDATA + 3;
 146         control_window = subwin(stdscr, 4, maxx, y_begin, 0);
 147 
 148         scrollok(cooling_device_window, TRUE);
 149         maxwidth = maxx - 18;
 150         status_bar_window = subwin(stdscr, 1, maxx, maxy-1, 0);
 151 
 152         strcpy(status_bar_slots[0], " Ctrl-c - Quit ");
 153         strcpy(status_bar_slots[1], " TAB - Tuning ");
 154         wmove(status_bar_window, 1, 30);
 155 
 156         /* prepare panels for dialogue, if panel already created then we must
 157          * be doing resizing, so just replace windows with new ones, old ones
 158          * should have been deleted by close_window
 159          */
 160         data_panel = new_panel(cooling_device_window);
 161         if (!data_panel)
 162                 syslog(LOG_DEBUG, "No data panel\n");
 163         else {
 164                 if (dialogue_window) {
 165                         dialogue_panel = new_panel(dialogue_window);
 166                         if (!dialogue_panel)
 167                                 syslog(LOG_DEBUG, "No dialogue panel\n");
 168                         else {
 169                                 /* Set up the user pointer to the next panel*/
 170                                 set_panel_userptr(data_panel, dialogue_panel);
 171                                 set_panel_userptr(dialogue_panel, data_panel);
 172                                 top = data_panel;
 173                         }
 174                 } else
 175                         syslog(LOG_INFO, "no dialogue win, term too small\n");
 176         }
 177         doupdate();
 178         werase(stdscr);
 179         refresh();
 180 }
 181 
 182 void resize_handler(int sig)
 183 {
 184         /* start over when term gets resized, but first we clean up */
 185         close_windows();
 186         endwin();
 187         refresh();
 188         clear();
 189         getmaxyx(stdscr, maxy, maxx);  /* get the new screen size */
 190         setup_windows();
 191         /* rate limit */
 192         sleep(1);
 193         syslog(LOG_DEBUG, "SIG %d, term resized to %d x %d\n",
 194                 sig, maxy, maxx);
 195         signal(SIGWINCH, resize_handler);
 196 }
 197 
 198 const char cdev_title[] = " COOLING DEVICES ";
 199 void show_cooling_device(void)
 200 {
 201         int i, j, x, y = 0;
 202 
 203         if (tui_disabled || !cooling_device_window)
 204                 return;
 205 
 206         werase(cooling_device_window);
 207         wattron(cooling_device_window, A_BOLD);
 208         mvwprintw(cooling_device_window,  1, 1,
 209                 "ID  Cooling Dev   Cur    Max   Thermal Zone Binding");
 210         wattroff(cooling_device_window, A_BOLD);
 211         for (j = 0; j < ptdata.nr_cooling_dev; j++) {
 212                 /* draw cooling device list on the left in the order of
 213                  * cooling device instances. skip unused idr.
 214                  */
 215                 mvwprintw(cooling_device_window, j + 2, 1,
 216                         "%02d %12.12s%6d %6d",
 217                         ptdata.cdi[j].instance,
 218                         ptdata.cdi[j].type,
 219                         ptdata.cdi[j].cur_state,
 220                         ptdata.cdi[j].max_state);
 221         }
 222 
 223         /* show cdev binding, y is the global cooling device instance */
 224         for (i = 0; i < ptdata.nr_tz_sensor; i++) {
 225                 int tz_inst = ptdata.tzi[i].instance;
 226                 for (j = 0; j < ptdata.nr_cooling_dev; j++) {
 227                         int cdev_inst;
 228                         y = j;
 229                         x = tz_inst * TZONE_RECORD_SIZE + TZ_LEFT_ALIGN;
 230 
 231                         draw_hbar(cooling_device_window, y+2, x,
 232                                 TZONE_RECORD_SIZE-1, ACS_VLINE, false);
 233 
 234                         /* draw a column of spaces to separate thermal zones */
 235                         mvwprintw(cooling_device_window, y+2, x-1, " ");
 236                         if (ptdata.tzi[i].cdev_binding) {
 237                                 cdev_inst = ptdata.cdi[j].instance;
 238                                 unsigned long trip_binding =
 239                                         ptdata.tzi[i].trip_binding[cdev_inst];
 240                                 int k = 0; /* per zone trip point id that
 241                                             * binded to this cdev, one to
 242                                             * many possible based on the
 243                                             * binding bitmask.
 244                                             */
 245                                 syslog(LOG_DEBUG,
 246                                         "bind tz%d cdev%d tp%lx %d cdev%lx\n",
 247                                         i, j, trip_binding, y,
 248                                         ptdata.tzi[i].cdev_binding);
 249                                 /* draw each trip binding for the cdev */
 250                                 while (trip_binding >>= 1) {
 251                                         k++;
 252                                         if (!(trip_binding & 1))
 253                                                 continue;
 254                                         /* draw '*' to show binding */
 255                                         mvwprintw(cooling_device_window,
 256                                                 y + 2,
 257                                                 x + ptdata.tzi[i].nr_trip_pts -
 258                                                 k - 1, "*");
 259                                 }
 260                         }
 261                 }
 262         }
 263         /* draw border after data so that border will not be messed up
 264          * even there is not enough space for all the data to be shown
 265          */
 266         wborder(cooling_device_window, 0, 0, 0, 0, 0, 0, 0, 0);
 267         wattron(cooling_device_window, A_BOLD);
 268         mvwprintw(cooling_device_window, 0, maxx/2 - sizeof(cdev_title),
 269                 cdev_title);
 270         wattroff(cooling_device_window, A_BOLD);
 271 
 272         wrefresh(cooling_device_window);
 273 }
 274 
 275 const char DIAG_TITLE[] = "[ TUNABLES ]";
 276 void show_dialogue(void)
 277 {
 278         int j, x = 0, y = 0;
 279         int rows, cols;
 280         WINDOW *w = dialogue_window;
 281 
 282         if (tui_disabled || !w)
 283                 return;
 284 
 285         getmaxyx(w, rows, cols);
 286 
 287         /* Silence compiler 'unused' warnings */
 288         (void)cols;
 289 
 290         werase(w);
 291         box(w, 0, 0);
 292         mvwprintw(w, 0, maxx/4, DIAG_TITLE);
 293         /* list all the available tunables */
 294         for (j = 0; j <= ptdata.nr_cooling_dev; j++) {
 295                 y = j % diag_dev_rows();
 296                 if (y == 0 && j != 0)
 297                         x += 20;
 298                 if (j == ptdata.nr_cooling_dev)
 299                         /* save last choice for target temp */
 300                         mvwprintw(w, y+1, x+1, "%C-%.12s", 'A'+j, "Set Temp");
 301                 else
 302                         mvwprintw(w, y+1, x+1, "%C-%.10s-%2d", 'A'+j,
 303                                 ptdata.cdi[j].type, ptdata.cdi[j].instance);
 304         }
 305         wattron(w, A_BOLD);
 306         mvwprintw(w, diag_dev_rows()+1, 1, "Enter Choice [A-Z]?");
 307         wattroff(w, A_BOLD);
 308         /* print legend at the bottom line */
 309         mvwprintw(w, rows - 2, 1,
 310                 "Legend: A=Active, P=Passive, C=Critical");
 311 
 312         wrefresh(dialogue_window);
 313 }
 314 
 315 void write_dialogue_win(char *buf, int y, int x)
 316 {
 317         WINDOW *w = dialogue_window;
 318 
 319         mvwprintw(w, y, x, "%s", buf);
 320 }
 321 
 322 const char control_title[] = " CONTROLS ";
 323 void show_control_w(void)
 324 {
 325         unsigned long state;
 326 
 327         get_ctrl_state(&state);
 328 
 329         if (tui_disabled || !control_window)
 330                 return;
 331 
 332         werase(control_window);
 333         mvwprintw(control_window, 1, 1,
 334                 "PID gain: kp=%2.2f ki=%2.2f kd=%2.2f Output %2.2f",
 335                 p_param.kp, p_param.ki, p_param.kd, p_param.y_k);
 336 
 337         mvwprintw(control_window, 2, 1,
 338                 "Target Temp: %2.1fC, Zone: %d, Control Device: %.12s",
 339                 p_param.t_target, target_thermal_zone, ctrl_cdev);
 340 
 341         /* draw border last such that everything is within boundary */
 342         wborder(control_window, 0, 0, 0, 0, 0, 0, 0, 0);
 343         wattron(control_window, A_BOLD);
 344         mvwprintw(control_window, 0, maxx/2 - sizeof(control_title),
 345                 control_title);
 346         wattroff(control_window, A_BOLD);
 347 
 348         wrefresh(control_window);
 349 }
 350 
 351 void initialize_curses(void)
 352 {
 353         if (tui_disabled)
 354                 return;
 355 
 356         initscr();
 357         start_color();
 358         keypad(stdscr, TRUE);   /* enable keyboard mapping */
 359         nonl();                 /* tell curses not to do NL->CR/NL on output */
 360         cbreak();               /* take input chars one at a time */
 361         noecho();               /* dont echo input */
 362         curs_set(0);            /* turn off cursor */
 363         use_default_colors();
 364 
 365         init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK);
 366         init_pair(PT_COLOR_HEADER_BAR, COLOR_BLACK, COLOR_WHITE);
 367         init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED);
 368         init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED);
 369         init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW);
 370         init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN);
 371         init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE);
 372         init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK);
 373 
 374 }
 375 
 376 void show_title_bar(void)
 377 {
 378         int i;
 379         int x = 0;
 380 
 381         if (tui_disabled || !title_bar_window)
 382                 return;
 383 
 384         wattrset(title_bar_window, COLOR_PAIR(PT_COLOR_HEADER_BAR));
 385         wbkgd(title_bar_window, COLOR_PAIR(PT_COLOR_HEADER_BAR));
 386         werase(title_bar_window);
 387 
 388         mvwprintw(title_bar_window, 0, 0,
 389                 "     TMON v%s", VERSION);
 390 
 391         wrefresh(title_bar_window);
 392 
 393         werase(status_bar_window);
 394 
 395         for (i = 0; i < 10; i++) {
 396                 if (strlen(status_bar_slots[i]) == 0)
 397                         continue;
 398                 wattron(status_bar_window, A_REVERSE);
 399                 mvwprintw(status_bar_window, 0, x, "%s", status_bar_slots[i]);
 400                 wattroff(status_bar_window, A_REVERSE);
 401                 x += strlen(status_bar_slots[i]) + 1;
 402         }
 403         wrefresh(status_bar_window);
 404 }
 405 
 406 static void handle_input_val(int ch)
 407 {
 408         char buf[32];
 409         int val;
 410         char path[256];
 411         WINDOW *w = dialogue_window;
 412 
 413         echo();
 414         keypad(w, TRUE);
 415         wgetnstr(w, buf, 31);
 416         val = atoi(buf);
 417 
 418         if (ch == ptdata.nr_cooling_dev) {
 419                 snprintf(buf, 31, "Invalid Temp %d! %d-%d", val,
 420                         MIN_CTRL_TEMP, MAX_CTRL_TEMP);
 421                 if (val < MIN_CTRL_TEMP || val > MAX_CTRL_TEMP)
 422                         write_status_bar(40, buf);
 423                 else {
 424                         p_param.t_target = val;
 425                         snprintf(buf, 31, "Set New Target Temp %d", val);
 426                         write_status_bar(40, buf);
 427                 }
 428         } else {
 429                 snprintf(path, 256, "%s/%s%d", THERMAL_SYSFS,
 430                         CDEV, ptdata.cdi[ch].instance);
 431                 sysfs_set_ulong(path, "cur_state", val);
 432         }
 433         noecho();
 434         dialogue_on = 0;
 435         show_data_w();
 436         show_control_w();
 437 
 438         top = (PANEL *)panel_userptr(top);
 439         top_panel(top);
 440 }
 441 
 442 static void handle_input_choice(int ch)
 443 {
 444         char buf[48];
 445         int base = 0;
 446         int cdev_id = 0;
 447 
 448         if ((ch >= 'A' && ch <= 'A' + ptdata.nr_cooling_dev) ||
 449                 (ch >= 'a' && ch <= 'a' + ptdata.nr_cooling_dev)) {
 450                 base = (ch < 'a') ? 'A' : 'a';
 451                 cdev_id = ch - base;
 452                 if (ptdata.nr_cooling_dev == cdev_id)
 453                         snprintf(buf, sizeof(buf), "New Target Temp:");
 454                 else
 455                         snprintf(buf, sizeof(buf), "New Value for %.10s-%2d: ",
 456                                 ptdata.cdi[cdev_id].type,
 457                                 ptdata.cdi[cdev_id].instance);
 458                 write_dialogue_win(buf, diag_dev_rows() + 2, 2);
 459                 handle_input_val(cdev_id);
 460         } else {
 461                 snprintf(buf, sizeof(buf), "Invalid selection %d", ch);
 462                 write_dialogue_win(buf, 8, 2);
 463         }
 464 }
 465 
 466 void *handle_tui_events(void *arg)
 467 {
 468         int ch;
 469 
 470         keypad(cooling_device_window, TRUE);
 471         while ((ch = wgetch(cooling_device_window)) != EOF) {
 472                 if (tmon_exit)
 473                         break;
 474                 /* when term size is too small, no dialogue panels are set.
 475                  * we need to filter out such cases.
 476                  */
 477                 if (!data_panel || !dialogue_panel ||
 478                         !cooling_device_window ||
 479                         !dialogue_window) {
 480 
 481                         continue;
 482                 }
 483                 pthread_mutex_lock(&input_lock);
 484                 if (dialogue_on) {
 485                         handle_input_choice(ch);
 486                         /* top panel filter */
 487                         if (ch == 'q' || ch == 'Q')
 488                                 ch = 0;
 489                 }
 490                 switch (ch) {
 491                 case KEY_LEFT:
 492                         box(cooling_device_window, 10, 0);
 493                         break;
 494                 case 9: /* TAB */
 495                         top = (PANEL *)panel_userptr(top);
 496                         top_panel(top);
 497                         if (top == dialogue_panel) {
 498                                 dialogue_on = 1;
 499                                 show_dialogue();
 500                         } else {
 501                                 dialogue_on = 0;
 502                                 /* force refresh */
 503                                 show_data_w();
 504                                 show_control_w();
 505                         }
 506                         break;
 507                 case 'q':
 508                 case 'Q':
 509                         tmon_exit = 1;
 510                         break;
 511                 }
 512                 update_panels();
 513                 doupdate();
 514                 pthread_mutex_unlock(&input_lock);
 515         }
 516 
 517         if (arg)
 518                 *(int *)arg = 0; /* make gcc happy */
 519 
 520         return NULL;
 521 }
 522 
 523 /* draw a horizontal bar in given pattern */
 524 static void draw_hbar(WINDOW *win, int y, int start, int len, unsigned long ptn,
 525                 bool end)
 526 {
 527         mvwaddch(win, y, start, ptn);
 528         whline(win, ptn, len);
 529         if (end)
 530                 mvwaddch(win, y, MAX_DISP_TEMP+TDATA_LEFT, ']');
 531 }
 532 
 533 static char trip_type_to_char(int type)
 534 {
 535         switch (type) {
 536         case THERMAL_TRIP_CRITICAL: return 'C';
 537         case THERMAL_TRIP_HOT: return 'H';
 538         case THERMAL_TRIP_PASSIVE: return 'P';
 539         case THERMAL_TRIP_ACTIVE: return 'A';
 540         default:
 541                 return '?';
 542         }
 543 }
 544 
 545 /* fill a string with trip point type and value in one line
 546  * e.g.      P(56)    C(106)
 547  * maintain the distance one degree per char
 548  */
 549 static void draw_tp_line(int tz, int y)
 550 {
 551         int j;
 552         int x;
 553 
 554         for (j = 0; j < ptdata.tzi[tz].nr_trip_pts; j++) {
 555                 x = ptdata.tzi[tz].tp[j].temp / 1000;
 556                 mvwprintw(thermal_data_window, y + 0, x + TDATA_LEFT,
 557                         "%c%d", trip_type_to_char(ptdata.tzi[tz].tp[j].type),
 558                         x);
 559                 syslog(LOG_INFO, "%s:tz %d tp %d temp = %lu\n", __func__,
 560                         tz, j, ptdata.tzi[tz].tp[j].temp);
 561         }
 562 }
 563 
 564 const char data_win_title[] = " THERMAL DATA ";
 565 void show_data_w(void)
 566 {
 567         int i;
 568 
 569 
 570         if (tui_disabled || !thermal_data_window)
 571                 return;
 572 
 573         werase(thermal_data_window);
 574         wattron(thermal_data_window, A_BOLD);
 575         mvwprintw(thermal_data_window, 0, maxx/2 - sizeof(data_win_title),
 576                 data_win_title);
 577         wattroff(thermal_data_window, A_BOLD);
 578         /* draw a line as ruler */
 579         for (i = 10; i < MAX_DISP_TEMP; i += 10)
 580                 mvwprintw(thermal_data_window, 1, i+TDATA_LEFT, "%2d", i);
 581 
 582         for (i = 0; i < ptdata.nr_tz_sensor; i++) {
 583                 int temp = trec[cur_thermal_record].temp[i] / 1000;
 584                 int y = 0;
 585 
 586                 y = i * NR_LINES_TZDATA + 2;
 587                 /* y at tz temp data line */
 588                 mvwprintw(thermal_data_window, y, 1, "%6.6s%2d:[%3d][",
 589                         ptdata.tzi[i].type,
 590                         ptdata.tzi[i].instance, temp);
 591                 draw_hbar(thermal_data_window, y, TDATA_LEFT, temp, ACS_RARROW,
 592                         true);
 593                 draw_tp_line(i, y);
 594         }
 595         wborder(thermal_data_window, 0, 0, 0, 0, 0, 0, 0, 0);
 596         wrefresh(thermal_data_window);
 597 }
 598 
 599 const char tz_title[] = "THERMAL ZONES(SENSORS)";
 600 
 601 void show_sensors_w(void)
 602 {
 603         int i, j;
 604         char buffer[512];
 605 
 606         if (tui_disabled || !tz_sensor_window)
 607                 return;
 608 
 609         werase(tz_sensor_window);
 610 
 611         memset(buffer, 0, sizeof(buffer));
 612         wattron(tz_sensor_window, A_BOLD);
 613         mvwprintw(tz_sensor_window, 1, 1, "Thermal Zones:");
 614         wattroff(tz_sensor_window, A_BOLD);
 615 
 616         mvwprintw(tz_sensor_window, 1, TZ_LEFT_ALIGN, "%s", buffer);
 617         /* fill trip points for each tzone */
 618         wattron(tz_sensor_window, A_BOLD);
 619         mvwprintw(tz_sensor_window, 2, 1, "Trip Points:");
 620         wattroff(tz_sensor_window, A_BOLD);
 621 
 622         /* draw trip point from low to high for each tz */
 623         for (i = 0; i < ptdata.nr_tz_sensor; i++) {
 624                 int inst = ptdata.tzi[i].instance;
 625 
 626                 mvwprintw(tz_sensor_window, 1,
 627                         TZ_LEFT_ALIGN+TZONE_RECORD_SIZE * inst, "%.9s%02d",
 628                         ptdata.tzi[i].type, ptdata.tzi[i].instance);
 629                 for (j = ptdata.tzi[i].nr_trip_pts - 1; j >= 0; j--) {
 630                         /* loop through all trip points */
 631                         char type;
 632                         int tp_pos;
 633                         /* reverse the order here since trips are sorted
 634                          * in ascending order in terms of temperature.
 635                          */
 636                         tp_pos = ptdata.tzi[i].nr_trip_pts - j - 1;
 637 
 638                         type = trip_type_to_char(ptdata.tzi[i].tp[j].type);
 639                         mvwaddch(tz_sensor_window, 2,
 640                                 inst * TZONE_RECORD_SIZE + TZ_LEFT_ALIGN +
 641                                 tp_pos, type);
 642                         syslog(LOG_DEBUG, "draw tz %d tp %d ch:%c\n",
 643                                 inst, j, type);
 644                 }
 645         }
 646         wborder(tz_sensor_window, 0, 0, 0, 0, 0, 0, 0, 0);
 647         wattron(tz_sensor_window, A_BOLD);
 648         mvwprintw(tz_sensor_window, 0, maxx/2 - sizeof(tz_title), tz_title);
 649         wattroff(tz_sensor_window, A_BOLD);
 650         wrefresh(tz_sensor_window);
 651 }
 652 
 653 void disable_tui(void)
 654 {
 655         tui_disabled = 1;
 656 }

/* [<][>][^][v][top][bottom][index][help] */