diff --git a/README.md b/README.md index f9235fc..b267b0f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ cpufetch currently supports x86 CPUs (both Intel and AMD CPUs) | Platform | Intel | AMD | Notes | |:---------:|:-------------------------:|:------------------------:|:-----------------:| | Linux | :heavy_check_mark: | :heavy_check_mark: | Prefered platform | -| Windows | :heavy_check_mark: | :heavy_check_mark: | Some information may be missing.
No colors and worse CPU art | +| Windows | :heavy_check_mark: | :heavy_check_mark: | Some information may be missing.
Colors will be used if supported | | macOS | :heavy_exclamation_mark: | :heavy_exclamation_mark: | Untested | diff --git a/src/printer.c b/src/printer.c index babf6b8..dca6805 100644 --- a/src/printer.c +++ b/src/printer.c @@ -9,6 +9,11 @@ #include "cpuid.h" #include "uarch.h" +#ifdef _WIN32 +#define NOMINMAX +#include +#endif + #define COL_NONE "" #define COL_INTEL_FANCY_1 "\x1b[46;1m" #define COL_INTEL_FANCY_2 "\x1b[47;1m" @@ -42,40 +47,40 @@ enum { ATTRIBUTE_PEAK }; -static const char* ATTRIBUTE_FIELDS [] = { - "Name:", +static const char* ATTRIBUTE_FIELDS [] = { + "Name:", "Hypervisor:", "Microarchitecture:", "Technology:", - "Max Frequency:", + "Max Frequency:", "Sockets:", - "Cores:", - "Cores (Total):", + "Cores:", + "Cores (Total):", "AVX:", - "FMA:", - "L1i Size:", - "L1d Size:", - "L2 Size:", + "FMA:", + "L1i Size:", + "L1d Size:", + "L2 Size:", "L3 Size:", - "Peak Performance:", + "Peak Performance:", }; -static const int ATTRIBUTE_LIST[] = { - ATTRIBUTE_NAME, - ATTRIBUTE_HYPERVISOR, - ATTRIBUTE_UARCH, +static const int ATTRIBUTE_LIST[] = { + ATTRIBUTE_NAME, + ATTRIBUTE_HYPERVISOR, + ATTRIBUTE_UARCH, ATTRIBUTE_TECHNOLOGY, - ATTRIBUTE_FREQUENCY, + ATTRIBUTE_FREQUENCY, ATTRIBUTE_SOCKETS, - ATTRIBUTE_NCORES, - ATTRIBUTE_NCORES_DUAL, + ATTRIBUTE_NCORES, + ATTRIBUTE_NCORES_DUAL, ATTRIBUTE_AVX, - ATTRIBUTE_FMA, - ATTRIBUTE_L1i, - ATTRIBUTE_L1d, - ATTRIBUTE_L2, + ATTRIBUTE_FMA, + ATTRIBUTE_L1i, + ATTRIBUTE_L1d, + ATTRIBUTE_L2, ATTRIBUTE_L3, - ATTRIBUTE_PEAK + ATTRIBUTE_PEAK }; struct ascii { @@ -94,7 +99,7 @@ struct ascii { }; void setAttribute(struct ascii* art, int type, char* value) { - art->attributes[type] = value; + art->attributes[type] = value; art->n_attributes_set++; } @@ -109,7 +114,7 @@ char* rgb_to_ansi(struct color* c, bool background, bool bold) { else snprintf(str, 44, "\x1b[38;2;%.3d;%.3d;%.3dm", c->R, c->G, c->B); } - + return str; } @@ -118,15 +123,15 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { uint32_t max_attributes = sizeof(ATTRIBUTE_LIST) / sizeof(ATTRIBUTE_LIST[0]); for(uint32_t i=0; i < max_attributes; i++) { if(ATTRIBUTE_FIELDS[i] == NULL) { - printBug("Attribute field at position %d is empty", i); + printBug("Attribute field at position %d is empty", i); return NULL; } if(i > 0 && ATTRIBUTE_LIST[i] == 0) { - printBug("Attribute list at position %d is empty", i); + printBug("Attribute list at position %d is empty", i); return NULL; } } - + char *COL_FANCY_1, *COL_FANCY_2, *COL_FANCY_3, *COL_FANCY_4, *COL_RETRO_1, *COL_RETRO_2, *COL_RETRO_3, *COL_RETRO_4; struct ascii* art = malloc(sizeof(struct ascii)); art->n_attributes_set = 0; @@ -136,16 +141,16 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { for(uint32_t i=0; i < art->max_attributes; i++) art->attributes[i] = NULL; strcpy(art->reset,RESET); - + if(art->vendor == CPU_VENDOR_INTEL) { COL_FANCY_1 = COL_INTEL_FANCY_1; COL_FANCY_2 = COL_INTEL_FANCY_2; COL_FANCY_3 = COL_INTEL_FANCY_3; COL_FANCY_4 = COL_INTEL_FANCY_4; COL_RETRO_1 = COL_INTEL_RETRO_1; - COL_RETRO_2 = COL_INTEL_RETRO_2; - COL_RETRO_3 = COL_INTEL_RETRO_1; - COL_RETRO_4 = COL_INTEL_RETRO_2; + COL_RETRO_2 = COL_INTEL_RETRO_2; + COL_RETRO_3 = COL_INTEL_RETRO_1; + COL_RETRO_4 = COL_INTEL_RETRO_2; art->ascii_chars[0] = '#'; } else { @@ -154,30 +159,43 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { COL_FANCY_3 = COL_AMD_FANCY_3; COL_FANCY_4 = COL_AMD_FANCY_4; COL_RETRO_1 = COL_AMD_RETRO_1; - COL_RETRO_2 = COL_AMD_RETRO_2; + COL_RETRO_2 = COL_AMD_RETRO_2; COL_RETRO_3 = COL_AMD_RETRO_1; - COL_RETRO_4 = COL_AMD_RETRO_2; - art->ascii_chars[0] = '@'; + COL_RETRO_4 = COL_AMD_RETRO_2; + art->ascii_chars[0] = '@'; } art->ascii_chars[1] = '#'; - + + #ifdef _WIN32 + HANDLE std_handle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD console_mode; + + // Attempt to enable the VT100-processing flag + GetConsoleMode(std_handle, &console_mode); + SetConsoleMode(std_handle, console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); + // Get the console mode flag again, to see if it successfully enabled it + GetConsoleMode(std_handle, &console_mode); + #endif + if(style == STYLE_EMPTY) { #ifdef _WIN32 - art->style = STYLE_LEGACY; + // Use fancy style if VT100-processing is enabled, + // or legacy style in other case + art->style = (console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) ? STYLE_FANCY : STYLE_LEGACY; #else art->style = STYLE_FANCY; - #endif + #endif } else { - art->style = style; + art->style = style; } - + switch(art->style) { case STYLE_LEGACY: strcpy(art->color1_ascii,COL_NONE); - strcpy(art->color2_ascii,COL_NONE); - strcpy(art->color1_text,COL_NONE); - strcpy(art->color2_text,COL_NONE); + strcpy(art->color2_ascii,COL_NONE); + strcpy(art->color1_text,COL_NONE); + strcpy(art->color2_text,COL_NONE); art->reset[0] = '\0'; break; case STYLE_FANCY: @@ -185,14 +203,14 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { COL_FANCY_1 = rgb_to_ansi(cs->c1, true, true); COL_FANCY_2 = rgb_to_ansi(cs->c2, true, true); COL_FANCY_3 = rgb_to_ansi(cs->c3, false, true); - COL_FANCY_4 = rgb_to_ansi(cs->c4, false, true); - } + COL_FANCY_4 = rgb_to_ansi(cs->c4, false, true); + } art->ascii_chars[0] = ' '; art->ascii_chars[1] = ' '; strcpy(art->color1_ascii,COL_FANCY_1); - strcpy(art->color2_ascii,COL_FANCY_2); - strcpy(art->color1_text,COL_FANCY_3); - strcpy(art->color2_text,COL_FANCY_4); + strcpy(art->color2_ascii,COL_FANCY_2); + strcpy(art->color1_text,COL_FANCY_3); + strcpy(art->color2_text,COL_FANCY_4); if(cs != NULL) { free(COL_FANCY_1); free(COL_FANCY_2); @@ -200,17 +218,17 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { free(COL_FANCY_4); } break; - case STYLE_RETRO: + case STYLE_RETRO: if(cs != NULL) { COL_RETRO_1 = rgb_to_ansi(cs->c1, false, true); - COL_RETRO_2 = rgb_to_ansi(cs->c2, false, true); + COL_RETRO_2 = rgb_to_ansi(cs->c2, false, true); COL_RETRO_3 = rgb_to_ansi(cs->c3, false, true); - COL_RETRO_4 = rgb_to_ansi(cs->c4, false, true); - } + COL_RETRO_4 = rgb_to_ansi(cs->c4, false, true); + } strcpy(art->color1_ascii,COL_RETRO_1); - strcpy(art->color2_ascii,COL_RETRO_2); - strcpy(art->color1_text,COL_RETRO_3); - strcpy(art->color2_text,COL_RETRO_4); + strcpy(art->color2_ascii,COL_RETRO_2); + strcpy(art->color1_text,COL_RETRO_3); + strcpy(art->color2_text,COL_RETRO_4); if(cs != NULL) { free(COL_RETRO_1); free(COL_RETRO_2); @@ -218,21 +236,21 @@ struct ascii* set_ascii(VENDOR cpuVendor, STYLE style, struct colors* cs) { free(COL_RETRO_4); } break; - case STYLE_INVALID: + case STYLE_INVALID: default: printBug("Found invalid style (%d)", art->style); - return NULL; + return NULL; } - + char tmp[NUMBER_OF_LINES*LINE_SIZE]; if(art->vendor == CPU_VENDOR_INTEL) - strcpy(tmp, INTEL_ASCII); + strcpy(tmp, INTEL_ASCII); else - strcpy(tmp, AMD_ASCII); - + strcpy(tmp, AMD_ASCII); + for(int i=0; i < NUMBER_OF_LINES; i++) - strncpy(art->art[i], tmp + i*LINE_SIZE, LINE_SIZE); - + strncpy(art->art[i], tmp + i*LINE_SIZE, LINE_SIZE); + return art; } @@ -248,7 +266,7 @@ void print_ascii_intel(struct ascii* art, uint32_t la) { uint32_t space_right; uint32_t space_up = (NUMBER_OF_LINES - art->n_attributes_set)/2; uint32_t space_down = NUMBER_OF_LINES - art->n_attributes_set - space_up; - + printf("\n"); for(uint32_t n=0;nart[n][i] == ' ') { flag = false; - printf("%s%c%s", art->color2_ascii, art->ascii_chars[1], art->reset); + printf("%s%c%s", art->color2_ascii, art->ascii_chars[1], art->reset); } else { printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset); @@ -271,10 +289,10 @@ void print_ascii_intel(struct ascii* art, uint32_t la) { printf("%c",' '); } } - - if(n > space_up-1 && n < NUMBER_OF_LINES-space_down) { + + if(n > space_up-1 && n < NUMBER_OF_LINES-space_down) { attr_to_print = get_next_attribute(art, attr_to_print); - space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_to_print])); + space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_to_print])); printf("%s%s%s%*s%s%s%s\n",art->color1_text, ATTRIBUTE_FIELDS[attr_to_print], art->reset, space_right, "", art->color2_text, art->attributes[attr_to_print], art->reset); } else printf("\n"); @@ -287,12 +305,12 @@ void print_ascii_amd(struct ascii* art, uint32_t la) { uint32_t space_right; uint32_t space_up = (NUMBER_OF_LINES - art->n_attributes_set)/2; uint32_t space_down = NUMBER_OF_LINES - art->n_attributes_set - space_up; - + printf("\n"); for(uint32_t n=0;nart[n][i] == '@') - printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset); + printf("%s%c%s", art->color1_ascii, art->ascii_chars[0], art->reset); else if(art->art[n][i] == '#') printf("%s%c%s", art->color2_ascii, art->ascii_chars[1], art->reset); else @@ -301,7 +319,7 @@ void print_ascii_amd(struct ascii* art, uint32_t la) { if(n > space_up-1 && n < NUMBER_OF_LINES-space_down) { attr_to_print = get_next_attribute(art, attr_to_print); - space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_to_print])); + space_right = 1 + (la - strlen(ATTRIBUTE_FIELDS[attr_to_print])); printf("%s%s%s%*s%s%s%s\n",art->color1_text, ATTRIBUTE_FIELDS[attr_to_print], art->reset, space_right, "", art->color2_text, art->attributes[attr_to_print], art->reset); } else printf("\n"); @@ -313,14 +331,14 @@ void print_ascii_amd(struct ascii* art, uint32_t la) { uint32_t longest_attribute_length(struct ascii* art) { uint32_t max = 0; uint64_t len = 0; - + for(uint32_t i=0; i < art->max_attributes; i++) { if(art->attributes[i] != NULL) { len = strlen(ATTRIBUTE_FIELDS[i]); if(len > max) max = len; } } - + return max; } @@ -336,7 +354,7 @@ bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* f struct ascii* art = set_ascii(get_cpu_vendor(cpu), s, cs); if(art == NULL) return false; - + char* cpu_name = get_str_cpu_name(cpu); char* uarch = get_str_uarch(cpu); char* manufacturing_process = get_str_process(cpu); @@ -345,7 +363,7 @@ bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* f char* n_cores = get_str_topology(cpu, topo, false); char* n_cores_dual = get_str_topology(cpu, topo, true); char* avx = get_str_avx(cpu); - char* fma = get_str_fma(cpu); + char* fma = get_str_fma(cpu); char* l1i = get_str_l1i(topo->cach); char* l1d = get_str_l1d(topo->cach); char* l2 = get_str_l2(topo->cach); @@ -361,23 +379,23 @@ bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* f setAttribute(art,ATTRIBUTE_FMA,fma); setAttribute(art,ATTRIBUTE_L1i,l1i); setAttribute(art,ATTRIBUTE_L1d,l1d); - setAttribute(art,ATTRIBUTE_L2,l2); + setAttribute(art,ATTRIBUTE_L2,l2); setAttribute(art,ATTRIBUTE_PEAK,pp); - + uint32_t socket_num = get_nsockets(topo); - if (socket_num > 1) { + if (socket_num > 1) { setAttribute(art, ATTRIBUTE_SOCKETS, sockets); setAttribute(art, ATTRIBUTE_NCORES_DUAL, n_cores_dual); } if(l3 != NULL) { - setAttribute(art,ATTRIBUTE_L3,l3); + setAttribute(art,ATTRIBUTE_L3,l3); } if(art->n_attributes_set > NUMBER_OF_LINES) { printBug("The number of attributes set is bigger than the max that can be displayed"); - return false; + return false; } - if(cpu->hv->present) - setAttribute(art, ATTRIBUTE_HYPERVISOR, cpu->hv->hv_name); + if(cpu->hv->present) + setAttribute(art, ATTRIBUTE_HYPERVISOR, cpu->hv->hv_name); print_ascii(art); @@ -392,16 +410,16 @@ bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* f free(l1d); free(l2); free(l3); - free(pp); - + free(pp); + free(art->attributes); free(art); - + if(cs != NULL) free_colors_struct(cs); free_cache_struct(cach); free_topo_struct(topo); - free_freq_struct(freq); - free_cpuinfo_struct(cpu); - + free_freq_struct(freq); + free_cpuinfo_struct(cpu); + return true; }