Header.c 5.57 KB
Newer Older
Hisham Muhammad's avatar
Hisham Muhammad committed
1
2
/*
htop - Header.c
Hisham Muhammad's avatar
Hisham Muhammad committed
3
(C) 2004-2011 Hisham H. Muhammad
Hisham Muhammad's avatar
Hisham Muhammad committed
4
5
6
7
8
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "Header.h"
9
#include "Meter.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
10
11
12

#include "debug.h"
#include <assert.h>
13
#include <time.h>
Hisham Muhammad's avatar
Hisham Muhammad committed
14
15
16
17
18
19
20
21
22

/*{

typedef enum HeaderSide_ {
   LEFT_HEADER,
   RIGHT_HEADER
} HeaderSide;

typedef struct Header_ {
23
24
   Vector* leftMeters;
   Vector* rightMeters;
Hisham Muhammad's avatar
Hisham Muhammad committed
25
26
27
28
29
30
31
32
33
34
35
36
37
   ProcessList* pl;
   bool margin;
   int height;
   int pad;
} Header;

}*/

#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif

Header* Header_new(ProcessList* pl) {
38
   Header* this = calloc(sizeof(Header), 1);
39
40
   this->leftMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
   this->rightMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
Hisham Muhammad's avatar
Hisham Muhammad committed
41
42
43
44
45
46
   this->margin = true;
   this->pl = pl;
   return this;
}

void Header_delete(Header* this) {
47
48
   Vector_delete(this->leftMeters);
   Vector_delete(this->rightMeters);
Hisham Muhammad's avatar
Hisham Muhammad committed
49
50
51
52
   free(this);
}

void Header_createMeter(Header* this, char* name, HeaderSide side) {
53
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
54
55
56
                       ? this->leftMeters
                       : this->rightMeters;

57
58
59
60
61
62
63
64
65
   char* paren = strchr(name, '(');
   int param = 0;
   if (paren) {
      int ok = sscanf(paren, "(%d)", &param);
      if (!ok) param = 0;
      *paren = '\0';
   }
   for (MeterType** type = Meter_types; *type; type++) {
      if (String_eq(name, (*type)->name)) {
66
         Vector_add(meters, Meter_new(this->pl, param, *type));
67
68
         break;
      }
Hisham Muhammad's avatar
Hisham Muhammad committed
69
70
71
   }
}

72
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
73
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
74
75
76
                       ? this->leftMeters
                       : this->rightMeters;

77
78
   if (i >= Vector_size(meters))
      return;
79
   Meter* meter = (Meter*) Vector_get(meters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
80
81
82
   Meter_setMode(meter, mode);
}

83
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) {
84
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
85
86
87
                       ? this->leftMeters
                       : this->rightMeters;

88
   Meter* meter = Meter_new(this->pl, param, type);
89
   Vector_add(meters, meter);
90
   return meter;
Hisham Muhammad's avatar
Hisham Muhammad committed
91
92
93
}

int Header_size(Header* this, HeaderSide side) {
94
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
95
96
97
                       ? this->leftMeters
                       : this->rightMeters;

98
   return Vector_size(meters);
Hisham Muhammad's avatar
Hisham Muhammad committed
99
100
101
}

char* Header_readMeterName(Header* this, int i, HeaderSide side) {
102
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
103
104
                       ? this->leftMeters
                       : this->rightMeters;
105
   Meter* meter = (Meter*) Vector_get(meters, i);
106
107
108
109
110
111
112
113
114
115

   int nameLen = strlen(meter->type->name);
   int len = nameLen + 100;
   char* name = malloc(len);
   strncpy(name, meter->type->name, nameLen);
   name[nameLen] = '\0';
   if (meter->param)
      snprintf(name + nameLen, len - nameLen, "(%d)", meter->param);

   return name;
Hisham Muhammad's avatar
Hisham Muhammad committed
116
117
}

118
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
119
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
120
121
122
                       ? this->leftMeters
                       : this->rightMeters;

123
   Meter* meter = (Meter*) Vector_get(meters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
124
125
126
   return meter->mode;
}

127
128
129
130
131
132
133
134
135
136
void Header_defaultMeters(Header* this, int cpuCount) {
   if (cpuCount > 8) {
      Vector_add(this->leftMeters, Meter_new(this->pl, 0, &LeftCPUs2Meter));
      Vector_add(this->rightMeters, Meter_new(this->pl, 0, &RightCPUs2Meter));
   } else if (cpuCount > 4) {
      Vector_add(this->leftMeters, Meter_new(this->pl, 0, &LeftCPUsMeter));
      Vector_add(this->rightMeters, Meter_new(this->pl, 0, &RightCPUsMeter));
   } else {
      Vector_add(this->leftMeters, Meter_new(this->pl, 0, &AllCPUsMeter));
   }
137
138
139
140
141
   Vector_add(this->leftMeters, Meter_new(this->pl, 0, &MemoryMeter));
   Vector_add(this->leftMeters, Meter_new(this->pl, 0, &SwapMeter));
   Vector_add(this->rightMeters, Meter_new(this->pl, 0, &TasksMeter));
   Vector_add(this->rightMeters, Meter_new(this->pl, 0, &LoadAverageMeter));
   Vector_add(this->rightMeters, Meter_new(this->pl, 0, &UptimeMeter));
Hisham Muhammad's avatar
Hisham Muhammad committed
142
143
}

144
145
146
void Header_reinit(Header* this) {
   for (int i = 0; i < Vector_size(this->leftMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
147
148
      if (meter->type->init)
         meter->type->init(meter);
149
150
151
   }
   for (int i = 0; i < Vector_size(this->rightMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
152
153
      if (meter->type->init)
         meter->type->init(meter);
154
155
156
157
   }
}

void Header_draw(const Header* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
158
159
160
161
162
163
164
   int height = this->height;
   int pad = this->pad;
   
   attrset(CRT_colors[RESET_COLOR]);
   for (int y = 0; y < height; y++) {
      mvhline(y, 0, ' ', COLS);
   }
165
166
   for (int y = (pad / 2), i = 0; i < Vector_size(this->leftMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
167
168
169
      meter->draw(meter, pad, y, COLS / 2 - (pad * 2 - 1) - 1);
      y += meter->h;
   }
170
171
   for (int y = (pad / 2), i = 0; i < Vector_size(this->rightMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
172
173
174
175
176
177
178
179
180
181
      meter->draw(meter, COLS / 2 + pad, y, COLS / 2 - (pad * 2 - 1) - 1);
      y += meter->h;
   }
}

int Header_calculateHeight(Header* this) {
   int pad = this->margin ? 2 : 0;
   int leftHeight = pad;
   int rightHeight = pad;

182
183
   for (int i = 0; i < Vector_size(this->leftMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
184
185
      leftHeight += meter->h;
   }
186
187
   for (int i = 0; i < Vector_size(this->rightMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
188
189
190
191
192
193
      rightHeight += meter->h;
   }
   this->pad = pad;
   this->height = MAX(leftHeight, rightHeight);
   return this->height;
}