Settings.c 13.8 KB
Newer Older
Hisham Muhammad's avatar
Hisham Muhammad committed
1
2
/*
htop - Settings.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 "Settings.h"
9
#include "Platform.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
10

David Hunt's avatar
David Hunt committed
11
#include "StringUtils.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
12
#include "Vector.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
13
#include "CRT.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
14

Hisham Muhammad's avatar
Hisham Muhammad committed
15
16
17
18
19
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

Hisham Muhammad's avatar
Hisham Muhammad committed
20
21
22
#define DEFAULT_DELAY 15

/*{
Hisham Muhammad's avatar
Hisham Muhammad committed
23
#include "Process.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
24
#include <stdbool.h>
Hisham Muhammad's avatar
Hisham Muhammad committed
25

Hisham Muhammad's avatar
Hisham Muhammad committed
26
27
28
29
30
typedef struct {
   int len;
   char** names;
   int* modes;
} MeterColumnSettings;
31

Hisham Muhammad's avatar
Hisham Muhammad committed
32
typedef struct Settings_ {
Hisham Muhammad's avatar
Hisham Muhammad committed
33
34
35
36
37
38
   char* filename;
   
   MeterColumnSettings columns[2];

   ProcessField* fields;
   int flags;
Hisham Muhammad's avatar
Hisham Muhammad committed
39
40
   int colorScheme;
   int delay;
Hisham Muhammad's avatar
Hisham Muhammad committed
41

42
   int cpuCount;
Hisham Muhammad's avatar
Hisham Muhammad committed
43
44
45
46
47
48
   int direction;
   ProcessField sortKey;

   bool countCPUsFromZero;
   bool detailedCPUTime;
   bool treeView;
49
   bool showProgramPath;
Hisham Muhammad's avatar
Hisham Muhammad committed
50
51
52
53
54
55
56
57
58
59
60
61
   bool hideThreads;
   bool shadowOtherUsers;
   bool showThreadNames;
   bool hideKernelThreads;
   bool hideUserlandThreads;
   bool highlightBaseName;
   bool highlightMegabytes;
   bool highlightThreads;
   bool updateProcessNames;
   bool accountGuestInCPUMeter;
   bool headerMargin;

Hisham Muhammad's avatar
Hisham Muhammad committed
62
   bool changed;
Hisham Muhammad's avatar
Hisham Muhammad committed
63
64
} Settings;

Hisham Muhammad's avatar
Hisham Muhammad committed
65
66
67
68
#ifndef Settings_cpuId
#define Settings_cpuId(settings, cpu) ((settings)->countCPUsFromZero ? (cpu) : (cpu)+1)
#endif

Hisham Muhammad's avatar
Hisham Muhammad committed
69
70
71
}*/

void Settings_delete(Settings* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
72
73
74
75
76
77
   free(this->filename);
   free(this->fields);
   for (unsigned int i = 0; i < (sizeof(this->columns)/sizeof(MeterColumnSettings)); i++) {
      String_freeArray(this->columns[i].names);
      free(this->columns[i].modes);
   }
Hisham Muhammad's avatar
Hisham Muhammad committed
78
79
80
   free(this);
}

Hisham Muhammad's avatar
Hisham Muhammad committed
81
static void Settings_readMeters(Settings* this, char* line, int column) {
Hisham Muhammad's avatar
Hisham Muhammad committed
82
   char* trim = String_trim(line);
83
84
   int nIds;
   char** ids = String_split(trim, ' ', &nIds);
Hisham Muhammad's avatar
Hisham Muhammad committed
85
   free(trim);
Hisham Muhammad's avatar
Hisham Muhammad committed
86
   this->columns[column].names = ids;
Hisham Muhammad's avatar
Hisham Muhammad committed
87
88
}

Hisham Muhammad's avatar
Hisham Muhammad committed
89
static void Settings_readMeterModes(Settings* this, char* line, int column) {
Hisham Muhammad's avatar
Hisham Muhammad committed
90
   char* trim = String_trim(line);
91
92
   int nIds;
   char** ids = String_split(trim, ' ', &nIds);
Hisham Muhammad's avatar
Hisham Muhammad committed
93
   free(trim);
Hisham Muhammad's avatar
Hisham Muhammad committed
94
   int len = 0;
95
   for (int i = 0; ids[i]; i++) {
Hisham Muhammad's avatar
Hisham Muhammad committed
96
97
98
      len++;
   }
   this->columns[column].len = len;
Hisham's avatar
Hisham committed
99
   int* modes = xCalloc(len, sizeof(int));
Hisham Muhammad's avatar
Hisham Muhammad committed
100
101
   for (int i = 0; i < len; i++) {
      modes[i] = atoi(ids[i]);
Hisham Muhammad's avatar
Hisham Muhammad committed
102
103
   }
   String_freeArray(ids);
Hisham Muhammad's avatar
Hisham Muhammad committed
104
   this->columns[column].modes = modes;
Hisham Muhammad's avatar
Hisham Muhammad committed
105
106
}

107
static void Settings_defaultMeters(Settings* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
108
   int sizes[] = { 3, 3 };
109
   if (this->cpuCount > 4) {
Hisham Muhammad's avatar
Hisham Muhammad committed
110
111
112
      sizes[1]++;
   }
   for (int i = 0; i < 2; i++) {
Hisham's avatar
Hisham committed
113
114
      this->columns[i].names = xCalloc(sizes[i] + 1, sizeof(char*));
      this->columns[i].modes = xCalloc(sizes[i], sizeof(int));
115
      this->columns[i].len = sizes[i];
Hisham Muhammad's avatar
Hisham Muhammad committed
116
117
118
   }
   
   int r = 0;
119
   if (this->cpuCount > 8) {
Hisham's avatar
Hisham committed
120
      this->columns[0].names[0] = xStrdup("LeftCPUs2");
121
122
123
      this->columns[0].modes[0] = BAR_METERMODE;
      this->columns[1].names[r] = xStrdup("RightCPUs2");
      this->columns[1].modes[r++] = BAR_METERMODE;
124
   } else if (this->cpuCount > 4) {
Hisham's avatar
Hisham committed
125
      this->columns[0].names[0] = xStrdup("LeftCPUs");
126
127
128
      this->columns[0].modes[0] = BAR_METERMODE;
      this->columns[1].names[r] = xStrdup("RightCPUs");
      this->columns[1].modes[r++] = BAR_METERMODE;
129
   } else {
Hisham's avatar
Hisham committed
130
      this->columns[0].names[0] = xStrdup("AllCPUs");
131
      this->columns[0].modes[0] = BAR_METERMODE;
Hisham Muhammad's avatar
Hisham Muhammad committed
132
   }
Hisham's avatar
Hisham committed
133
   this->columns[0].names[1] = xStrdup("Memory");
134
   this->columns[0].modes[1] = BAR_METERMODE;
Hisham's avatar
Hisham committed
135
   this->columns[0].names[2] = xStrdup("Swap");
136
   this->columns[0].modes[2] = BAR_METERMODE;
Hisham Muhammad's avatar
Hisham Muhammad committed
137
   
138
139
140
141
142
143
   this->columns[1].names[r] = xStrdup("Tasks");
   this->columns[1].modes[r++] = TEXT_METERMODE;
   this->columns[1].names[r] = xStrdup("LoadAverage");
   this->columns[1].modes[r++] = TEXT_METERMODE;
   this->columns[1].names[r] = xStrdup("Uptime");
   this->columns[1].modes[r++] = TEXT_METERMODE;
Hisham Muhammad's avatar
Hisham Muhammad committed
144
145
146
147
148
149
150
151
152
}

static void readFields(ProcessField* fields, int* flags, const char* line) {
   char* trim = String_trim(line);
   int nIds;
   char** ids = String_split(trim, ' ', &nIds);
   free(trim);
   int i, j;
   *flags = 0;
153
   for (j = 0, i = 0; i < Platform_numberOfFields && ids[i]; i++) {
Hisham Muhammad's avatar
Hisham Muhammad committed
154
155
      // This "+1" is for compatibility with the older enum format.
      int id = atoi(ids[i]) + 1;
156
      if (id > 0 && Process_fields[id].name && id < Platform_numberOfFields) {
Hisham Muhammad's avatar
Hisham Muhammad committed
157
158
159
160
         fields[j] = id;
         *flags |= Process_fields[id].flags;
         j++;
      }
161
   }
Hisham's avatar
Hisham committed
162
   fields[j] = NULL_PROCESSFIELD;
Hisham Muhammad's avatar
Hisham Muhammad committed
163
   String_freeArray(ids);
164
165
}

166
static bool Settings_read(Settings* this, const char* fileName) {
167
168
169
   FILE* fd;
   uid_t euid = geteuid();

170
   (void) seteuid(getuid());
171
   fd = fopen(fileName, "r");
172
   (void) seteuid(euid);
173
   if (!fd)
Hisham Muhammad's avatar
Hisham Muhammad committed
174
      return false;
175
   
Hisham Muhammad's avatar
Hisham Muhammad committed
176
   bool readMeters = false;
177
178
179
180
181
   for (;;) {
      char* line = String_readLine(fd);
      if (!line) {
         break;
      }
182
      int nOptions;
183
184
      char** option = String_split(line, '=', &nOptions);
      free (line);
185
186
187
188
      if (nOptions < 2) {
         String_freeArray(option);
         continue;
      }
Hisham Muhammad's avatar
Hisham Muhammad committed
189
      if (String_eq(option[0], "fields")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
190
         readFields(this->fields, &(this->flags), option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
191
192
      } else if (String_eq(option[0], "sort_key")) {
         // This "+1" is for compatibility with the older enum format.
Hisham Muhammad's avatar
Hisham Muhammad committed
193
         this->sortKey = atoi(option[1]) + 1;
Hisham Muhammad's avatar
Hisham Muhammad committed
194
      } else if (String_eq(option[0], "sort_direction")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
195
         this->direction = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
196
      } else if (String_eq(option[0], "tree_view")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
197
         this->treeView = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
198
      } else if (String_eq(option[0], "hide_threads")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
199
         this->hideThreads = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
200
      } else if (String_eq(option[0], "hide_kernel_threads")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
201
         this->hideKernelThreads = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
202
      } else if (String_eq(option[0], "hide_userland_threads")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
203
         this->hideUserlandThreads = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
204
      } else if (String_eq(option[0], "shadow_other_users")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
205
         this->shadowOtherUsers = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
206
      } else if (String_eq(option[0], "show_thread_names")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
207
         this->showThreadNames = atoi(option[1]);
208
209
      } else if (String_eq(option[0], "show_program_path")) {
         this->showProgramPath = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
210
      } else if (String_eq(option[0], "highlight_base_name")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
211
         this->highlightBaseName = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
212
      } else if (String_eq(option[0], "highlight_megabytes")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
213
         this->highlightMegabytes = atoi(option[1]);
214
      } else if (String_eq(option[0], "highlight_threads")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
215
         this->highlightThreads = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
216
      } else if (String_eq(option[0], "header_margin")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
217
         this->headerMargin = atoi(option[1]);
218
      } else if (String_eq(option[0], "expand_system_time")) {
219
         // Compatibility option.
Hisham Muhammad's avatar
Hisham Muhammad committed
220
         this->detailedCPUTime = atoi(option[1]);
221
      } else if (String_eq(option[0], "detailed_cpu_time")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
222
         this->detailedCPUTime = atoi(option[1]);
223
      } else if (String_eq(option[0], "cpu_count_from_zero")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
224
         this->countCPUsFromZero = atoi(option[1]);
225
      } else if (String_eq(option[0], "update_process_names")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
226
         this->updateProcessNames = atoi(option[1]);
227
      } else if (String_eq(option[0], "account_guest_in_cpu_meter")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
228
         this->accountGuestInCPUMeter = atoi(option[1]);
Hisham Muhammad's avatar
Hisham Muhammad committed
229
230
231
232
      } else if (String_eq(option[0], "delay")) {
         this->delay = atoi(option[1]);
      } else if (String_eq(option[0], "color_scheme")) {
         this->colorScheme = atoi(option[1]);
233
         if (this->colorScheme < 0 || this->colorScheme >= LAST_COLORSCHEME) this->colorScheme = 0;
Hisham Muhammad's avatar
Hisham Muhammad committed
234
      } else if (String_eq(option[0], "left_meters")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
235
         Settings_readMeters(this, option[1], 0);
236
         readMeters = true;
Hisham Muhammad's avatar
Hisham Muhammad committed
237
      } else if (String_eq(option[0], "right_meters")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
238
         Settings_readMeters(this, option[1], 1);
239
         readMeters = true;
Hisham Muhammad's avatar
Hisham Muhammad committed
240
      } else if (String_eq(option[0], "left_meter_modes")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
241
         Settings_readMeterModes(this, option[1], 0);
242
         readMeters = true;
Hisham Muhammad's avatar
Hisham Muhammad committed
243
      } else if (String_eq(option[0], "right_meter_modes")) {
Hisham Muhammad's avatar
Hisham Muhammad committed
244
         Settings_readMeterModes(this, option[1], 1);
245
         readMeters = true;
Hisham Muhammad's avatar
Hisham Muhammad committed
246
247
248
249
250
      }
      String_freeArray(option);
   }
   fclose(fd);
   if (!readMeters) {
251
      Settings_defaultMeters(this);
Hisham Muhammad's avatar
Hisham Muhammad committed
252
253
254
255
   }
   return true;
}

Hisham Muhammad's avatar
Hisham Muhammad committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
static void writeFields(FILE* fd, ProcessField* fields, const char* name) {
   fprintf(fd, "%s=", name);
   for (int i = 0; fields[i]; i++) {
      // This "-1" is for compatibility with the older enum format.
      fprintf(fd, "%d ", (int) fields[i]-1);
   }
   fprintf(fd, "\n");
}

static void writeMeters(Settings* this, FILE* fd, int column) {
   for (int i = 0; i < this->columns[column].len; i++) {
      fprintf(fd, "%s ", this->columns[column].names[i]);
   }
   fprintf(fd, "\n");
}

static void writeMeterModes(Settings* this, FILE* fd, int column) {
   for (int i = 0; i < this->columns[column].len; i++) {
      fprintf(fd, "%d ", this->columns[column].modes[i]);
   }
   fprintf(fd, "\n");
}

Hisham Muhammad's avatar
Hisham Muhammad committed
279
280
bool Settings_write(Settings* this) {
   FILE* fd;
281
282
   uid_t euid = geteuid();

283
   (void) seteuid(getuid());
Hisham Muhammad's avatar
Hisham Muhammad committed
284
   fd = fopen(this->filename, "w");
285
   (void) seteuid(euid);
Hisham Muhammad's avatar
Hisham Muhammad committed
286
287
288
   if (fd == NULL) {
      return false;
   }
289
   fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n");
Hisham Muhammad's avatar
Hisham Muhammad committed
290
   fprintf(fd, "# The parser is also very primitive, and not human-friendly.\n");
Hisham Muhammad's avatar
Hisham Muhammad committed
291
   writeFields(fd, this->fields, "fields");
Hisham Muhammad's avatar
Hisham Muhammad committed
292
   // This "-1" is for compatibility with the older enum format.
Hisham Muhammad's avatar
Hisham Muhammad committed
293
294
295
296
297
298
299
   fprintf(fd, "sort_key=%d\n", (int) this->sortKey-1);
   fprintf(fd, "sort_direction=%d\n", (int) this->direction);
   fprintf(fd, "hide_threads=%d\n", (int) this->hideThreads);
   fprintf(fd, "hide_kernel_threads=%d\n", (int) this->hideKernelThreads);
   fprintf(fd, "hide_userland_threads=%d\n", (int) this->hideUserlandThreads);
   fprintf(fd, "shadow_other_users=%d\n", (int) this->shadowOtherUsers);
   fprintf(fd, "show_thread_names=%d\n", (int) this->showThreadNames);
300
   fprintf(fd, "show_program_path=%d\n", (int) this->showProgramPath);
Hisham Muhammad's avatar
Hisham Muhammad committed
301
302
303
304
305
306
307
308
309
   fprintf(fd, "highlight_base_name=%d\n", (int) this->highlightBaseName);
   fprintf(fd, "highlight_megabytes=%d\n", (int) this->highlightMegabytes);
   fprintf(fd, "highlight_threads=%d\n", (int) this->highlightThreads);
   fprintf(fd, "tree_view=%d\n", (int) this->treeView);
   fprintf(fd, "header_margin=%d\n", (int) this->headerMargin);
   fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime);
   fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->countCPUsFromZero);
   fprintf(fd, "update_process_names=%d\n", (int) this->updateProcessNames);
   fprintf(fd, "account_guest_in_cpu_meter=%d\n", (int) this->accountGuestInCPUMeter);
Hisham Muhammad's avatar
Hisham Muhammad committed
310
311
   fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
   fprintf(fd, "delay=%d\n", (int) this->delay);
Hisham Muhammad's avatar
Hisham Muhammad committed
312
313
314
315
   fprintf(fd, "left_meters="); writeMeters(this, fd, 0);
   fprintf(fd, "left_meter_modes="); writeMeterModes(this, fd, 0);
   fprintf(fd, "right_meters="); writeMeters(this, fd, 1);
   fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1);
Hisham Muhammad's avatar
Hisham Muhammad committed
316
317
318
   fclose(fd);
   return true;
}
319

Hisham Muhammad's avatar
Hisham Muhammad committed
320
321
Settings* Settings_new(int cpuCount) {
  
Hisham's avatar
Hisham committed
322
   Settings* this = xCalloc(1, sizeof(Settings));
Hisham Muhammad's avatar
Hisham Muhammad committed
323
324
325
326
327
328
329
330
331
332
333
334
335
336

   this->sortKey = PERCENT_CPU;
   this->direction = 1;
   this->hideThreads = false;
   this->shadowOtherUsers = false;
   this->showThreadNames = false;
   this->hideKernelThreads = false;
   this->hideUserlandThreads = false;
   this->treeView = false;
   this->highlightBaseName = false;
   this->highlightMegabytes = false;
   this->detailedCPUTime = false;
   this->countCPUsFromZero = false;
   this->updateProcessNames = false;
337
   this->cpuCount = cpuCount;
338
   this->showProgramPath = true;
Hisham's avatar
Hisham committed
339
   this->highlightThreads = true;
Hisham Muhammad's avatar
Hisham Muhammad committed
340
   
Hisham's avatar
Hisham committed
341
   this->fields = xCalloc(Platform_numberOfFields+1, sizeof(ProcessField));
Hisham Muhammad's avatar
Hisham Muhammad committed
342
343
344
   // TODO: turn 'fields' into a Vector,
   // (and ProcessFields into proper objects).
   this->flags = 0;
345
   ProcessField* defaults = Platform_defaultFields;
Hisham Muhammad's avatar
Hisham Muhammad committed
346
347
348
349
350
   for (int i = 0; defaults[i]; i++) {
      this->fields[i] = defaults[i];
      this->flags |= Process_fields[defaults[i]].flags;
   }

351
352
353
   char* legacyDotfile = NULL;
   char* rcfile = getenv("HTOPRC");
   if (rcfile) {
Hisham's avatar
Hisham committed
354
      this->filename = xStrdup(rcfile);
355
356
357
358
359
360
361
   } else {
      const char* home = getenv("HOME");
      if (!home) home = "";
      const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
      char* configDir = NULL;
      char* htopDir = NULL;
      if (xdgConfigHome) {
Hisham Muhammad's avatar
Hisham Muhammad committed
362
         this->filename = String_cat(xdgConfigHome, "/htop/htoprc");
Hisham's avatar
Hisham committed
363
         configDir = xStrdup(xdgConfigHome);
364
365
         htopDir = String_cat(xdgConfigHome, "/htop");
      } else {
Hisham Muhammad's avatar
Hisham Muhammad committed
366
         this->filename = String_cat(home, "/.config/htop/htoprc");
367
368
369
370
         configDir = String_cat(home, "/.config");
         htopDir = String_cat(home, "/.config/htop");
      }
      legacyDotfile = String_cat(home, "/.htoprc");
371
      uid_t euid = geteuid();
372
      (void) seteuid(getuid());
373
374
      (void) mkdir(configDir, 0700);
      (void) mkdir(htopDir, 0700);
375
376
      free(htopDir);
      free(configDir);
377
      struct stat st;
378
379
380
      if (lstat(legacyDotfile, &st) != 0) {
         st.st_mode = 0;
      }
381
      if (access(legacyDotfile, R_OK) != 0 || S_ISLNK(st.st_mode)) {
382
383
384
         free(legacyDotfile);
         legacyDotfile = NULL;
      }
385
      (void) seteuid(euid);
386
   }
387
388
389
   this->colorScheme = 0;
   this->changed = false;
   this->delay = DEFAULT_DELAY;
390
   bool ok = Settings_read(this, legacyDotfile ? legacyDotfile : this->filename);
391
392
393
394
395
396
397
   if (ok) {
      if (legacyDotfile) {
         // Transition to new location and delete old configuration file
         if (Settings_write(this))
            unlink(legacyDotfile);
      }
   } else {
398
399
400
      this->changed = true;
      // TODO: how to get SYSCONFDIR correctly through Autoconf?
      char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
401
      ok = Settings_read(this, systemSettings);
402
403
      free(systemSettings);
      if (!ok) {
404
         Settings_defaultMeters(this);
Hisham Muhammad's avatar
Hisham Muhammad committed
405
406
         this->hideKernelThreads = true;
         this->highlightMegabytes = true;
Hisham's avatar
Hisham committed
407
         this->highlightThreads = true;
408
         this->headerMargin = true;
409
410
      }
   }
Hisham Muhammad's avatar
Hisham Muhammad committed
411
   free(legacyDotfile);
412
413
   return this;
}
Hisham Muhammad's avatar
Hisham Muhammad committed
414
415
416
417
418
419
420

void Settings_invertSortOrder(Settings* this) {
   if (this->direction == 1)
      this->direction = -1;
   else
      this->direction = 1;
}