summaryrefslogtreecommitdiffstats
path: root/MemorySwapMeter.c
blob: 82eddee2177a74e3f4c5fb7172cb8840a5b17b9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
htop - MemorySwapMeter.c
(C) 2021 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include "config.h" // IWYU pragma: keep

#include "MemorySwapMeter.h"

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>

#include "Macros.h"
#include "MemoryMeter.h"
#include "Object.h"
#include "SwapMeter.h"
#include "XUtils.h"


typedef struct MemorySwapMeterData_ {
   Meter* memoryMeter;
   Meter* swapMeter;
} MemorySwapMeterData;

static void MemorySwapMeter_updateValues(Meter* this) {
   MemorySwapMeterData* data = this->meterData;

   Meter_updateValues(data->memoryMeter);
   Meter_updateValues(data->swapMeter);
}

static void MemorySwapMeter_draw(Meter* this, int x, int y, int w) {
   MemorySwapMeterData* data = this->meterData;

   /* Use the same width for each sub meter to align with CPU meter */
   const int colwidth = w / 2;
   const int diff = w - colwidth * 2;

   assert(data->memoryMeter->draw);
   data->memoryMeter->draw(data->memoryMeter, x, y, colwidth);
   assert(data->swapMeter->draw);
   data->swapMeter->draw(data->swapMeter, x + colwidth + diff, y, colwidth);
}

static void MemorySwapMeter_init(Meter* this) {
   MemorySwapMeterData* data = this->meterData;

   if (!data) {
      data = this->meterData = xMalloc(sizeof(MemorySwapMeterData));
      data->memoryMeter = NULL;
      data->swapMeter = NULL;
   }

   if (!data->memoryMeter)
      data->memoryMeter = Meter_new(this->host, 0, (const MeterClass*) Class(MemoryMeter));
   if (!data->swapMeter)
      data->swapMeter = Meter_new(this->host, 0, (const MeterClass*) Class(SwapMeter));

   if (Meter_initFn(data->memoryMeter))
      Meter_init(data->memoryMeter);
   if (Meter_initFn(data->swapMeter))
      Meter_init(data->swapMeter);

   if (this->mode == 0)
      this->mode = BAR_METERMODE;

   this->h = MAXIMUM(Meter_modes[data->memoryMeter->mode]->h, Meter_modes[data->swapMeter->mode]->h);
}

static void MemorySwapMeter_updateMode(Meter* this, int mode) {
   MemorySwapMeterData* data = this->meterData;

   this->mode = mode;

   Meter_setMode(data->memoryMeter, mode);
   Meter_setMode(data->swapMeter, mode);

   this->h = MAXIMUM(Meter_modes[data->memoryMeter->mode]->h, Meter_modes[data->swapMeter->mode]->h);
}

static void MemorySwapMeter_done(Meter* this) {
   MemorySwapMeterData* data = this->meterData;

   Meter_delete((Object*)data->swapMeter);
   Meter_delete((Object*)data->memoryMeter);

   free(data);
}

const MeterClass MemorySwapMeter_class = {
   .super = {
      .extends = Class(Meter),
      .delete = Meter_delete,
   },
   .updateValues = MemorySwapMeter_updateValues,
   .defaultMode = CUSTOM_METERMODE,
   .isMultiColumn = true,
   .name = "MemorySwap",
   .uiName = "Memory & Swap",
   .description = "Combined memory and swap usage",
   .caption = "M&S",
   .draw = MemorySwapMeter_draw,
   .init = MemorySwapMeter_init,
   .updateMode = MemorySwapMeter_updateMode,
   .done = MemorySwapMeter_done
};