Header.c 5.87 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
9
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "Header.h"

Hisham Muhammad's avatar
Hisham Muhammad committed
10
11
12
13
14
15
16
17
18
19
20
21
#include "CRT.h"
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "String.h"

Hisham Muhammad's avatar
Hisham Muhammad committed
22
#include <assert.h>
23
#include <time.h>
Hisham Muhammad's avatar
Hisham Muhammad committed
24
25
#include <string.h>
#include <stdlib.h>
Hisham Muhammad's avatar
Hisham Muhammad committed
26
27

/*{
Hisham Muhammad's avatar
Hisham Muhammad committed
28
29
#include "ProcessList.h"
#include "Meter.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
30
31
32
33
34
35
36

typedef enum HeaderSide_ {
   LEFT_HEADER,
   RIGHT_HEADER
} HeaderSide;

typedef struct Header_ {
37
38
   Vector* leftMeters;
   Vector* rightMeters;
Hisham Muhammad's avatar
Hisham Muhammad committed
39
40
41
42
43
44
45
46
47
48
49
50
51
   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) {
52
   Header* this = calloc(sizeof(Header), 1);
53
54
   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
55
56
57
58
59
60
   this->margin = true;
   this->pl = pl;
   return this;
}

void Header_delete(Header* this) {
61
62
   Vector_delete(this->leftMeters);
   Vector_delete(this->rightMeters);
Hisham Muhammad's avatar
Hisham Muhammad committed
63
64
65
66
   free(this);
}

void Header_createMeter(Header* this, char* name, HeaderSide side) {
67
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
68
69
70
                       ? this->leftMeters
                       : this->rightMeters;

71
72
73
74
75
76
77
78
79
   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)) {
80
         Vector_add(meters, Meter_new(this->pl, param, *type));
81
82
         break;
      }
Hisham Muhammad's avatar
Hisham Muhammad committed
83
84
85
   }
}

86
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
87
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
88
89
90
                       ? this->leftMeters
                       : this->rightMeters;

91
92
   if (i >= Vector_size(meters))
      return;
93
   Meter* meter = (Meter*) Vector_get(meters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
94
95
96
   Meter_setMode(meter, mode);
}

97
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) {
98
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
99
100
101
                       ? this->leftMeters
                       : this->rightMeters;

102
   Meter* meter = Meter_new(this->pl, param, type);
103
   Vector_add(meters, meter);
104
   return meter;
Hisham Muhammad's avatar
Hisham Muhammad committed
105
106
107
}

int Header_size(Header* this, HeaderSide side) {
108
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
109
110
111
                       ? this->leftMeters
                       : this->rightMeters;

112
   return Vector_size(meters);
Hisham Muhammad's avatar
Hisham Muhammad committed
113
114
115
}

char* Header_readMeterName(Header* this, int i, HeaderSide side) {
116
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
117
118
                       ? this->leftMeters
                       : this->rightMeters;
119
   Meter* meter = (Meter*) Vector_get(meters, i);
120
121
122
123
124
125
126
127
128
129

   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
130
131
}

132
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
133
   Vector* meters = side == LEFT_HEADER
Hisham Muhammad's avatar
Hisham Muhammad committed
134
135
136
                       ? this->leftMeters
                       : this->rightMeters;

137
   Meter* meter = (Meter*) Vector_get(meters, i);
Hisham Muhammad's avatar
Hisham Muhammad committed
138
139
140
   return meter->mode;
}

141
142
143
144
145
146
147
148
149
150
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));
   }
151
152
153
154
155
   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
156
157
}

158
159
160
void Header_reinit(Header* this) {
   for (int i = 0; i < Vector_size(this->leftMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
161
162
      if (meter->type->init)
         meter->type->init(meter);
163
164
165
   }
   for (int i = 0; i < Vector_size(this->rightMeters); i++) {
      Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
166
167
      if (meter->type->init)
         meter->type->init(meter);
168
169
170
171
   }
}

void Header_draw(const Header* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
172
173
174
175
176
177
178
   int height = this->height;
   int pad = this->pad;
   
   attrset(CRT_colors[RESET_COLOR]);
   for (int y = 0; y < height; y++) {
      mvhline(y, 0, ' ', COLS);
   }
179
180
   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
181
182
183
      meter->draw(meter, pad, y, COLS / 2 - (pad * 2 - 1) - 1);
      y += meter->h;
   }
184
185
   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
186
187
188
189
190
191
192
193
194
195
      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;

196
197
   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
198
199
      leftHeight += meter->h;
   }
200
201
   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
202
203
204
205
206
207
      rightHeight += meter->h;
   }
   this->pad = pad;
   this->height = MAX(leftHeight, rightHeight);
   return this->height;
}