DynamicMeter.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. htop - DynamicMeter.c
  3. (C) 2021 htop dev team
  4. (C) 2021 Red Hat, Inc. All Rights Reserved.
  5. Released under the GNU GPLv2+, see the COPYING file
  6. in the source distribution for its full text.
  7. */
  8. #include "config.h" // IWYU pragma: keep
  9. #include "DynamicMeter.h"
  10. #include <assert.h>
  11. #include <stdbool.h>
  12. #include <stddef.h>
  13. #include <string.h>
  14. #include "CRT.h"
  15. #include "Machine.h"
  16. #include "Object.h"
  17. #include "Platform.h"
  18. #include "RichString.h"
  19. #include "Settings.h"
  20. #include "XUtils.h"
  21. static const int DynamicMeter_attributes[] = {
  22. DYNAMIC_GRAY,
  23. DYNAMIC_DARKGRAY,
  24. DYNAMIC_RED,
  25. DYNAMIC_GREEN,
  26. DYNAMIC_BLUE,
  27. DYNAMIC_CYAN,
  28. DYNAMIC_MAGENTA,
  29. DYNAMIC_YELLOW,
  30. DYNAMIC_WHITE
  31. };
  32. Hashtable* DynamicMeters_new(void) {
  33. return Platform_dynamicMeters();
  34. }
  35. void DynamicMeters_delete(Hashtable* dynamics) {
  36. if (dynamics) {
  37. Platform_dynamicMetersDone(dynamics);
  38. Hashtable_delete(dynamics);
  39. }
  40. }
  41. typedef struct {
  42. unsigned int key;
  43. const char* name;
  44. bool found;
  45. } DynamicIterator;
  46. static void DynamicMeter_compare(ht_key_t key, void* value, void* data) {
  47. const DynamicMeter* meter = (const DynamicMeter*)value;
  48. DynamicIterator* iter = (DynamicIterator*)data;
  49. if (String_eq(iter->name, meter->name)) {
  50. iter->found = true;
  51. iter->key = key;
  52. }
  53. }
  54. bool DynamicMeter_search(Hashtable* dynamics, const char* name, unsigned int* key) {
  55. DynamicIterator iter = { .key = 0, .name = name, .found = false };
  56. if (dynamics)
  57. Hashtable_foreach(dynamics, DynamicMeter_compare, &iter);
  58. if (key)
  59. *key = iter.key;
  60. return iter.found;
  61. }
  62. const char* DynamicMeter_lookup(Hashtable* dynamics, unsigned int key) {
  63. const DynamicMeter* meter = Hashtable_get(dynamics, key);
  64. return meter ? meter->name : NULL;
  65. }
  66. static void DynamicMeter_init(Meter* meter) {
  67. Platform_dynamicMeterInit(meter);
  68. }
  69. static void DynamicMeter_updateValues(Meter* meter) {
  70. Platform_dynamicMeterUpdateValues(meter);
  71. }
  72. static void DynamicMeter_display(const Object* cast, RichString* out) {
  73. const Meter* meter = (const Meter*)cast;
  74. Platform_dynamicMeterDisplay(meter, out);
  75. }
  76. static const char* DynamicMeter_getCaption(const Meter* this) {
  77. const Settings* settings = this->host->settings;
  78. const DynamicMeter* meter = Hashtable_get(settings->dynamicMeters, this->param);
  79. if (meter)
  80. return meter->caption ? meter->caption : meter->name;
  81. return this->caption;
  82. }
  83. static void DynamicMeter_getUiName(const Meter* this, char* name, size_t length) {
  84. assert(length > 0);
  85. const Settings* settings = this->host->settings;
  86. const DynamicMeter* meter = Hashtable_get(settings->dynamicMeters, this->param);
  87. if (meter) {
  88. const char* uiName = meter->caption;
  89. if (uiName) {
  90. size_t uiNameLen = strlen(uiName);
  91. if (uiNameLen > 2 && uiName[uiNameLen - 2] == ':')
  92. uiNameLen -= 2;
  93. String_safeStrncpy(name, uiName, MINIMUM(length, uiNameLen + 1));
  94. } else {
  95. String_safeStrncpy(name, meter->name, length);
  96. }
  97. }
  98. }
  99. const MeterClass DynamicMeter_class = {
  100. .super = {
  101. .extends = Class(Meter),
  102. .delete = Meter_delete,
  103. .display = DynamicMeter_display
  104. },
  105. .init = DynamicMeter_init,
  106. .updateValues = DynamicMeter_updateValues,
  107. .getCaption = DynamicMeter_getCaption,
  108. .getUiName = DynamicMeter_getUiName,
  109. .defaultMode = TEXT_METERMODE,
  110. .supportedModes = METERMODE_DEFAULT_SUPPORTED,
  111. .maxItems = 0,
  112. .total = 100.0,
  113. .attributes = DynamicMeter_attributes,
  114. .name = "Dynamic",
  115. .uiName = "Dynamic",
  116. .caption = "",
  117. };