├── .clang-format ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CONTRIBUTORS ├── LICENSE ├── Makefile ├── README.md ├── examples ├── BackTrack.jpg ├── CrunchBang.png ├── Debian.png ├── Fedora.png ├── Fuduntu.png ├── LMDE.png ├── LinuxDeepin.png ├── Mint.png ├── OSX.png ├── OpenBSD.png ├── Peppermint.png ├── Solaris.png ├── Trisquel.png ├── Ubuntu.png ├── Windows.png ├── eOS.jpg └── examples.md ├── man └── man1 │ └── screenfetch-c.1 └── src ├── arrays.c ├── arrays.h ├── colors.h ├── detect.h ├── disp.c ├── disp.h ├── error_flag.c ├── error_flag.h ├── logos.c ├── logos.h ├── main.c ├── misc.h ├── plat ├── bsd │ └── detect.c ├── darwin │ └── detect.c ├── linux │ └── detect.c ├── sun │ └── detect.c └── win32 │ ├── bitmap.c │ ├── bitmap.h │ └── detect.c ├── scripts ├── detectgpu ├── detectgtk ├── detectwm └── detectwmtheme ├── tests ├── gltest.c └── x11test.c ├── util.c ├── util.h └── version.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Right 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: None 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | AfterExternBlock: false 33 | BeforeCatch: false 34 | BeforeElse: false 35 | IndentBraces: false 36 | SplitEmptyFunction: true 37 | SplitEmptyRecord: true 38 | SplitEmptyNamespace: true 39 | BreakBeforeBinaryOperators: None 40 | BreakBeforeBraces: Attach 41 | BreakBeforeInheritanceComma: false 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializersBeforeComma: false 44 | BreakConstructorInitializers: BeforeColon 45 | BreakAfterJavaFieldAnnotations: false 46 | BreakStringLiterals: true 47 | ColumnLimit: 100 48 | CommentPragmas: '^ IWYU pragma:' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 4 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: true 58 | ForEachMacros: 59 | - foreach 60 | - Q_FOREACH 61 | - BOOST_FOREACH 62 | IncludeBlocks: Preserve 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: false 72 | IndentPPDirectives: None 73 | IndentWidth: 2 74 | IndentWrappedFunctionNames: false 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: true 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: None 82 | ObjCBlockIndentWidth: 2 83 | ObjCSpaceAfterProperty: false 84 | ObjCSpaceBeforeProtocolList: true 85 | PenaltyBreakAssignment: 2 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Right 93 | ReflowComments: true 94 | SortIncludes: false 95 | SpaceAfterCStyleCast: false 96 | SpaceBeforeAssignmentOperators: true 97 | SpaceBeforeParens: ControlStatements 98 | SpaceInEmptyParentheses: false 99 | SpacesBeforeTrailingComments: 1 100 | SpacesInAngles: false 101 | SpacesInContainerLiterals: true 102 | SpacesInCStyleCastParentheses: false 103 | SpacesInParentheses: false 104 | SpacesInSquareBrackets: false 105 | Standard: Cpp11 106 | TabWidth: 2 107 | UseTab: Never 108 | ... 109 | 110 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | schedule: 9 | - cron: '0 12 * * *' 10 | 11 | jobs: 12 | build: 13 | strategy: 14 | matrix: 15 | compiler: 16 | - gcc 17 | - clang 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: deps 22 | run: | 23 | sudo apt update 24 | sudo apt install -y libgl-dev libx11-dev 25 | - name: build 26 | run: make CC=${{ matrix.compiler }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore bin directory 2 | bin/ 3 | #ignore emacs backups 4 | *~ 5 | #ignore objects 6 | *.o 7 | #ignore other binaries created by make 8 | *.exe 9 | screenfetch-c 10 | x11test 11 | gltest 12 | 13 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | The following people have contributed to screenfetch-c. 2 | I thank them all for their time and effort: 3 | ------------------------------------------------------- 4 | 5 | Brett Bohnenkamper (KittyKatt) 6 | zerweck 7 | spaghetti2514 8 | shrx 9 | Hu6 10 | diantahoc 11 | NachoSimo 12 | nyanpasu 13 | Aaron Caffrey (wifiextender) 14 | djcj (a.k.a. darealshinji on Github) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013,14,15 William Woodruff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O3 -std=c99 -Wall -Wformat -Wunused-variable -pedantic 3 | CPPFLAGS = -D_POSIX_C_SOURCE=200809L 4 | LDFLAGS = 5 | INSTALL = install -c 6 | 7 | PREFIX = /usr/local 8 | BINDIR = $(PREFIX)/bin 9 | MANDIR = $(PREFIX)/share/man/man1 10 | 11 | ALL_SOURCES = $(shell find . -type f \( -name '*.c' -o -name '*.h' \)) 12 | 13 | SOURCES = $(wildcard ./src/*.c) 14 | OBJS = $(SOURCES:.c=.o) 15 | 16 | EXEEXT = 17 | PROG = screenfetch-c$(EXEEXT) 18 | 19 | 20 | SCRIPTS = 21 | TESTS = 22 | 23 | OLDTARGETS = linux win bsd osx sun 24 | 25 | ifeq ($(COLORS),0) 26 | CPPFLAGS += -DNO_COLORS 27 | endif 28 | ifneq (,$(findstring mingw,$(shell $(CC) -dumpmachine))) 29 | OS = Windows_NT 30 | endif 31 | ifeq ($(OS),Windows_NT) 32 | SOURCES += $(wildcard ./src/plat/win32/*.c) 33 | CPPFLAGS += -DWIN32_LEAN_AND_MEAN 34 | LDFLAGS += -lgdi32 35 | EXEEXT = .exe 36 | else 37 | UNAME_S := $(shell uname -s) 38 | 39 | ifeq ($(UNAME_S),Linux) 40 | SOURCES += $(wildcard ./src/plat/linux/*.c) 41 | CFLAGS += -Wno-unused-result 42 | LDFLAGS += -lX11 -lGL 43 | SCRIPTS += ./src/scripts/detectgtk 44 | TESTS += x11test gltest 45 | endif 46 | 47 | ifeq ($(UNAME_S),Darwin) 48 | SOURCES += $(wildcard ./src/plat/darwin/*.c) 49 | LDFLAGS += -framework CoreFoundation -framework IOKit -framework CoreGraphics 50 | CPPFLAGS += -D_DARWIN_C_SOURCE -D_DARWIN_USE_64_BIT_INODE 51 | endif 52 | 53 | ifeq ($(UNAME_S),SunOS) 54 | SOURCES += $(wildcard ./src/plat/sun/*.c) 55 | LDFLAGS += -lX11 56 | SCRIPTS += ./src/scripts/detectwm ./src/scripts/detectwmtheme 57 | TESTS += x11test 58 | endif 59 | 60 | ifneq (,$(filter $(UNAME_S),FreeBSD NetBSD OpenBSD DragonFly)) 61 | SOURCES += $(wildcard ./src/plat/bsd/*.c) 62 | LDFLAGS += 63 | SCRIPTS += ./src/scripts/detectwm ./src/scripts/detectwmtheme \ 64 | ./src/scripts/detectgtk 65 | endif 66 | endif 67 | 68 | all: $(TESTS) $(OBJS) 69 | $(CC) $(CFLAGS) $(CPPFLAGS) $(OBJS) -o $(PROG) $(LDFLAGS) 70 | 71 | .c.o: 72 | $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ 73 | 74 | install: all 75 | $(INSTALL) $(PROG) $(BINDIR)/$(PROG) 76 | if [ -n "$(SCRIPTS)" ] ; then \ 77 | $(INSTALL) $(SCRIPTS) $(BINDIR) ; \ 78 | fi 79 | mkdir -p $(MANDIR) 80 | $(INSTALL) ./man/man1/screenfetch-c.1 $(MANDIR)/screenfetch-c.1 81 | 82 | uninstall: 83 | rm -rf $(BINDIR)/screenfetch-c 84 | rm -rf $(BINDIR)/detectde 85 | rm -rf $(BINDIR)/detectgtk 86 | rm -rf $(BINDIR)/detectwm 87 | rm -rf $(BINDIR)/detectwmtheme 88 | rm -rf $(BINDIR)/detectgpu 89 | rm -rf $(MANDIR)/screenfetch-c.1 90 | 91 | x11test: 92 | @echo "Testing for X11..." 93 | $(CC) $(CFLAGS) ./src/tests/x11test.c -o ./x11test -lX11 94 | @echo "Looks good." 95 | 96 | gltest: 97 | @echo "Testing for OpenGL..." 98 | $(CC) $(CFLAGS) ./src/tests/gltest.c -o ./gltest -lGL 99 | @echo "Looks good." 100 | 101 | clean: 102 | rm -f ./src/*.o ./src/plat/*/*.o 103 | rm -f threadtest 104 | rm -f x11test 105 | rm -f gltest 106 | rm -f screenfetch-c screenfetch-c.exe 107 | 108 | fmt: 109 | clang-format -i -style=file $(ALL_SOURCES) 110 | 111 | $(OLDTARGETS): all 112 | 113 | .PHONY: all install uninstall clean fmt $(OLDTARGETS) 114 | 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | screenfetch-c 2 | ============= 3 | 4 | [![Build Status](https://img.shields.io/github/workflow/status/woodruffw/screenfetch-c/CI/master)](https://github.com/woodruffw/screenfetch-c/actions?query=workflow%3ACI) 5 | 6 | ## Current Version: 1.6 (release) 7 | 8 | screenfetch-c is an attempt to rewrite screenFetch, a popular shell 9 | script that displays system information and an ASCII logo, in the C 10 | language. 11 | Like the original screenFetch, screenfetch-c is meant to be compatible with a number of systems, including the BSDs, Solaris, GNU/Linux, OS X, and Windows. 12 | 13 | ## Installing screenfetch-c 14 | 15 | ### Dependencies: 16 | screenfetch-c only relies on libraries that come on virtually every system. 17 | 18 | * On Linux, OpenGL is used to detect the GPU. In most package managers, this is listed as `libgl-dev`. 19 | 20 | * On Linux and Solaris, libX11 is required. In most package managers, this is listed as `libX11-dev`. 21 | 22 | Installing screenfetch-c is very simple: 23 | 24 | ```bash 25 | $ git clone https://www.github.com/woodruffw/screenfetch-c.git 26 | $ cd screenfetch-c 27 | $ make 28 | ``` 29 | 30 | If you want to disable colors you can run `make COLORS=0` instead. 31 | 32 | _Note:_ For Solaris, `make` *must* be GNU make. If it isn't, use `gmake`. Using regular (Sun) `make` will cause strange errors. 33 | 34 | ### Arch Linux 35 | 36 | screenfetch-c is availible on the [AUR](https://aur.archlinux.org/packages/screenfetch-c-git/) 37 | 38 | ### OS X 39 | 40 | screenfetch-c is also available via Homebrew! 41 | 42 | To install it, just run the following: 43 | 44 | ```bash 45 | $ brew install woodruffw/screenfetch-c/screenfetch-c 46 | ``` 47 | 48 | ## Removal: 49 | Removing screenfetch-c is just as easy as installing it: 50 | 51 | ```bash 52 | $ sudo make uninstall 53 | ``` 54 | 55 | If you installed it via Homebrew: 56 | 57 | ```bash 58 | $ brew rm screenfetch-c 59 | $ brew untap woodruffw/screenfetch-c # optional 60 | ``` 61 | 62 | ## Contributing 63 | 64 | There are a number of things that still need to be tested or completed in screenfetch-c. 65 | 66 | If you think that you can test/fix/improve one or more of them, feel free to fork and issue requests back to me. 67 | 68 | In particular, the following things still need to be done: 69 | 70 | - Improve error checking and handling. 71 | - Matching screencapture capabilities on Windows with OS X/Linux/BSD/Solaris 72 | - Improve RAM/HDD detection on BSD 73 | - Fix manual mode on Windows 74 | - Improve features on Android 75 | - Improve/replace configuration format and parser 76 | 77 | ## Notes on MinGW 78 | Shell detection on the MinGW build is limited. 79 | You must set the `SHELL` environment variable manually if you're running screenfetch-c from command prompt or PowerShell. 80 | For command prompt that's `set SHELL=cmd.exe` and for PowerShell it's `$env:SHELL = "PowerShell"`. 81 | 82 | You can also run screenfetch-c from a batch script 83 | ``` batch 84 | @echo off 85 | set SHELL=cmd.exe 86 | echo. 87 | cmd /C screenfetch-c.exe 88 | echo. 89 | pause 90 | ``` 91 | or a PowerShell script 92 | ``` ps1 93 | $env:SHELL = "PowerShell" 94 | Write-Host "" 95 | Invoke-Expression -Command:"cmd /C screenfetch-c.exe" 96 | Write-Host " 97 | Press any key to continue ..." 98 | $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") 99 | ``` 100 | if you prefer to start it with a double click. 101 | 102 | Unlike PowerShell the Windows command prompt doesn't support ANSI colors by default. You can deactivate colors if you build with `make COLORS=0`. 103 | However there's a neat project called [ANSICON](https://github.com/adoxa/ansicon) which allows you to enable colors in command prompt by running screenfetch-c with `cmd /C ansicon.exe screenfetch-c.exe`. 104 | 105 | ## Current Known Compatibility: 106 | 107 | _Note:_ These are only the ones that have actually been tested (so far). screenfetch-c may very well work on many of the untested distros, so feel free to try it. 108 | 109 | - [x] OS X 110 | - [x] Windows (Cygwin, MSYS2, MinGW) 111 | - [x] Arch Linux 112 | - [x] Fedora 113 | - [x] Linux Mint 114 | - [x] LMDE 115 | - [x] Ubuntu (including derivatives) 116 | - [x] Fedora 117 | - [x] Debian 118 | - [x] CrunchBang 119 | - [x] Gentoo 120 | - [ ] Funtoo 121 | - [x] FreeBSD 122 | - [x] OpenBSD 123 | - [ ] NetBSD 124 | - [ ] DragonFlyBSD 125 | - [ ] OpenSUSE 126 | - [ ] Mandriva/Mandrake 127 | - [ ] Slackware 128 | - [x] Red Hat (RHEL) 129 | - [ ] Frugalware 130 | - [x] Peppermint 131 | - [ ] SolusOS 132 | - [ ] Mageia 133 | - [ ] ParabolaGNU/Linux-libre 134 | - [ ] Viperr 135 | - [x] LinuxDeepin 136 | - [ ] Chakra 137 | - [x] Fuduntu 138 | - [x] Trisquel 139 | - [ ] Manjaro 140 | - [x] ElementaryOS (styled as 'elementary OS') 141 | - [ ] Scientific Linux 142 | - [x] Backtrack Linux 143 | - [x] Kali Linux 144 | - [ ] Sabayon 145 | - [x] Android (requires -D "Android" flag) 146 | - [x] Linux (upon failure to detect a specific distro) 147 | - [x] Solaris (including SunOS, OpenSolaris, and OpenIndiana) 148 | - [x] Angstrom 149 | 150 | ## License 151 | screenfetch-c is licensed under the MIT license. 152 | 153 | For the exact terms, see the [license](./LICENSE). 154 | -------------------------------------------------------------------------------- /examples/BackTrack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/BackTrack.jpg -------------------------------------------------------------------------------- /examples/CrunchBang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/CrunchBang.png -------------------------------------------------------------------------------- /examples/Debian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Debian.png -------------------------------------------------------------------------------- /examples/Fedora.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Fedora.png -------------------------------------------------------------------------------- /examples/Fuduntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Fuduntu.png -------------------------------------------------------------------------------- /examples/LMDE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/LMDE.png -------------------------------------------------------------------------------- /examples/LinuxDeepin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/LinuxDeepin.png -------------------------------------------------------------------------------- /examples/Mint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Mint.png -------------------------------------------------------------------------------- /examples/OSX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/OSX.png -------------------------------------------------------------------------------- /examples/OpenBSD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/OpenBSD.png -------------------------------------------------------------------------------- /examples/Peppermint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Peppermint.png -------------------------------------------------------------------------------- /examples/Solaris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Solaris.png -------------------------------------------------------------------------------- /examples/Trisquel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Trisquel.png -------------------------------------------------------------------------------- /examples/Ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Ubuntu.png -------------------------------------------------------------------------------- /examples/Windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/Windows.png -------------------------------------------------------------------------------- /examples/eOS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woodruffw/screenfetch-c/2d76746f07e502818051652878c334f9eb93ea6d/examples/eOS.jpg -------------------------------------------------------------------------------- /examples/examples.md: -------------------------------------------------------------------------------- 1 | screenfetch-c 2 | ============= 3 | 4 | ### Examples: 5 | 6 | Here are some examples of the output that screenfetch-c is capable of providing on various OSes. 7 | 8 | Please keep in mind the fact that some of these images may not reflect the most recent version of screenfetch-c. 9 | 10 | 11 | Windows: 12 | 13 | 14 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Windows.png?raw=true) 15 | 16 | OS X: 17 | 18 | 19 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/OSX.png?raw=true) 20 | 21 | Ubuntu based: 22 | 23 | 24 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Ubuntu.png?raw=true) 25 | 26 | Fedora: 27 | 28 | 29 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Fedora.png?raw=true) 30 | 31 | Linux Mint: 32 | 33 | 34 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Mint.png?raw=true) 35 | 36 | Linux Mint Debian (LMDE): 37 | 38 | 39 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/LMDE.png?raw=true) 40 | 41 | Elementary OS: 42 | 43 | 44 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/eOS.jpg?raw=true) 45 | 46 | Backtrack Linux: 47 | 48 | 49 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/BackTrack.jpg?raw=true) 50 | 51 | CrunchBang: 52 | 53 | 54 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/CrunchBang.png?raw=true) 55 | 56 | Debian: 57 | 58 | 59 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Debian.png?raw=true) 60 | 61 | Peppermint: 62 | 63 | 64 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Peppermint.png?raw=true) 65 | 66 | Trisquel: 67 | 68 | 69 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Trisquel.png?raw=true) 70 | 71 | Fuduntu: 72 | 73 | 74 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Fuduntu.png?raw=true) 75 | 76 | LinuxDeepin: 77 | 78 | 79 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/LinuxDeepin.png?raw=true) 80 | 81 | OpenBSD: 82 | 83 | 84 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/OpenBSD.png?raw=true) 85 | 86 | Solaris: 87 | 88 | ![alt tag] (https://raw.github.com/woodrufw/screenfetch-c/master/examples/Solaris.png?raw=true) 89 | -------------------------------------------------------------------------------- /man/man1/screenfetch-c.1: -------------------------------------------------------------------------------- 1 | .\" Manpage for screenfetch-c 2 | .\" Contact woodruffw on GitHub or at william @ tuffbizz.com to report any bugs or errors 3 | .TH screenfetch-c 1 "04 August 2013" "1.6r" "User Commands" 4 | .SH NAME 5 | .BR screenfetch-c " - Display computer information and an ASCII logo" 6 | .SH SYNOPSIS 7 | .B screenfetch-c 8 | .RI [ OPTIONS ] 9 | .SH DESCRIPTION 10 | .B screenfetch-c 11 | is a C rewrite of the original screenFetch, which was written in bash by Brett Bohnenkamper. 12 | Like the original, it displays both an ASCII logo determined by the computer's OS and a variety of statistics, including kernel type, ram, uptime, and so forth. 13 | .SH COMPATIBILITY 14 | Supported OSes: 15 | Microsoft Windows, Mac OS X, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris and its derivatives, 16 | and most Linux-kernel based distributions. 17 | .PP 18 | .I Note: 19 | If you are using manual mode to provide 20 | .B screenfetch-c 21 | with system information, you will need to enter the distribution name EXACTLY as written below: 22 | Arch Linux, ParabolaGNU/Linux-libre, Chakra, Manjaro, Frugalware, Ubuntu, LinuxMint, SolusOS, Debian, LMDE, CrunchBang, Peppermint, LinuxDeepin, Trisquel, elementary OS, Backtrack Linux, Slackware, Gentoo, Sabayon, Funtoo, Fuduntu, Fedora, OpenSUSE, Red Hat Linux, Mandriva, Mandrake, Mageia, Viperr, Andoid, Linux, Solaris, Angstrom. 23 | .PP 24 | Supported shells: 25 | GNU bash, csh, zsh, ksh, fish, dash, ash. 26 | .SH OPTIONS 27 | .PP 28 | .BR \-v , 29 | .B \-\-verbose 30 | .PP 31 | .TI Enable verbose mode, which prints out detection information. 32 | .PP 33 | .BR \-s , 34 | .B \-\-screenshot 35 | .PP 36 | Take a screenshot after completing the output. 37 | On non\-Windows systems, this will save a file titled 38 | .RI ' screenfetch_screenshot.png ' 39 | in 40 | .BR $HOME . 41 | On Windows, this will save the screenshot in the system clipboard. 42 | .PP 43 | .BR \-n , 44 | .B \-\-no-logo 45 | .PP 46 | Strip output of ASCII logo - print information only. 47 | .PP 48 | .BR \-D , 49 | .BI \-\-distro " DISTRO" 50 | .PP 51 | Set the distro outputted by 52 | .BR screenfetch-c . 53 | .PP 54 | .BR \-E , 55 | .B \-\-suppress-errors 56 | .PP 57 | Suppress (most) error messages as they arise. 58 | .PP 59 | .BR \-p , 60 | .B \-\-portrait 61 | .PP 62 | Print output in portrait mode. 63 | .PP 64 | .BR \-V , 65 | .B \-\-version 66 | .PP 67 | Display the version of 68 | .B screenfetch-c 69 | currently being used. 70 | .PP 71 | .BR \-h , 72 | .B \-\-help 73 | .PP 74 | Displays help and compatibility information. 75 | .PP 76 | .BR \-L , 77 | .BI \-\-logo-only " DISTRO" 78 | .PP 79 | Output only the ASCII logo associated with that distro. Follows the general naming conventions of the 80 | .B \-D 81 | flag, but with "OS X", "Windows", and "Solaris" as possibilities as well. 82 | .SH ENVIRONMENT 83 | .B screenfetch-c 84 | uses the following environment variables: 85 | .PP 86 | .BR USER " - Used on BSD to determine the current user." 87 | .PP 88 | .BR HOME " - Used to determine the user's home directory." 89 | .PP 90 | .BR SHELL " - Used to determine the active shell." 91 | .PP 92 | Each of these variables must be defined properly in order for 93 | .B screenfetch-c 94 | to function as intended. 95 | .SH RELEASE HISTORY 96 | .IR 0.1 " - ALPHA - INCOMPLETE, UNCOMPILED" 97 | .PP 98 | .IR 0.5 " - ALPHA - INCOMPLETE, TEST COMPILED" 99 | .PP 100 | .IR 1.0 " - BETA - LACKING MINOR PARTS, STABLE, WORKING ON MOST SYSTEMS" 101 | .PP 102 | .IR 1.1 " - BETA - NEARLY COMPLETE, MINOR BUGS AND GPU DETECTION NOT FINISHED" 103 | .PP 104 | .IR 1.2 " - RELEASE - WORKS ON THE MAJORITY OF SYSTEMS" 105 | .PP 106 | .IR 1.3 " - RELEASE - SIGNIFICANT REFACTORING AND PERFORMANCE IMPROVEMENTS" 107 | .PP 108 | .IR 1.4+ " - RELEASE - CODE REDUCTION, PERFORMANCE IMPROVEMENTS AND NATIVIZATION ON LINUX" 109 | .SH BUGS AND ERRATIC BEHAVIOR 110 | Shell version detection relies of very specific naming schemes and may appear incorrectly if any shell changes its versioning scheme. 111 | .PP 112 | DragonFly BSD systems with more than 4GiB of RAM may have their RAM stats displayed incorrectly, as 32-bit integers are used in sysctl. 113 | .PP 114 | Memory detection on Linux systems includes swap/buffer RAM in used RAM, not free RAM. While this is not a bug per se, it may contradict figures from other utilities (which factor out swap/buffer RAM). 115 | .PP 116 | Found a bug or issue? Please tell me about it: 117 | .I http://github.com/woodruffw/screenfetch-c 118 | .SH DIAGNOSTICS 119 | .B screenfetch-c 120 | has two built-in diagnostic output modes: verbose (disabled by default) and error (enabled by default). 121 | If a serious or fatal error occurs, the user will be notified via error (stderr). 122 | Otherwise, the user may choose to enable the verbose mode, which display real-time detection. 123 | .SH EXIT STATUS 124 | .B screenfetch-c 125 | returns 126 | .B EXIT_SUCCESS 127 | in all circumstances except for malformed argument strings. 128 | For example, 129 | .B screenfetch-c 130 | will return 131 | .B EXIT_FAILURE 132 | if flagged with 133 | .B \-D 134 | but not given an additional argument. 135 | .SH AUTHOR 136 | .B screenfetch-c 137 | was written and is maintained by William Woodruff 138 | .RI ( "william @ tuffbizz.com" ) 139 | .PP 140 | The original screenFetch was written by Brett Bohnenkamper 141 | .RI ( "kittykatt @ archlinux.us" ) 142 | .PP 143 | For a list of contributors to 144 | .BR screenfetch-c , 145 | please refer to the CONTRIBUTORS file. 146 | .SH SEE ALSO 147 | .IR screenFetch (1), 148 | .IR archey (1) 149 | -------------------------------------------------------------------------------- /src/arrays.c: -------------------------------------------------------------------------------- 1 | /* arrays.c 2 | ** Authors: Aaron Caffrey, William Woodruff 3 | ** ------------- 4 | ** 5 | ** The strings used by screenfetch-c to store system information are 6 | ** initialized in this file. 7 | */ 8 | 9 | #include "arrays.h" 10 | #include "misc.h" 11 | #include "colors.h" 12 | 13 | char given_distro_str[MAX_STRLEN] = "Unknown"; 14 | char distro_str[MAX_STRLEN] = "Unknown"; 15 | char host_str[MAX_STRLEN] = "Unknown"; 16 | char kernel_str[MAX_STRLEN] = "Unknown"; 17 | char uptime_str[MAX_STRLEN] = "Unknown"; 18 | char pkgs_str[MAX_STRLEN] = "Unknown"; 19 | char cpu_str[MAX_STRLEN] = "Unknown"; 20 | char gpu_str[MAX_STRLEN] = "Unknown"; 21 | char disk_str[MAX_STRLEN] = "Unknown"; 22 | char mem_str[MAX_STRLEN] = "Unknown"; 23 | char shell_str[MAX_STRLEN] = "Unknown"; 24 | char res_str[MAX_STRLEN] = "Unknown"; 25 | char de_str[MAX_STRLEN] = "Unknown"; 26 | char wm_str[MAX_STRLEN] = "Unknown"; 27 | char wm_theme_str[MAX_STRLEN] = "Unknown"; 28 | char gtk_str[MAX_STRLEN] = "Unknown"; 29 | char icon_str[MAX_STRLEN] = "Unknown"; 30 | char font_str[MAX_STRLEN] = "Unknown"; 31 | 32 | char host_color[MAX_STRLEN] = TNRM; 33 | 34 | char *detected_arr[DETECTED_ARR_LEN] = {host_str, distro_str, kernel_str, cpu_str, gpu_str, 35 | shell_str, pkgs_str, disk_str, mem_str, uptime_str, 36 | res_str, de_str, wm_str, wm_theme_str, gtk_str, 37 | icon_str, font_str}; 38 | 39 | char *detected_arr_names[DETECTED_ARR_LEN] = { 40 | "", "OS: ", "Kernel: ", "CPU: ", "GPU: ", "Shell: ", 41 | "Packages: ", "Disk: ", "Memory: ", "Uptime: ", "Resolution: ", "DE: ", 42 | "WM: ", "WM Theme: ", "GTK: ", "Icon Theme: ", "Font: "}; 43 | -------------------------------------------------------------------------------- /src/arrays.h: -------------------------------------------------------------------------------- 1 | /* arrays.h 2 | ** Authors: Aaron Caffrey, William Woodruff 3 | ** ------------- 4 | ** 5 | ** The strings used by screenfetch-c to store system information are 6 | ** externalized in this file. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_ARRAYS_H 10 | #define SCREENFETCH_C_ARRAYS_H 11 | 12 | #include "misc.h" 13 | 14 | extern char given_distro_str[MAX_STRLEN]; 15 | extern char distro_str[MAX_STRLEN]; 16 | extern char host_str[MAX_STRLEN]; 17 | extern char kernel_str[MAX_STRLEN]; 18 | extern char uptime_str[MAX_STRLEN]; 19 | extern char pkgs_str[MAX_STRLEN]; 20 | extern char cpu_str[MAX_STRLEN]; 21 | extern char gpu_str[MAX_STRLEN]; 22 | extern char disk_str[MAX_STRLEN]; 23 | extern char mem_str[MAX_STRLEN]; 24 | extern char shell_str[MAX_STRLEN]; 25 | extern char res_str[MAX_STRLEN]; 26 | extern char de_str[MAX_STRLEN]; 27 | extern char wm_str[MAX_STRLEN]; 28 | extern char wm_theme_str[MAX_STRLEN]; 29 | extern char gtk_str[MAX_STRLEN]; 30 | extern char icon_str[MAX_STRLEN]; 31 | extern char font_str[MAX_STRLEN]; 32 | 33 | extern char host_color[MAX_STRLEN]; 34 | 35 | #define DETECTED_ARR_LEN 17 36 | extern char *detected_arr[DETECTED_ARR_LEN]; 37 | extern char *detected_arr_names[DETECTED_ARR_LEN]; 38 | 39 | #endif /* SCREENFETCH_C_ARRAYS_H */ 40 | -------------------------------------------------------------------------------- /src/colors.h: -------------------------------------------------------------------------------- 1 | /* colors.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Macros for colorified terminal output. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_COLORS_H 10 | #define SCREENFETCH_C_COLORS_H 11 | 12 | #ifdef NO_COLORS 13 | 14 | #define TNRM "" 15 | #define TBLK "" 16 | #define TRED "" 17 | #define TGRN "" 18 | #define TBRN "" 19 | #define TBLU "" 20 | #define TPUR "" 21 | #define TCYN "" 22 | #define TLGY "" 23 | #define TDGY "" 24 | #define TLRD "" 25 | #define TLGN "" 26 | #define TYLW "" 27 | #define TLBL "" 28 | #define TLPR "" 29 | #define TLCY "" 30 | #define TWHT "" 31 | 32 | #else 33 | 34 | #define TNRM "\x1B[0m" /* normal */ 35 | #define TBLK "\x1B[0;30m" /* black */ 36 | #define TRED "\x1B[0;31m" /* red */ 37 | #define TGRN "\x1B[0;32m" /* green */ 38 | #define TBRN "\x1B[0;33m" /* brown */ 39 | #define TBLU "\x1B[0;34m" /* blue */ 40 | #define TPUR "\x1B[0;35m" /* purple */ 41 | #define TCYN "\x1B[0;36m" /* cyan */ 42 | #define TLGY "\x1B[0;37m" /* light gray */ 43 | #define TDGY "\x1B[1;30m" /* dark gray */ 44 | #define TLRD "\x1B[1;31m" /* light red */ 45 | #define TLGN "\x1B[1;32m" /* light green */ 46 | #define TYLW "\x1B[1;33m" /* yellow */ 47 | #define TLBL "\x1B[1;34m" /* light blue */ 48 | #define TLPR "\x1B[1;35m" /* light purple */ 49 | #define TLCY "\x1B[1;36m" /* light cyan */ 50 | #define TWHT "\x1B[1;37m" /* white */ 51 | 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/detect.h: -------------------------------------------------------------------------------- 1 | /* detect.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c are prototyped here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_DETECT_H 10 | #define SCREENFETCH_C_DETECT_H 11 | 12 | void detect_distro(void); 13 | void detect_host(void); 14 | void detect_kernel(void); 15 | void detect_uptime(void); 16 | void detect_pkgs(void); 17 | void detect_cpu(void); 18 | void detect_gpu(void); 19 | void detect_disk(void); 20 | void detect_mem(void); 21 | void detect_shell(void); 22 | void detect_res(void); 23 | void detect_de(void); 24 | void detect_wm(void); 25 | void detect_wm_theme(void); 26 | void detect_gtk(void); 27 | 28 | #endif /* SCREENFETCH_C_DETECT_H */ 29 | -------------------------------------------------------------------------------- /src/disp.c: -------------------------------------------------------------------------------- 1 | /* disp.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Functions used by screenfetch-c for displaying version 6 | ** and help output to the user. 7 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 8 | */ 9 | 10 | /* standard includes */ 11 | #include 12 | #include 13 | #include 14 | 15 | /* program includes */ 16 | #include "version.h" 17 | #include "logos.h" 18 | #include "colors.h" 19 | #include "misc.h" 20 | #include "disp.h" 21 | #include "arrays.h" 22 | 23 | /* display_version 24 | called if the -V (--version) flag is tripped 25 | */ 26 | void display_version(void) { 27 | printf("%s\n", "screenfetch-c - Version " SCREENFETCH_C_VERSION_MAJOR 28 | "." SCREENFETCH_C_VERSION_MINOR ", revision " SCREENFETCH_C_VERSION_RELEASE "."); 29 | return; 30 | } 31 | 32 | /* display_help 33 | called if the -h (--help) flag is tripped 34 | */ 35 | void display_help(void) { 36 | display_version(); 37 | printf("\n%s\n", "Options:\n" 38 | " -v, --verbose\t\t\t Enable verbosity during output.\n" 39 | " -s, --screenshot\t\t Take a screenshot.\n" 40 | " -n, --no-logo\t\t\t Print output without a logo.\n" 41 | " -D, --distro [DISTRO]\t\t Print output with DISTRO's logo.\n" 42 | " -E, --suppress-errors\t\t Suppress error output.\n" 43 | " -p, --portrait\t\t Print output in portrait mode.\n" 44 | " -V, --version\t\t\t Output screenfetch-c's version and exit.\n" 45 | " -h, --help\t\t\t Output this help information.\n" 46 | " -L, --logo-only [DISTRO]\t Output only DISTRO's logo.\n" 47 | "For more information, consult screenfetch-c's man page.\n"); 48 | 49 | return; 50 | } 51 | 52 | /* display_verbose 53 | called if the -v (--verbose) flag is tripped 54 | arguments: char *data[], *data_names[] the system data and names 55 | */ 56 | void display_verbose(char *data[], char *data_names[]) { 57 | int i = 0; 58 | for (i = 0; i < DETECTED_ARR_LEN; i++) 59 | VERBOSE_OUT(data_names[i], data[i]); 60 | 61 | return; 62 | } 63 | 64 | /* process_logo_only 65 | output handling for output_logo_only 66 | argument char *distro: the output logo 67 | argument unsigned short int num: the length of the logo in lines 68 | */ 69 | void process_logo_only(char *distro[], unsigned short int num) { 70 | unsigned short int x = 0; 71 | 72 | for (x = 0; x < num; x++) 73 | printf("%s\n", distro[x]); 74 | 75 | return; 76 | } 77 | 78 | /* output_logo_only 79 | outputs an ASCII logo based upon the distro name passed to it 80 | argument char *distro: the name of the distro to output 81 | */ 82 | void output_logo_only(char *distro) { 83 | if (STREQ(distro, "Windows")) { 84 | process_logo_only(windows_logo, 16); 85 | } else if (strstr(distro, "OS X") || strstr(distro, "Mac OS") || strstr(distro, "macOS")) { 86 | process_logo_only(macosx_logo, 16); 87 | } else if (STREQ(distro, "Arch Linux - Old")) { 88 | process_logo_only(oldarch_logo, 18); 89 | } else if (STREQ(distro, "Arch Linux")) { 90 | process_logo_only(arch_logo, 19); 91 | } else if (STREQ(distro, "LinuxMint")) { 92 | process_logo_only(mint_logo, 18); 93 | } else if (STREQ(distro, "LMDE")) { 94 | process_logo_only(lmde_logo, 18); 95 | } else if (STREQ(distro, "Ubuntu") || STREQ(distro, "Lubuntu") || STREQ(distro, "Xubuntu")) { 96 | process_logo_only(ubuntu_logo, 18); 97 | } else if (STREQ(distro, "Debian")) { 98 | process_logo_only(debian_logo, 18); 99 | } else if (STREQ(distro, "CrunchBang")) { 100 | process_logo_only(crunchbang_logo, 18); 101 | } else if (STREQ(distro, "Gentoo")) { 102 | process_logo_only(gentoo_logo, 18); 103 | } else if (STREQ(distro, "Funtoo")) { 104 | process_logo_only(funtoo_logo, 18); 105 | } else if (STREQ(distro, "Fedora")) { 106 | process_logo_only(fedora_logo, 18); 107 | } else if (STREQ(distro, "Mandriva") || STREQ(distro, "Mandrake")) { 108 | process_logo_only(mandriva_mandrake_logo, 18); 109 | } else if (STREQ(distro, "OpenSUSE")) { 110 | process_logo_only(opensuse_logo, 18); 111 | } else if (STREQ(distro, "Slackware")) { 112 | process_logo_only(slackware_logo, 21); 113 | } else if (STREQ(distro, "Red Hat Linux")) { 114 | process_logo_only(redhat_logo, 18); 115 | } else if (STREQ(distro, "Frugalware")) { 116 | process_logo_only(frugalware_logo, 23); 117 | } else if (STREQ(distro, "Peppermint")) { 118 | process_logo_only(peppermint_logo, 19); 119 | } else if (STREQ(distro, "SolusOS")) { 120 | process_logo_only(solusos_logo, 18); 121 | } else if (STREQ(distro, "Mageia")) { 122 | process_logo_only(mageia_logo, 18); 123 | } else if (STREQ(distro, "ParabolaGNU/Linux-libre")) { 124 | process_logo_only(parabolagnu_linuxlibre_logo, 18); 125 | } else if (STREQ(distro, "Viperr")) { 126 | process_logo_only(viperr_logo, 18); 127 | } else if (STREQ(distro, "LinuxDeepin")) { 128 | process_logo_only(linuxdeepin_logo, 18); 129 | } else if (STREQ(distro, "Chakra")) { 130 | process_logo_only(chakra_logo, 18); 131 | } else if (STREQ(distro, "Fuduntu")) { 132 | process_logo_only(fuduntu_logo, 21); 133 | } else if (STREQ(distro, "Trisquel")) { 134 | process_logo_only(trisquel_logo, 18); 135 | } else if (STREQ(distro, "Manjaro")) { 136 | process_logo_only(manjaro_logo, 18); 137 | } else if (STREQ(distro, "elementary OS")) { 138 | process_logo_only(elementaryos_logo, 18); 139 | } else if (STREQ(distro, "Scientific Linux")) { 140 | process_logo_only(scientificlinux_logo, 20); 141 | } else if (STREQ(distro, "Backtrack Linux")) { 142 | process_logo_only(backtracklinux_logo, 21); 143 | } else if (STREQ(distro, "Kali Linux")) { 144 | process_logo_only(kalilinux_logo, 21); 145 | } else if (STREQ(distro, "Sabayon")) { 146 | process_logo_only(sabayon_logo, 18); 147 | } else if (STREQ(distro, "FreeBSD")) { 148 | process_logo_only(freebsd_logo, 18); 149 | } else if (STREQ(distro, "OpenBSD")) { 150 | process_logo_only(openbsd_logo, 23); 151 | } else if (STREQ(distro, "NetBSD")) { 152 | process_logo_only(netbsd_logo, 20); 153 | } else if (STREQ(distro, "DragonFly BSD")) { 154 | process_logo_only(dragonflybsd_logo, 18); 155 | } else if (STREQ(distro, "Android")) { 156 | process_logo_only(android_logo, 16); 157 | } else if (STREQ(distro, "Solaris")) { 158 | process_logo_only(solaris_logo, 17); 159 | } else if (STREQ(distro, "Angstrom")) { 160 | process_logo_only(angstrom_logo, 16); 161 | } else /* if (STREQ(distro_str, "Linux")) */ 162 | { 163 | process_logo_only(linux_logo, 16); 164 | } 165 | 166 | return; 167 | } 168 | 169 | /* process_data 170 | output handling main_ascii_output 171 | argument char *data[]: the data being output 172 | argument char *data_names[]: the name associated with each datum 173 | argument char *logo[]: the logo associated with the distro 174 | argument unsigned short int num1, num2: indices for the data 175 | argument char *col1..3: colors for the output 176 | */ 177 | void process_data(char *data[], char *data_names[], char *logo[], unsigned short int num1, 178 | unsigned short int num2, char *col1, char *col2, char *col3) { 179 | unsigned short int x = 0; 180 | 181 | if (0 == num2) { 182 | for (x = 0; x < num1; x++) { 183 | printf("%s %s%s%s%s%s%s\n", logo[x], col1, col2, col3, data_names[x], TNRM, data[x]); 184 | } 185 | } else { 186 | for (x = 0; x < num1; x++) { 187 | if (x < num2) { 188 | printf("%s %s%s%s%s%s%s\n", logo[x], col1, col2, col3, data_names[x], TNRM, data[x]); 189 | } else { 190 | printf("%s\n", logo[x]); 191 | } 192 | } 193 | } 194 | 195 | return; 196 | } 197 | 198 | /* main_ascii_output 199 | the primary output for screenfetch-c 200 | arguments char *data[], char *data_names[]: 201 | */ 202 | void main_ascii_output(char *data[], char *data_names[]) { 203 | if (strstr(data[1], "Microsoft Windows 8") || strstr(data[1], "Microsoft Windows 10")) { 204 | process_data(data, data_names, windows_modern_logo, 19, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 205 | } else if (strstr(data[1], "Microsoft")) { 206 | process_data(data, data_names, windows_logo, 16, DETECTED_ARR_LEN, TRED, TWHT, TRED); 207 | } else if (strstr(data[1], "OS X") || strstr(data[1], "Mac OS") || strstr(data[1], "macOS")) { 208 | process_data(data, data_names, macosx_logo, 16, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 209 | } else if (STREQ(data[1], "Arch Linux - Old")) { 210 | process_data(data, data_names, oldarch_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 211 | } else if (STREQ(data[1], "Arch Linux")) { 212 | process_data(data, data_names, arch_logo, 19, DETECTED_ARR_LEN, TLCY, TNRM, TLCY); 213 | } else if (STREQ(data[1], "LinuxMint")) { 214 | process_data(data, data_names, mint_logo, 18, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 215 | } else if (STREQ(data[1], "LMDE")) { 216 | process_data(data, data_names, lmde_logo, 18, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 217 | } else if (STREQ(data[1], "Ubuntu") || STREQ(data[1], "Lubuntu") || STREQ(data[1], "Xubuntu")) { 218 | process_data(data, data_names, ubuntu_logo, 18, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 219 | } else if (STREQ(data[1], "Debian")) { 220 | process_data(data, data_names, debian_logo, 18, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 221 | } else if (STREQ(data[1], "CrunchBang")) { 222 | process_data(data, data_names, crunchbang_logo, 18, DETECTED_ARR_LEN, TDGY, TNRM, TDGY); 223 | } else if (STREQ(data[1], "Gentoo")) { 224 | process_data(data, data_names, gentoo_logo, 18, DETECTED_ARR_LEN, TLPR, TNRM, TLPR); 225 | } else if (STREQ(data[1], "Funtoo")) { 226 | process_data(data, data_names, funtoo_logo, 18, DETECTED_ARR_LEN, TLPR, TNRM, TLPR); 227 | } else if (STREQ(data[1], "Fedora")) { 228 | process_data(data, data_names, fedora_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 229 | } else if (STREQ(data[1], "Mandriva") || STREQ(data[1], "Mandrake")) { 230 | process_data(data, data_names, mandriva_mandrake_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 231 | } else if (STREQ(data[1], "OpenSUSE")) { 232 | process_data(data, data_names, opensuse_logo, 18, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 233 | } else if (STREQ(data[1], "Slackware")) { 234 | process_data(data, data_names, slackware_logo, 21, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 235 | } else if (STREQ(data[1], "Red Hat Linux")) { 236 | process_data(data, data_names, redhat_logo, 18, DETECTED_ARR_LEN, TRED, TNRM, TRED); 237 | } else if (STREQ(data[1], "Frugalware")) { 238 | process_data(data, data_names, frugalware_logo, 23, DETECTED_ARR_LEN, TLCY, TNRM, TLCY); 239 | } else if (STREQ(data[1], "Peppermint")) { 240 | process_data(data, data_names, peppermint_logo, 18, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 241 | } else if (STREQ(data[1], "SolusOS")) { 242 | process_data(data, data_names, solusos_logo, 18, DETECTED_ARR_LEN, TLGY, TNRM, TLGY); 243 | } else if (STREQ(data[1], "Mageia")) { 244 | process_data(data, data_names, mageia_logo, 18, DETECTED_ARR_LEN, TLGY, TNRM, TLGY); 245 | } else if (STREQ(data[1], "ParabolaGNU/Linux-libre")) { 246 | process_data(data, data_names, parabolagnu_linuxlibre_logo, 18, DETECTED_ARR_LEN, TLGY, TLPR, 247 | TLGY); 248 | } else if (STREQ(data[1], "Viperr")) { 249 | process_data(data, data_names, viperr_logo, 18, DETECTED_ARR_LEN, TLGY, TNRM, TLGY); 250 | } else if (STREQ(data[1], "LinuxDeepin")) { 251 | process_data(data, data_names, linuxdeepin_logo, 18, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 252 | } else if (STREQ(data[1], "Chakra")) { 253 | process_data(data, data_names, chakra_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 254 | } else if (STREQ(data[1], "Fuduntu")) { 255 | process_data(data, data_names, fuduntu_logo, 21, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 256 | } else if (STREQ(data[1], "Trisquel")) { 257 | process_data(data, data_names, trisquel_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 258 | } else if (STREQ(data[1], "Manjaro")) { 259 | process_data(data, data_names, manjaro_logo, 18, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 260 | } else if (STREQ(data[1], "elementary OS")) { 261 | process_data(data, data_names, elementaryos_logo, 18, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 262 | } else if (STREQ(data[1], "Scientific Linux")) { 263 | process_data(data, data_names, scientificlinux_logo, 20, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 264 | } else if (STREQ(data[1], "Backtrack Linux")) { 265 | process_data(data, data_names, backtracklinux_logo, 21, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 266 | } else if (STREQ(data[1], "Kali Linux")) { 267 | process_data(data, data_names, backtracklinux_logo, 21, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 268 | } else if (STREQ(data[1], "Sabayon")) { 269 | process_data(data, data_names, sabayon_logo, 18, DETECTED_ARR_LEN, TLBL, TNRM, TLBL); 270 | } else if (STREQ(data[1], "Android")) { 271 | process_data(data, data_names, android_logo, 16, DETECTED_ARR_LEN, TLGN, TNRM, TLGN); 272 | } else if (STREQ(data[1], "Angstrom")) { 273 | process_data(data, data_names, angstrom_logo, 16, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 274 | } else if (STREQ(data[1], "Linux")) { 275 | process_data(data, data_names, linux_logo, 18, DETECTED_ARR_LEN, TLGY, TNRM, TLGY); 276 | } else if (STREQ(data[1], "FreeBSD")) { 277 | process_data(data, data_names, freebsd_logo, 18, DETECTED_ARR_LEN, TLRD, TNRM, TLRD); 278 | } else if (STREQ(data[1], "OpenBSD")) { 279 | process_data(data, data_names, openbsd_logo, 23, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 280 | } else if (STREQ(data[1], "NetBSD")) { 281 | process_data(data, data_names, netbsd_logo, 23, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 282 | } else if (STREQ(data[1], "DragonFly BSD")) { 283 | process_data(data, data_names, dragonflybsd_logo, 23, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 284 | } else if (STREQ(data[1], "SunOS")) { 285 | process_data(data, data_names, solaris_logo, 17, DETECTED_ARR_LEN, TNRM, TNRM, TNRM); 286 | } else { 287 | ERR_REPORT("Could not find a logo for the distro."); 288 | } 289 | 290 | return; 291 | } 292 | 293 | /* main_text_output 294 | the secondary output for screenfetch-c - all info WITHOUT ASCII art 295 | arguments char *data[], char *data_names[] 296 | */ 297 | void main_text_output(char *data[], char *data_names[]) { 298 | int i; 299 | 300 | for (i = 0; i < DETECTED_ARR_LEN; i++) 301 | printf("%s %s\n", data_names[i], data[i]); 302 | 303 | return; 304 | } 305 | -------------------------------------------------------------------------------- /src/disp.h: -------------------------------------------------------------------------------- 1 | /* disp.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Function prototypes for disp.c and macros for error/verbose outut. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | ** You should have received a copy of it with this code. 8 | */ 9 | 10 | #ifndef SCREENFETCH_C_DISP_H 11 | #define SCREENFETCH_C_DISP_H 12 | 13 | #include "colors.h" 14 | 15 | void display_version(void); 16 | void display_help(void); 17 | void display_verbose(char *data[], char *data_names[]); 18 | void process_logo_only(char *distro[], unsigned short int num); 19 | void output_logo_only(char *distro); 20 | void process_data(char *data[], char *data_names[], char *logo[], unsigned short int num1, 21 | unsigned short int num2, char *col1, char *col2, char *col3); 22 | void main_ascii_output(char *data[], char *data_names[]); 23 | void main_text_output(char *data[], char *data_names[]); 24 | 25 | #define ERR_REPORT(str) \ 26 | (fprintf(stderr, TWHT "[[ " TLRD "!" TWHT " ]] " TNRM "Error: %s (%s:%d)\n", str, __FILE__, \ 27 | __LINE__)) 28 | #define VERBOSE_OUT(str1, str2) (fprintf(stdout, TLRD ":: " TNRM "%s%s\n", str1, str2)) 29 | 30 | #endif /* SCREENFETCH_C_DISP_H */ 31 | -------------------------------------------------------------------------------- /src/error_flag.c: -------------------------------------------------------------------------------- 1 | /* error_flag.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** screenfetch-c's error flag is initialized in this file. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #include 10 | 11 | bool error = true; 12 | -------------------------------------------------------------------------------- /src/error_flag.h: -------------------------------------------------------------------------------- 1 | /* error_flag.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** screenfetch-c's error flag is externalized in this file. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_ERROR_FLAG_H 10 | #define SCREENFETCH_C_ERROR_FLAG_H 11 | 12 | extern bool error; 13 | 14 | #endif /* SCREENFETCH_C_ERROR_FLAG_H */ 15 | -------------------------------------------------------------------------------- /src/logos.h: -------------------------------------------------------------------------------- 1 | /* logos.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The ASCII logos used by screenfetch-c are externalized in this file. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_LOGOS_H 10 | #define SCREENFETCH_C_LOGOS_H 11 | 12 | extern char *oldarch_logo[]; 13 | extern char *arch_logo[]; 14 | extern char *mint_logo[]; 15 | extern char *lmde_logo[]; 16 | extern char *ubuntu_logo[]; 17 | extern char *debian_logo[]; 18 | extern char *crunchbang_logo[]; 19 | extern char *gentoo_logo[]; 20 | extern char *funtoo_logo[]; 21 | extern char *fedora_logo[]; 22 | extern char *freebsd_logo[]; 23 | extern char *openbsd_logo[]; 24 | extern char *dragonflybsd_logo[]; 25 | extern char *netbsd_logo[]; 26 | extern char *mandriva_mandrake_logo[]; 27 | extern char *opensuse_logo[]; 28 | extern char *slackware_logo[]; 29 | extern char *redhat_logo[]; 30 | extern char *frugalware_logo[]; 31 | extern char *peppermint_logo[]; 32 | extern char *solusos_logo[]; 33 | extern char *mageia_logo[]; 34 | extern char *parabolagnu_linuxlibre_logo[]; 35 | extern char *viperr_logo[]; 36 | extern char *linuxdeepin_logo[]; 37 | extern char *chakra_logo[]; 38 | extern char *fuduntu_logo[]; 39 | extern char *macosx_logo[]; 40 | extern char *windows_logo[]; 41 | extern char *windows_modern_logo[]; 42 | extern char *trisquel_logo[]; 43 | extern char *manjaro_logo[]; 44 | extern char *elementaryos_logo[]; 45 | extern char *scientificlinux_logo[]; 46 | extern char *backtracklinux_logo[]; 47 | extern char *kalilinux_logo[]; 48 | extern char *sabayon_logo[]; 49 | extern char *android_logo[]; 50 | extern char *linux_logo[]; 51 | extern char *solaris_logo[]; 52 | extern char *angstrom_logo[]; 53 | 54 | #endif /* SCREENFETCH_C_LOGOS_H */ 55 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* main.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** screenfetch-c is a rewrite of screenFetch.sh in C. 6 | ** This is primarily an experiment borne out of an awareness of the 7 | ** slow execution time on the screenfetch-dev.sh script. 8 | ** Hopefully this rewrite will execute faster, although it's more for 9 | ** self education than anything else. 10 | ** 11 | ** If you have any questions, please feel free to contact me via: 12 | ** - github: http://www.github.com/woodruffw/screenfetch-c 13 | ** - email: william @ tuffbizz.com 14 | */ 15 | 16 | /* standard includes */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /* program includes */ 24 | #include "arrays.h" 25 | #include "detect.h" 26 | #include "disp.h" 27 | #include "logos.h" 28 | #include "colors.h" 29 | #include "misc.h" 30 | #include "util.h" 31 | #include "error_flag.h" 32 | 33 | int main(int argc, char **argv) { 34 | bool logo = true, portrait = false; 35 | bool verbose = false, screenshot = false; 36 | 37 | struct option options[] = { 38 | {"verbose", no_argument, 0, 'v'}, {"no-logo", no_argument, 0, 'n'}, 39 | {"screenshot", no_argument, 0, 's'}, {"distro", required_argument, 0, 'D'}, 40 | {"suppress-errors", no_argument, 0, 'E'}, {"portrait", no_argument, 0, 'p'}, 41 | {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, 42 | {"logo-only", required_argument, 0, 'L'}, {0, 0, 0, 0}}; 43 | 44 | signed char c; 45 | int index = 0; 46 | while ((c = getopt_long(argc, argv, "vnsD:EpVhL:", options, &index)) != -1) { 47 | switch (c) { 48 | case 'v': 49 | verbose = true; 50 | break; 51 | case 'n': 52 | logo = false; 53 | break; 54 | case 's': 55 | screenshot = true; 56 | break; 57 | case 'D': 58 | SET_GIVEN_DISTRO(optarg); 59 | break; 60 | case 'E': 61 | error = false; 62 | break; 63 | case 'p': 64 | portrait = true; 65 | break; 66 | case 'V': 67 | display_version(); 68 | return EXIT_SUCCESS; 69 | case 'h': 70 | display_help(); 71 | return EXIT_SUCCESS; 72 | case 'L': 73 | output_logo_only(optarg); 74 | return EXIT_SUCCESS; 75 | default: 76 | return EXIT_FAILURE; 77 | } 78 | } 79 | 80 | detect_distro(); 81 | detect_host(); 82 | detect_kernel(); 83 | detect_uptime(); 84 | detect_pkgs(); 85 | detect_cpu(); 86 | detect_gpu(); 87 | detect_disk(); 88 | detect_mem(); 89 | detect_shell(); 90 | detect_res(); 91 | detect_de(); 92 | detect_wm(); 93 | detect_wm_theme(); 94 | detect_gtk(); 95 | 96 | /* if the user specified a different OS to display, set distro_set to it */ 97 | if (!STREQ(given_distro_str, "Unknown")) 98 | safe_strncpy(distro_str, given_distro_str, MAX_STRLEN); 99 | 100 | if (verbose) 101 | display_verbose(detected_arr, detected_arr_names); 102 | 103 | if (portrait) { 104 | output_logo_only(distro_str); 105 | main_text_output(detected_arr, detected_arr_names); 106 | } else if (logo) 107 | main_ascii_output(detected_arr, detected_arr_names); 108 | else 109 | main_text_output(detected_arr, detected_arr_names); 110 | 111 | if (screenshot) 112 | take_screenshot(verbose); 113 | 114 | return EXIT_SUCCESS; 115 | } 116 | -------------------------------------------------------------------------------- /src/misc.h: -------------------------------------------------------------------------------- 1 | /* misc.h 2 | ** Author: William Woodruff 3 | ** 4 | ** Miscellaneous macros used in screenfetch-c. 5 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 6 | */ 7 | 8 | #ifndef SCREENFETCH_C_MISC_H 9 | #define SCREENFETCH_C_MISC_H 10 | 11 | #define KB (1024) 12 | #define MB (KB * KB) 13 | #define GB (MB * KB) 14 | #define MAX_STRLEN 512 15 | #define SET_GIVEN_DISTRO(str) (safe_strncpy(given_distro_str, str, MAX_STRLEN)) 16 | #define STREQ(x, y) (!strcmp(x, y)) 17 | #define STRCASEEQ(x, y) (!strcasecmp(x, y)) 18 | #define BEGINS_WITH(x, y) (!strncmp(x, y, strlen(y))) 19 | #define FILE_EXISTS(file) (!access(file, F_OK)) 20 | 21 | #endif /* SCREENFETCH_C_MISC_H */ 22 | -------------------------------------------------------------------------------- /src/plat/bsd/detect.c: -------------------------------------------------------------------------------- 1 | /* detect.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c on *BSD are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* BSD-specific includes */ 18 | #include 19 | #include 20 | #if defined(__FreeBSD__) 21 | #include 22 | #elif defined(__NetBSD__) 23 | #elif defined(__OpenBSD__) 24 | #include 25 | #elif defined(__DragonFly__) 26 | #include 27 | #endif 28 | 29 | /* program includes */ 30 | #include "../../arrays.h" 31 | #include "../../colors.h" 32 | #include "../../misc.h" 33 | #include "../../disp.h" 34 | #include "../../util.h" 35 | #include "../../error_flag.h" 36 | 37 | /* detect_distro 38 | detects the computer's distribution 39 | */ 40 | void detect_distro(void) { 41 | struct utsname distro_info; 42 | 43 | uname(&distro_info); 44 | snprintf(distro_str, MAX_STRLEN, "%s", distro_info.sysname); 45 | 46 | #if defined(__FreeBSD__) 47 | safe_strncpy(host_color, TLRD, MAX_STRLEN); 48 | #endif 49 | 50 | return; 51 | } 52 | 53 | /* detect_host 54 | detects the computer's hostname and active user and formats them 55 | */ 56 | void detect_host(void) { 57 | char *given_user = "Unknown"; 58 | char given_host[MAX_STRLEN] = "Unknown"; 59 | struct utsname host_info; 60 | 61 | given_user = getlogin(); 62 | uname(&host_info); 63 | safe_strncpy(given_host, host_info.nodename, MAX_STRLEN); 64 | 65 | snprintf(host_str, MAX_STRLEN, "%s%s%s%s@%s%s%s%s", host_color, given_user, TNRM, TWHT, TNRM, 66 | host_color, given_host, TNRM); 67 | 68 | return; 69 | } 70 | 71 | /* detect_kernel 72 | detects the computer's kernel 73 | */ 74 | void detect_kernel(void) { 75 | struct utsname kern_info; 76 | 77 | uname(&kern_info); 78 | snprintf(kernel_str, MAX_STRLEN, "%s", kern_info.release); 79 | 80 | return; 81 | } 82 | 83 | /* detect_uptime 84 | detects the computer's uptime 85 | */ 86 | void detect_uptime(void) { 87 | long uptime = 0; 88 | #if !defined(__NetBSD__) 89 | long currtime = 0, boottime = 0; 90 | #endif 91 | FILE *uptime_file; 92 | unsigned int secs = 0; 93 | unsigned int mins = 0; 94 | unsigned int hrs = 0; 95 | unsigned int days = 0; 96 | 97 | #if defined(__NetBSD__) 98 | uptime_file = popen("cut -d ' ' -f 1 < /proc/uptime", "r"); 99 | fscanf(uptime_file, "%ld", &uptime); 100 | pclose(uptime_file); 101 | #elif defined(__FreeBSD__) || defined(__DragonFly__) 102 | uptime_file = popen("sysctl -n kern.boottime | cut -d '=' -f 2 | " 103 | "cut -d ',' -f 1", 104 | "r"); 105 | fscanf(uptime_file, "%ld", &boottime); /* get boottime in secs */ 106 | pclose(uptime_file); 107 | 108 | currtime = time(NULL); 109 | 110 | uptime = currtime - boottime; 111 | #elif defined(__OpenBSD__) 112 | uptime_file = popen("sysctl -n kern.boottime", "r"); 113 | fscanf(uptime_file, "%ld", &boottime); /* get boottime in secs */ 114 | pclose(uptime_file); 115 | 116 | currtime = time(NULL); 117 | 118 | uptime = currtime - boottime; 119 | #endif 120 | 121 | split_uptime(uptime, &secs, &mins, &hrs, &days); 122 | 123 | if (days > 0) 124 | snprintf(uptime_str, MAX_STRLEN, "%dd %dh %dm %ds", days, hrs, mins, secs); 125 | else 126 | snprintf(uptime_str, MAX_STRLEN, "%dh %dm %ds", hrs, mins, secs); 127 | 128 | return; 129 | } 130 | 131 | /* detect_pkgs 132 | detects the number of packages installed on the computer 133 | */ 134 | void detect_pkgs(void) { 135 | int packages = 0; 136 | #if defined(__FreeBSD__) || defined(__OpenBSD__) 137 | FILE *pkgs_file; 138 | #endif 139 | 140 | #if defined(__FreeBSD__) 141 | pkgs_file = popen("pkg info | wc -l", "r"); 142 | fscanf(pkgs_file, "%d", &packages); 143 | pclose(pkgs_file); 144 | #elif defined(__OpenBSD__) 145 | pkgs_file = popen("pkg_info | wc -l", "r"); 146 | fscanf(pkgs_file, "%d", &packages); 147 | pclose(pkgs_file); 148 | #else 149 | safe_strncpy(pkgs_str, "Not Found", MAX_STRLEN); 150 | 151 | if (error) 152 | ERR_REPORT("Could not find packages on current OS."); 153 | #endif 154 | 155 | snprintf(pkgs_str, MAX_STRLEN, "%d", packages); 156 | 157 | return; 158 | } 159 | 160 | /* detect_cpu 161 | detects the computer's CPU brand/name-string 162 | */ 163 | void detect_cpu(void) { 164 | FILE *cpu_file; 165 | 166 | #if defined(__NetBSD__) 167 | cpu_file = popen("awk 'BEGIN{FS=\":\"} /model name/ { print $2; exit }' " 168 | "/proc/cpuinfo | sed -e 's/ @/\\n/' -e 's/^ *//g' -e 's/ *$//g' " 169 | "| head -1 | tr -d '\\n'", 170 | "r"); 171 | fgets(cpu_str, MAX_STRLEN, cpu_file); 172 | pclose(cpu_file); 173 | #else 174 | cpu_file = popen("sysctl -n hw.model | tr -d '\\n'", "r"); 175 | fgets(cpu_str, MAX_STRLEN, cpu_file); 176 | pclose(cpu_file); 177 | #endif 178 | 179 | return; 180 | } 181 | 182 | /* detect_gpu 183 | detects the computer's GPU brand/name-string 184 | */ 185 | void detect_gpu(void) { 186 | FILE *gpu_file; 187 | 188 | gpu_file = popen("detectgpu 2>/dev/null", "r"); 189 | fgets(gpu_str, MAX_STRLEN, gpu_file); 190 | pclose(gpu_file); 191 | 192 | return; 193 | } 194 | 195 | /* detect_disk 196 | detects the computer's total disk capacity and usage 197 | */ 198 | void detect_disk(void) { 199 | struct statvfs disk_info; 200 | unsigned long disk_total = 0, disk_used = 0, disk_percentage = 0; 201 | 202 | if (!(statvfs(getenv("HOME"), &disk_info))) { 203 | disk_total = ((disk_info.f_blocks * disk_info.f_bsize) / GB); 204 | disk_used = (((disk_info.f_blocks - disk_info.f_bfree) * disk_info.f_bsize) / GB); 205 | disk_percentage = (((float)disk_used / disk_total) * 100); 206 | snprintf(disk_str, MAX_STRLEN, "%ldG / %ldG (%ld%%)", disk_used, disk_total, disk_percentage); 207 | } else if (error) { 208 | ERR_REPORT("Could not stat $HOME for filesystem statistics."); 209 | } 210 | 211 | return; 212 | } 213 | 214 | /* detect_mem 215 | detects the computer's total and used RAM 216 | */ 217 | void detect_mem(void) { 218 | FILE *mem_file; 219 | long long total_mem = 0; 220 | 221 | mem_file = popen("sysctl -n hw.physmem", "r"); 222 | fscanf(mem_file, "%lld", &total_mem); 223 | pclose(mem_file); 224 | 225 | total_mem /= (long)MB; 226 | 227 | snprintf(mem_str, MAX_STRLEN, "%lld%s", total_mem, "MB"); 228 | 229 | return; 230 | } 231 | 232 | /* detect_shell 233 | detects the shell currently running on the computer 234 | -- 235 | CAVEAT: shell version detection relies on the standard versioning format for 236 | each shell. If any shell's older (or newer versions) suddenly begin to use a new 237 | scheme, the version may be displayed incorrectly. 238 | -- 239 | */ 240 | void detect_shell(void) { 241 | FILE *shell_file; 242 | char *shell_name; 243 | char vers_str[MAX_STRLEN]; 244 | 245 | shell_name = getenv("SHELL"); 246 | 247 | if (shell_name == NULL) { 248 | if (error) 249 | ERR_REPORT("Could not detect a shell."); 250 | 251 | return; 252 | } 253 | 254 | if (STREQ(shell_name, "/bin/sh")) { 255 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 256 | } else if (strstr(shell_name, "bash")) { 257 | shell_file = popen("bash --version | head -1", "r"); 258 | fgets(vers_str, MAX_STRLEN, shell_file); 259 | snprintf(shell_str, MAX_STRLEN, "bash %.*s", 17, vers_str + 10); 260 | pclose(shell_file); 261 | } else if (strstr(shell_name, "zsh")) { 262 | shell_file = popen("zsh --version", "r"); 263 | fgets(vers_str, MAX_STRLEN, shell_file); 264 | snprintf(shell_str, MAX_STRLEN, "zsh %.*s", 5, vers_str + 4); 265 | pclose(shell_file); 266 | } else if (strstr(shell_name, "csh")) { 267 | shell_file = popen("csh --version | head -1", "r"); 268 | fgets(vers_str, MAX_STRLEN, shell_file); 269 | snprintf(shell_str, MAX_STRLEN, "csh %.*s", 7, vers_str + 5); 270 | pclose(shell_file); 271 | } else if (strstr(shell_name, "fish")) { 272 | shell_file = popen("fish --version", "r"); 273 | fgets(vers_str, MAX_STRLEN, shell_file); 274 | snprintf(shell_str, MAX_STRLEN, "fish %.*s", 13, vers_str + 6); 275 | pclose(shell_file); 276 | } else if (strstr(shell_name, "dash") || strstr(shell_name, "ash") || strstr(shell_name, "ksh")) { 277 | /* i don't have a version detection system for these, yet */ 278 | safe_strncpy(shell_str, shell_name, MAX_STRLEN); 279 | } 280 | 281 | return; 282 | } 283 | 284 | /* detect_res 285 | detects the combined resolution of all monitors attached to the computer 286 | */ 287 | void detect_res(void) { 288 | FILE *res_file; 289 | 290 | res_file = popen("xdpyinfo 2> /dev/null | sed -n 's/.*dim.* " 291 | "\\([0-9]*x[0-9]*\\) .*/\\1/pg' | tr '\\n' ' '", 292 | "r"); 293 | fgets(res_str, MAX_STRLEN, res_file); 294 | pclose(res_file); 295 | 296 | if (STREQ(res_str, "Unknown")) { 297 | safe_strncpy(res_str, "No X Server", MAX_STRLEN); 298 | } 299 | 300 | return; 301 | } 302 | 303 | /* detect_de 304 | detects the desktop environment currently running on top of the OS 305 | -- 306 | CAVEAT: This function relies on the presence of 'detectde', a shell script. 307 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 308 | -- 309 | */ 310 | void detect_de(void) { 311 | char *curr_de; 312 | 313 | if ((curr_de = getenv("XDG_CURRENT_DESKTOP"))) { 314 | safe_strncpy(de_str, curr_de, MAX_STRLEN); 315 | } else { 316 | if (getenv("GNOME_DESKTOP_SESSION_ID")) { 317 | safe_strncpy(de_str, "Gnome", MAX_STRLEN); 318 | } else if (getenv("MATE_DESKTOP_SESSION_ID")) { 319 | safe_strncpy(de_str, "MATE", MAX_STRLEN); 320 | } else if (getenv("KDE_FULL_SESSION")) { 321 | /* KDE_SESSION_VERSION only exists on KDE4+, so 322 | getenv will return NULL on KDE <= 3. 323 | */ 324 | snprintf(de_str, MAX_STRLEN, "KDE%s", getenv("KDE_SESSION_VERSION")); 325 | } else if (error) { 326 | ERR_REPORT("No desktop environment found."); 327 | } 328 | } 329 | 330 | return; 331 | } 332 | 333 | /* detect_wm 334 | detects the window manager currently running on top of the OS 335 | -- 336 | CAVEAT: This function relies on the presence of 'detectwm', a shell script. 337 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 338 | -- 339 | */ 340 | void detect_wm(void) { 341 | FILE *wm_file; 342 | 343 | wm_file = popen("detectwm 2> /dev/null", "r"); 344 | fgets(wm_str, MAX_STRLEN, wm_file); 345 | pclose(wm_file); 346 | 347 | return; 348 | } 349 | 350 | /* detect_wm_theme 351 | detects the theme associated with the WM detected in detect_wm() 352 | -- 353 | CAVEAT: This function relies on the presence of 'detectwmtheme', a shell script. 354 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 355 | -- 356 | */ 357 | void detect_wm_theme(void) { 358 | char exec_str[MAX_STRLEN]; 359 | FILE *wm_theme_file; 360 | 361 | snprintf(exec_str, MAX_STRLEN, "detectwmtheme %s 2> /dev/null", wm_str); 362 | 363 | wm_theme_file = popen(exec_str, "r"); 364 | fgets(wm_theme_str, MAX_STRLEN, wm_theme_file); 365 | pclose(wm_theme_file); 366 | 367 | return; 368 | } 369 | 370 | /* detect_gtk 371 | detects the theme, icon(s), and font(s) associated with a GTK DE (if present) 372 | -- 373 | CAVEAT: This function relies on the presence of 'detectgtk', a shell script. 374 | If it isn't present somewhere in the PATH, the GTK will be set as 'Unknown' 375 | -- 376 | */ 377 | void detect_gtk(void) { 378 | FILE *gtk_file; 379 | char gtk2_str[MAX_STRLEN] = "Unknown"; 380 | char gtk3_str[MAX_STRLEN] = "Unknown"; 381 | char gtk_icons_str[MAX_STRLEN] = "Unknown"; 382 | char gtk_font_str[MAX_STRLEN] = "Unknown"; 383 | 384 | gtk_file = popen("detectgtk 2> /dev/null", "r"); 385 | fscanf(gtk_file, "%s%s%s%s", gtk2_str, gtk3_str, gtk_icons_str, gtk_font_str); 386 | pclose(gtk_file); 387 | 388 | if (STREQ(gtk2_str, gtk3_str)) { 389 | if (STREQ(gtk2_str, "Unknown")) 390 | safe_strncpy(gtk_str, gtk2_str, MAX_STRLEN); 391 | else 392 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK2/3)", gtk2_str); 393 | } else if (STREQ(gtk2_str, "Unknown") && !STREQ(gtk3_str, "Unknown")) 394 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK3)", gtk3_str); 395 | else if (STREQ(gtk3_str, "Unknown") && !STREQ(gtk2_str, "Unknown")) 396 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK2)", gtk2_str); 397 | else 398 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK2), %s (GTK3)", gtk2_str, gtk3_str); 399 | 400 | snprintf(icon_str, MAX_STRLEN, "%s", gtk_icons_str); 401 | 402 | snprintf(font_str, MAX_STRLEN, "%s", gtk_font_str); 403 | 404 | return; 405 | } 406 | -------------------------------------------------------------------------------- /src/plat/darwin/detect.c: -------------------------------------------------------------------------------- 1 | /* detect.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c on OS X (Darwin) are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* OS X-specific includes */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /* program includes */ 36 | #include "../../arrays.h" 37 | #include "../../colors.h" 38 | #include "../../misc.h" 39 | #include "../../disp.h" 40 | #include "../../util.h" 41 | #include "../../error_flag.h" 42 | 43 | /* detect_distro 44 | detects the computer's distribution (OS X release) 45 | */ 46 | void detect_distro(void) { 47 | char *codenames[] = {"Cheetah", "Puma", "Jaguar", "Panther", 48 | "Tiger", "Leopard", "Snow Leopard", "Lion", 49 | "Mountain Lion", "Mavericks", "Yosemite", "El Capitan", 50 | "Sierra", "High Sierra", "Mojave", "Catalina"}; 51 | CFArrayRef split = CFStringCreateArrayBySeparatingStrings( 52 | NULL, 53 | CFPreferencesCopyAppValue(CFSTR("ProductVersion"), 54 | CFSTR("/System/Library/CoreServices/SystemVersion")), 55 | CFSTR(".")); 56 | unsigned maj = CFStringGetIntValue(CFArrayGetValueAtIndex(split, 0)); 57 | unsigned min = CFStringGetIntValue(CFArrayGetValueAtIndex(split, 1)); 58 | unsigned fix = 0; 59 | if (CFArrayGetCount(split) == 3) { 60 | fix = CFStringGetIntValue(CFArrayGetValueAtIndex(split, 2)); 61 | } 62 | 63 | char build_ver[16]; 64 | CFStringGetCString(CFPreferencesCopyAppValue(CFSTR("ProductBuildVersion"), 65 | CFSTR("/System/Library/CoreServices/SystemVersion")), 66 | build_ver, 16, kCFStringEncodingUTF8); 67 | 68 | char *codename = "Mac OS"; 69 | char buf[128]; 70 | if (min < sizeof(codenames) / sizeof(*codenames)) { 71 | snprintf(buf, sizeof(buf), "%s %s", min < 8 ? "Mac OS X" : min < 12 ? "OS X" : "macOS", 72 | codenames[min]); 73 | codename = buf; 74 | } else { 75 | char *lookfor = "SOFTWARE LICENSE AGREEMENT FOR "; 76 | FILE *fp = fopen("/System/Library/CoreServices/Setup " 77 | "Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf", 78 | "r"); 79 | if (fp != NULL) { 80 | for (int i = 0; i < 50 && fgets(buf, sizeof(buf), fp); ++i) { 81 | char *p = strstr(buf, lookfor); 82 | if (p) { 83 | codename = p + strlen(lookfor); 84 | codename[strlen(p) - strlen(lookfor) - 1] = '\0'; 85 | break; 86 | } 87 | } 88 | fclose(fp); 89 | } 90 | } 91 | 92 | snprintf(distro_str, MAX_STRLEN, "%s %d.%d.%d (%s)", codename, maj, min, fix, build_ver); 93 | safe_strncpy(host_color, TLBL, MAX_STRLEN); 94 | 95 | return; 96 | } 97 | 98 | /* detect_host 99 | detects the computer's hostname and active user and formats them 100 | */ 101 | void detect_host(void) { 102 | char *given_user = "Unknown"; 103 | char given_host[MAX_STRLEN] = "Unknown"; 104 | struct utsname host_info; 105 | 106 | given_user = getlogin(); 107 | uname(&host_info); 108 | safe_strncpy(given_host, host_info.nodename, MAX_STRLEN); 109 | 110 | snprintf(host_str, MAX_STRLEN, "%s%s%s%s@%s%s%s%s", host_color, given_user, TNRM, TWHT, TNRM, 111 | host_color, given_host, TNRM); 112 | 113 | return; 114 | } 115 | 116 | /* detect_kernel 117 | detects the computer's kernel 118 | */ 119 | void detect_kernel(void) { 120 | struct utsname kern_info; 121 | 122 | uname(&kern_info); 123 | snprintf(kernel_str, MAX_STRLEN, "%s %s %s", kern_info.sysname, kern_info.release, 124 | kern_info.machine); 125 | 126 | return; 127 | } 128 | 129 | /* detect_uptime 130 | detects the computer's uptime 131 | */ 132 | void detect_uptime(void) { 133 | long long uptime = 0; 134 | unsigned int secs = 0; 135 | unsigned int mins = 0; 136 | unsigned int hrs = 0; 137 | unsigned int days = 0; 138 | 139 | /* three cheers for undocumented functions and structs */ 140 | static mach_timebase_info_data_t timebase_info; 141 | 142 | if (timebase_info.denom == 0) { 143 | (void)mach_timebase_info(&timebase_info); 144 | } 145 | 146 | uptime = (long long)((mach_absolute_time() * timebase_info.numer) / 147 | (1000 * 1000 * timebase_info.denom)); 148 | uptime /= 1000; 149 | 150 | split_uptime(uptime, &secs, &mins, &hrs, &days); 151 | 152 | if (days > 0) 153 | snprintf(uptime_str, MAX_STRLEN, "%dd %dh %dm %ds", days, hrs, mins, secs); 154 | else 155 | snprintf(uptime_str, MAX_STRLEN, "%dh %dm %ds", hrs, mins, secs); 156 | 157 | return; 158 | } 159 | 160 | /* detect_pkgs 161 | detects the number of packages installed on the computer 162 | */ 163 | void detect_pkgs(void) { 164 | int packages = 0; 165 | glob_t gl; 166 | 167 | if (glob("/usr/local/Cellar/*", GLOB_NOSORT, NULL, &gl) == 0) { 168 | packages = gl.gl_pathc; 169 | } else if (error) { 170 | ERR_REPORT("Failure while globbing packages."); 171 | } 172 | 173 | globfree(&gl); 174 | 175 | snprintf(pkgs_str, MAX_STRLEN, "%d", packages); 176 | 177 | return; 178 | } 179 | 180 | /* detect_cpu 181 | detects the computer's CPU brand/name-string 182 | */ 183 | void detect_cpu(void) { 184 | size_t size = MAX_STRLEN; 185 | sysctlbyname("machdep.cpu.brand_string", cpu_str, &size, NULL, 0); 186 | return; 187 | } 188 | 189 | /* detect_gpu 190 | detects the computer's GPU brand/name-string 191 | */ 192 | void detect_gpu(void) { 193 | CFMutableDictionaryRef matchDict = IOServiceMatching("IOPCIDevice"); 194 | io_iterator_t iterator; 195 | if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchDict, &iterator) == 196 | kIOReturnSuccess) { 197 | io_registry_entry_t regEntry; 198 | while ((regEntry = IOIteratorNext(iterator))) { 199 | CFMutableDictionaryRef serviceDictionary; 200 | if (IORegistryEntryCreateCFProperties(regEntry, &serviceDictionary, kCFAllocatorDefault, 201 | kNilOptions) != kIOReturnSuccess) { 202 | IOObjectRelease(regEntry); 203 | continue; 204 | } 205 | const void *GPUModel = CFDictionaryGetValue(serviceDictionary, CFSTR("model")); 206 | if (GPUModel && CFGetTypeID(GPUModel) == CFDataGetTypeID()) 207 | safe_strncpy(gpu_str, (char *)CFDataGetBytePtr((CFDataRef)GPUModel), MAX_STRLEN); 208 | CFRelease(serviceDictionary); 209 | IOObjectRelease(regEntry); 210 | } 211 | IOObjectRelease(iterator); 212 | } 213 | 214 | return; 215 | } 216 | 217 | /* detect_disk 218 | detects the computer's total disk capacity and usage 219 | */ 220 | void detect_disk(void) { 221 | struct statfs disk_info; 222 | long disk_total = 0, disk_used = 0, disk_percentage = 0; 223 | 224 | if (!(statfs(getenv("HOME"), &disk_info))) { 225 | disk_total = ((disk_info.f_blocks * disk_info.f_bsize) / GB); 226 | disk_used = (((disk_info.f_blocks - disk_info.f_bfree) * disk_info.f_bsize) / GB); 227 | disk_percentage = (((float)disk_used / disk_total) * 100); 228 | snprintf(disk_str, MAX_STRLEN, "%ldG / %ldG (%ld%%)", disk_used, disk_total, disk_percentage); 229 | } else if (error) { 230 | ERR_REPORT("Could not stat $HOME for filesystem statistics."); 231 | } 232 | 233 | return; 234 | } 235 | 236 | /* detect_mem 237 | detects the computer's total and used RAM 238 | */ 239 | void detect_mem(void) { 240 | int64_t used_mem = 0, total_mem = 0; 241 | vm_size_t page_size; 242 | mach_port_t mach_port; 243 | mach_msg_type_number_t count; 244 | vm_statistics64_data_t vm_stats; 245 | mach_port = mach_host_self(); 246 | count = sizeof(vm_stats) / sizeof(natural_t); 247 | if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && 248 | KERN_SUCCESS == 249 | host_statistics64(mach_port, HOST_VM_INFO, (host_info64_t)&vm_stats, &count)) { 250 | used_mem = ((int64_t)vm_stats.active_count + (int64_t)vm_stats.wire_count) * (int64_t)page_size; 251 | } 252 | 253 | size_t len = sizeof(total_mem); 254 | sysctlbyname("hw.memsize", &total_mem, &len, NULL, 0); 255 | 256 | snprintf(mem_str, MAX_STRLEN, "%lld%s / %lld%s", used_mem / MB, "MB", total_mem / MB, "MB"); 257 | 258 | return; 259 | } 260 | 261 | /* detect_shell 262 | detects the shell currently running on the computer 263 | -- 264 | CAVEAT: shell version detection relies on the standard versioning format for 265 | each shell. If any shell's older (or newer versions) suddenly begin to use a 266 | new scheme, the version may be displayed incorrectly. 267 | -- 268 | */ 269 | void detect_shell(void) { 270 | FILE *shell_file; 271 | char *shell_name; 272 | char vers_str[MAX_STRLEN]; 273 | 274 | shell_name = getenv("SHELL"); 275 | 276 | if (shell_name == NULL) { 277 | if (error) 278 | ERR_REPORT("Could not detect a shell."); 279 | 280 | return; 281 | } 282 | 283 | if (STREQ(shell_name, "/bin/sh")) { 284 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 285 | } else if (strstr(shell_name, "bash")) { 286 | shell_file = popen("bash --version | head -1", "r"); 287 | fgets(vers_str, MAX_STRLEN, shell_file); 288 | snprintf(shell_str, MAX_STRLEN, "bash %.*s", 17, vers_str + 10); 289 | pclose(shell_file); 290 | } else if (strstr(shell_name, "zsh")) { 291 | shell_file = popen("zsh --version", "r"); 292 | fgets(vers_str, MAX_STRLEN, shell_file); 293 | snprintf(shell_str, MAX_STRLEN, "zsh %.*s", 5, vers_str + 4); 294 | pclose(shell_file); 295 | } else if (strstr(shell_name, "csh")) { 296 | shell_file = popen("csh --version | head -1", "r"); 297 | fgets(vers_str, MAX_STRLEN, shell_file); 298 | snprintf(shell_str, MAX_STRLEN, "csh %.*s", 7, vers_str + 5); 299 | pclose(shell_file); 300 | } else if (strstr(shell_name, "fish")) { 301 | shell_file = popen("fish --version", "r"); 302 | fgets(vers_str, MAX_STRLEN, shell_file); 303 | snprintf(shell_str, MAX_STRLEN, "fish %.*s", 13, vers_str + 6); 304 | pclose(shell_file); 305 | } else if (strstr(shell_name, "dash") || strstr(shell_name, "ash") || strstr(shell_name, "ksh")) { 306 | /* i don't have a version detection system for these, yet */ 307 | safe_strncpy(shell_str, shell_name, MAX_STRLEN); 308 | } 309 | 310 | return; 311 | } 312 | 313 | /* detect_res 314 | detects the combined resolution of all monitors attached to the computer 315 | */ 316 | void detect_res(void) { 317 | uint32_t count = 0, chars = 0; 318 | CGGetOnlineDisplayList(UINT32_MAX, NULL, &count); 319 | CGDirectDisplayID displays[count]; 320 | CGGetOnlineDisplayList(count, displays, &count); 321 | chars += snprintf(res_str, MAX_STRLEN, "%zu x %zu", CGDisplayPixelsWide(*displays), 322 | CGDisplayPixelsHigh(*displays)); 323 | for (int i = 1; i < count; ++i) { 324 | chars += snprintf(res_str + chars, MAX_STRLEN, ", %zu x %zu", CGDisplayPixelsWide(displays[i]), 325 | CGDisplayPixelsHigh(displays[i])); 326 | } 327 | return; 328 | } 329 | 330 | /* detect_de 331 | detects the desktop environment currently running on top of the OS. 332 | On OS X, this will always be Aqua. 333 | */ 334 | void detect_de(void) { 335 | safe_strncpy(de_str, "Aqua", MAX_STRLEN); 336 | 337 | return; 338 | } 339 | 340 | /* detect_wm 341 | detects the window manager currently running on top of the OS. 342 | On OS X, this will always be the Quartz Compositor. 343 | */ 344 | void detect_wm(void) { 345 | safe_strncpy(wm_str, "Quartz Compositor", MAX_STRLEN); 346 | 347 | return; 348 | } 349 | 350 | /* detect_wm_theme 351 | detects the theme associated with the WM detected in detect_wm(). 352 | On OS X, there are dark and light theme, and various accent colours. 353 | */ 354 | void detect_wm_theme(void) { 355 | char *accents[] = {"Graphite", "Red", "Orange", "Yellow", "Green", "", "Purple", "Pink", "Blue"}; 356 | char *color; 357 | Boolean accentExists; 358 | CFStringRef def = CFSTR(".GlobalPreferences"); 359 | CFIndex accentColor = 360 | CFPreferencesGetAppIntegerValue(CFSTR("AppleAccentColor"), def, &accentExists); 361 | CFIndex aquaColorVariant = 362 | CFPreferencesGetAppIntegerValue(CFSTR("AppleAquaColorVariant"), def, NULL); 363 | CFPropertyListRef style = CFPreferencesCopyAppValue(CFSTR("AppleInterfaceStyle"), def); 364 | if (accentExists) { 365 | color = accents[accentColor + 1]; 366 | } else if (aquaColorVariant == 6) { 367 | color = "Graphite"; 368 | } else { 369 | color = "Blue"; 370 | } 371 | snprintf(wm_theme_str, MAX_STRLEN, "%s %s", style ? "Dark" : "Light", color); 372 | return; 373 | } 374 | 375 | /* detect_gtk 376 | OS X doesn't use GTK, so this function fills str with "Not Applicable" 377 | */ 378 | void detect_gtk(void) { 379 | safe_strncpy(gtk_str, "Not Applicable", MAX_STRLEN); 380 | 381 | return; 382 | } 383 | -------------------------------------------------------------------------------- /src/plat/linux/detect.c: -------------------------------------------------------------------------------- 1 | /* detect.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c on Linux are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* linux-specific includes */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | /* program includes */ 32 | #include "../../arrays.h" 33 | #include "../../colors.h" 34 | #include "../../misc.h" 35 | #include "../../disp.h" 36 | #include "../../util.h" 37 | #include "../../error_flag.h" 38 | 39 | /* remove preceding and trailing single quote character, 40 | remove trailing newline 41 | */ 42 | static void unquote(char *s) { 43 | int len = strlen(s); 44 | 45 | if (s[len - 1] == '\n') { 46 | s[len - 1] = '\0'; 47 | len--; 48 | } 49 | if (s[len - 1] == '\'') { 50 | s[len - 1] = '\0'; 51 | len--; 52 | } 53 | if (s[0] == '\'') { 54 | memmove(s, s + 1, len); 55 | } 56 | } 57 | 58 | /* detect_distro 59 | detects the computer's distribution (really only relevant on Linux) 60 | */ 61 | void detect_distro(void) { 62 | /* if distro_str was NOT set by the -D flag */ 63 | if (STREQ(distro_str, "Unknown")) { 64 | FILE *distro_file; 65 | 66 | char distro_name_str[MAX_STRLEN]; 67 | 68 | if (FILE_EXISTS("/system/bin/getprop")) { 69 | safe_strncpy(distro_str, "Android", MAX_STRLEN); 70 | safe_strncpy(host_color, TLGN, MAX_STRLEN); 71 | } else { 72 | bool detected = false; 73 | 74 | /* Bad solution, as /etc/issue contains junk on some distros */ 75 | distro_file = fopen("/etc/issue", "r"); 76 | 77 | if (distro_file != NULL) { 78 | /* get the first 4 chars, that's all we need */ 79 | fscanf(distro_file, "%4s", distro_name_str); 80 | fclose(distro_file); 81 | 82 | if (STREQ(distro_name_str, "Kali")) { 83 | safe_strncpy(distro_str, "Kali Linux", MAX_STRLEN); 84 | detected = true; 85 | safe_strncpy(host_color, TLBL, MAX_STRLEN); 86 | } else if (STREQ(distro_name_str, "Back")) { 87 | safe_strncpy(distro_str, "Backtrack Linux", MAX_STRLEN); 88 | detected = true; 89 | safe_strncpy(host_color, TLRD, MAX_STRLEN); 90 | } else if (STREQ(distro_name_str, "Crun")) { 91 | safe_strncpy(distro_str, "CrunchBang", MAX_STRLEN); 92 | detected = true; 93 | safe_strncpy(host_color, TDGY, MAX_STRLEN); 94 | } else if (STREQ(distro_name_str, "LMDE")) { 95 | safe_strncpy(distro_str, "LMDE", MAX_STRLEN); 96 | detected = true; 97 | safe_strncpy(host_color, TLGN, MAX_STRLEN); 98 | } else if (STREQ(distro_name_str, "Debi") || STREQ(distro_name_str, "Rasp")) { 99 | safe_strncpy(distro_str, "Debian", MAX_STRLEN); 100 | detected = true; 101 | safe_strncpy(host_color, TLRD, MAX_STRLEN); 102 | } 103 | } 104 | 105 | if (!detected) { 106 | if (FILE_EXISTS("/etc/redhat-release")) { 107 | safe_strncpy(distro_str, "Red Hat Linux", MAX_STRLEN); 108 | safe_strncpy(host_color, TLRD, MAX_STRLEN); 109 | } else if (FILE_EXISTS("/etc/fedora-release")) { 110 | safe_strncpy(distro_str, "Fedora", MAX_STRLEN); 111 | safe_strncpy(host_color, TLBL, MAX_STRLEN); 112 | } else if (FILE_EXISTS("/etc/SuSE-release")) { 113 | safe_strncpy(distro_str, "OpenSUSE", MAX_STRLEN); 114 | safe_strncpy(host_color, TLGN, MAX_STRLEN); 115 | } else if (FILE_EXISTS("/etc/arch-release")) { 116 | safe_strncpy(distro_str, "Arch Linux", MAX_STRLEN); 117 | safe_strncpy(host_color, TLCY, MAX_STRLEN); 118 | } else if (FILE_EXISTS("/etc/gentoo-release")) { 119 | safe_strncpy(distro_str, "Gentoo", MAX_STRLEN); 120 | safe_strncpy(host_color, TLPR, MAX_STRLEN); 121 | } else if (FILE_EXISTS("/etc/angstrom-version")) { 122 | safe_strncpy(distro_str, "Angstrom", MAX_STRLEN); 123 | safe_strncpy(host_color, TNRM, MAX_STRLEN); 124 | } else if (FILE_EXISTS("/etc/manjaro-release")) { 125 | safe_strncpy(distro_str, "Manjaro", MAX_STRLEN); 126 | safe_strncpy(host_color, TLGN, MAX_STRLEN); 127 | } else if (FILE_EXISTS("/etc/slackware-release")) { 128 | safe_strncpy(distro_str, "Slackware", MAX_STRLEN); 129 | safe_strncpy(host_color, TLBL, MAX_STRLEN); 130 | } else if (FILE_EXISTS("/etc/lsb-release")) { 131 | distro_file = fopen("/etc/lsb-release", "r"); 132 | fscanf(distro_file, "%s ", distro_name_str); 133 | fclose(distro_file); 134 | 135 | snprintf(distro_str, MAX_STRLEN, "%s", distro_name_str + 11); 136 | safe_strncpy(host_color, TLRD, MAX_STRLEN); 137 | } else if (FILE_EXISTS("/etc/os-release")) { 138 | /* 139 | TODO: Parse NAME or PRETTY_NAME from os-release 140 | Until then, spit out an error message. 141 | */ 142 | if (error) 143 | ERR_REPORT("Failed to detect a Linux distro (1)."); 144 | } else { 145 | safe_strncpy(distro_str, "Linux", MAX_STRLEN); 146 | safe_strncpy(host_color, TLGY, MAX_STRLEN); 147 | 148 | if (error) { 149 | ERR_REPORT("Failed to detect a Linux distro (2)."); 150 | } 151 | } 152 | } 153 | } 154 | } 155 | 156 | return; 157 | } 158 | 159 | /* detect_host 160 | detects the computer's hostname and active user and formats them 161 | */ 162 | void detect_host(void) { 163 | char given_user[MAX_STRLEN] = "Unknown"; 164 | char given_host[MAX_STRLEN] = "Unknown"; 165 | struct passwd *user_info; 166 | struct utsname host_info; 167 | 168 | if ((user_info = getpwuid(geteuid()))) { 169 | safe_strncpy(given_user, user_info->pw_name, MAX_STRLEN); 170 | } else if (error) { 171 | ERR_REPORT("Could not detect username."); 172 | } 173 | 174 | if (!(uname(&host_info))) { 175 | safe_strncpy(given_host, host_info.nodename, MAX_STRLEN); 176 | } else if (error) { 177 | ERR_REPORT("Could not detect hostname."); 178 | } 179 | 180 | snprintf(host_str, MAX_STRLEN, "%s%s%s%s@%s%s%s%s", host_color, given_user, TNRM, TWHT, TNRM, 181 | host_color, given_host, TNRM); 182 | 183 | return; 184 | } 185 | 186 | /* detect_kernel 187 | detects the computer's kernel 188 | */ 189 | void detect_kernel(void) { 190 | struct utsname kern_info; 191 | 192 | if (!(uname(&kern_info))) { 193 | snprintf(kernel_str, MAX_STRLEN, "%s %s %s", kern_info.sysname, kern_info.release, 194 | kern_info.machine); 195 | } else if (error) { 196 | ERR_REPORT("Could not detect kernel information."); 197 | safe_strncpy(kernel_str, "Linux", MAX_STRLEN); 198 | } 199 | 200 | return; 201 | } 202 | 203 | /* detect_uptime 204 | detects the computer's uptime 205 | */ 206 | void detect_uptime(void) { 207 | unsigned int secs = 0; 208 | unsigned int mins = 0; 209 | unsigned int hrs = 0; 210 | unsigned int days = 0; 211 | struct sysinfo si_upt; 212 | 213 | if (!(sysinfo(&si_upt))) { 214 | split_uptime(si_upt.uptime, &secs, &mins, &hrs, &days); 215 | 216 | if (days > 0) 217 | snprintf(uptime_str, MAX_STRLEN, "%dd %dh %dm %ds", days, hrs, mins, secs); 218 | else 219 | snprintf(uptime_str, MAX_STRLEN, "%dh %dm %ds", hrs, mins, secs); 220 | } else { 221 | ERR_REPORT("Could not detect system uptime."); 222 | } 223 | 224 | return; 225 | } 226 | 227 | /* detect_pkgs 228 | detects the number of packages installed on the computer 229 | */ 230 | void detect_pkgs(void) { 231 | FILE *pkgs_file; 232 | int packages = 0; 233 | glob_t gl; 234 | 235 | if (STREQ(distro_str, "Arch Linux") || STREQ(distro_str, "ParabolaGNU/Linux-libre") || 236 | STREQ(distro_str, "Chakra") || STREQ(distro_str, "Manjaro")) { 237 | if (!(glob("/var/lib/pacman/local/*", GLOB_NOSORT, NULL, &gl))) { 238 | packages = gl.gl_pathc; 239 | } else if (error) { 240 | ERR_REPORT("Failure while globbing packages."); 241 | } 242 | 243 | globfree(&gl); 244 | } else if (STREQ(distro_str, "Frugalware")) { 245 | pkgs_file = popen("pacman-g2 -Q 2> /dev/null | wc -l", "r"); 246 | fscanf(pkgs_file, "%d", &packages); 247 | pclose(pkgs_file); 248 | } else if (STREQ(distro_str, "Ubuntu") || STREQ(distro_str, "Lubuntu") || 249 | STREQ(distro_str, "Xubuntu") || STREQ(distro_str, "LinuxMint") || 250 | STREQ(distro_str, "SolusOS") || STREQ(distro_str, "Debian") || 251 | STREQ(distro_str, "LMDE") || STREQ(distro_str, "CrunchBang") || 252 | STREQ(distro_str, "Peppermint") || STREQ(distro_str, "LinuxDeepin") || 253 | STREQ(distro_str, "Trisquel") || STREQ(distro_str, "elementary OS") || 254 | STREQ(distro_str, "Backtrack Linux") || STREQ(distro_str, "Kali Linux")) { 255 | if (!(glob("/var/lib/dpkg/info/*.list", GLOB_NOSORT, NULL, &gl))) { 256 | packages = gl.gl_pathc; 257 | } else if (error) { 258 | ERR_REPORT("Failure while globbing packages."); 259 | } 260 | 261 | globfree(&gl); 262 | } else if (STREQ(distro_str, "Slackware")) { 263 | if (!(glob("/var/log/packages/*", GLOB_NOSORT, NULL, &gl))) { 264 | packages = gl.gl_pathc; 265 | } else if (error) { 266 | ERR_REPORT("Failure while globbing packages."); 267 | } 268 | 269 | globfree(&gl); 270 | } else if (STREQ(distro_str, "Gentoo") || STREQ(distro_str, "Sabayon") || 271 | STREQ(distro_str, "Funtoo")) { 272 | if (!(glob("/var/db/pkg/*/*", GLOB_NOSORT, NULL, &gl))) { 273 | packages = gl.gl_pathc; 274 | } else if (error) { 275 | ERR_REPORT("Failure while globbing packages."); 276 | } 277 | 278 | globfree(&gl); 279 | } else if (STREQ(distro_str, "Fuduntu") || STREQ(distro_str, "Fedora") || 280 | STREQ(distro_str, "OpenSUSE") || STREQ(distro_str, "Red Hat Linux") || 281 | STREQ(distro_str, "Mandriva") || STREQ(distro_str, "Mandrake") || 282 | STREQ(distro_str, "Mageia") || STREQ(distro_str, "Viperr")) { 283 | /* RPM uses Berkeley DBs internally, so this won't change soon */ 284 | pkgs_file = popen("rpm -qa 2> /dev/null | wc -l", "r"); 285 | fscanf(pkgs_file, "%d", &packages); 286 | pclose(pkgs_file); 287 | } else if (STREQ(distro_str, "Angstrom")) { 288 | pkgs_file = popen("opkg list-installed 2> /dev/null | wc -l", "r"); 289 | fscanf(pkgs_file, "%d", &packages); 290 | pclose(pkgs_file); 291 | } else if (STREQ(distro_str, "Linux")) /* if linux disto detection failed */ 292 | { 293 | safe_strncpy(pkgs_str, "Not Found", MAX_STRLEN); 294 | 295 | if (error) 296 | ERR_REPORT("Packages cannot be detected on an unknown " 297 | "Linux distro."); 298 | } 299 | 300 | snprintf(pkgs_str, MAX_STRLEN, "%d", packages); 301 | 302 | return; 303 | } 304 | 305 | /* detect_cpu 306 | detects the computer's CPU brand/name-string 307 | */ 308 | void detect_cpu(void) { 309 | FILE *cpu_file; 310 | char cpuinfo_buf[MAX_STRLEN]; 311 | char *cpuinfo_line; 312 | int end; 313 | 314 | if ((cpu_file = fopen("/proc/cpuinfo", "r"))) { 315 | /* read past the first 4 lines (#5 is model name) */ 316 | for (int i = 0; i < 5; i++) { 317 | if (!(fgets(cpuinfo_buf, MAX_STRLEN, cpu_file))) { 318 | ERR_REPORT("Fatal error while reading /proc/cpuinfo"); 319 | return; 320 | } 321 | } 322 | 323 | /* fail to match a colon. this should never happen, but check anyways */ 324 | if (!(cpuinfo_line = strchr(cpuinfo_buf, ':'))) { 325 | ERR_REPORT("Fatal error matching in /proc/cpuinfo"); 326 | return; 327 | } 328 | 329 | cpuinfo_line += 2; 330 | end = strlen(cpuinfo_line); 331 | 332 | if (cpuinfo_line[end - 1] == '\n') 333 | cpuinfo_line[end - 1] = '\0'; 334 | 335 | if (STREQ(cpuinfo_line, "ARMv6-compatible processor rev 7 (v6l)")) { 336 | safe_strncpy(cpu_str, "BCM2708 (Raspberry Pi)", MAX_STRLEN); 337 | } else { 338 | safe_strncpy(cpu_str, cpuinfo_line, MAX_STRLEN); 339 | } 340 | } else if (error) { 341 | ERR_REPORT("Failed to open /proc/cpuinfo. Ancient Linux kernel?"); 342 | } 343 | 344 | return; 345 | } 346 | 347 | /* detect_gpu 348 | detects the computer's GPU brand/name-string 349 | */ 350 | void detect_gpu(void) { 351 | Display *disp = NULL; 352 | Window wind; 353 | GLint attr[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; 354 | XVisualInfo *visual_info = NULL; 355 | GLXContext context = NULL; 356 | 357 | if ((disp = XOpenDisplay(NULL))) { 358 | wind = DefaultRootWindow(disp); 359 | 360 | if ((visual_info = glXChooseVisual(disp, 0, attr))) { 361 | if ((context = glXCreateContext(disp, visual_info, NULL, GL_TRUE))) { 362 | glXMakeCurrent(disp, wind, context); 363 | safe_strncpy(gpu_str, (const char *)glGetString(GL_RENDERER), MAX_STRLEN); 364 | 365 | glXDestroyContext(disp, context); 366 | } else if (error) { 367 | ERR_REPORT("Failed to create OpenGL context."); 368 | } 369 | 370 | XFree(visual_info); 371 | } else if (error) { 372 | ERR_REPORT("Failed to select a proper X visual."); 373 | } 374 | 375 | XCloseDisplay(disp); 376 | } else if (error) { 377 | safe_strncpy(gpu_str, "No X Server", MAX_STRLEN); 378 | ERR_REPORT("Could not open an X display (detect_gpu)."); 379 | } 380 | 381 | return; 382 | } 383 | 384 | /* detect_disk 385 | detects the computer's total disk capacity and usage 386 | */ 387 | void detect_disk(void) { 388 | FILE *mnt_file; 389 | struct mntent *ent; 390 | struct statvfs fs; 391 | unsigned long long disk_total = 0, disk_used = 0, disk_pct = 0; 392 | 393 | if ((mnt_file = setmntent("/etc/mtab", "r"))) { 394 | while ((ent = getmntent(mnt_file))) { 395 | /* we only want to get the size of "real" disks (starting with /) */ 396 | if (ent->mnt_dir && ent->mnt_fsname && ent->mnt_fsname[0] == '/') { 397 | if (!statvfs(ent->mnt_dir, &fs)) { 398 | disk_total += (fs.f_blocks * fs.f_bsize); 399 | disk_used += ((fs.f_blocks - fs.f_bfree) * fs.f_bsize); 400 | } else { 401 | ERR_REPORT("Could not stat filesystem for statistics (detect_disk)."); 402 | } 403 | } 404 | } 405 | 406 | disk_total /= GB; 407 | disk_used /= GB; 408 | disk_pct = disk_total > 0 ? (disk_used * 100 / disk_total) : 0; 409 | 410 | snprintf(disk_str, MAX_STRLEN, "%llu%s / %llu%s (%llu%%)", disk_used, "GiB", disk_total, "GiB", 411 | disk_pct); 412 | 413 | endmntent(mnt_file); 414 | } else if (error) { 415 | ERR_REPORT("Could not open /etc/mtab (detect_disk)."); 416 | } 417 | 418 | return; 419 | } 420 | 421 | /* detect_mem 422 | detects the computer's total and used RAM 423 | */ 424 | void detect_mem(void) { 425 | long long memtotal = 0, shmem = 0, memavailable = 0, sunreclaim = 0; 426 | long long total_mem, used_mem, mem_pct; 427 | FILE *fp; 428 | char line[64]; 429 | 430 | if ((fp = fopen("/proc/meminfo", "r"))) { 431 | while (fgets(line, 64, fp)) { 432 | if (strncmp(line, "MemTotal:", 9) == 0) { 433 | sscanf(line + 9, "%lld", &memtotal); 434 | } else if (strncmp(line, "Shmem:", 6) == 0) { 435 | sscanf(line + 6, "%lld", &shmem); 436 | } else if (strncmp(line, "MemAvailable:", 13) == 0) { 437 | sscanf(line + 13, "%lld", &memavailable); 438 | } else if (strncmp(line, "SUnreclaim:", 11) == 0) { 439 | sscanf(line + 11, "%lld", &sunreclaim); 440 | } 441 | } 442 | fclose(fp); 443 | } else { 444 | ERR_REPORT("Failed to open /proc/meminfo. Ancient Linux kernel?"); 445 | } 446 | 447 | total_mem = (memtotal + shmem) * 1000; 448 | used_mem = total_mem - ((memavailable + sunreclaim) * 1000); 449 | total_mem /= MB; 450 | used_mem /= MB; 451 | mem_pct = total_mem > 0 ? (used_mem * 100 / total_mem) : 0; 452 | 453 | snprintf(mem_str, MAX_STRLEN, "%lld%s / %lld%s (%lld%%)", used_mem, "MiB", total_mem, "MiB", 454 | mem_pct); 455 | 456 | return; 457 | } 458 | 459 | /* detect_shell 460 | detects the shell currently running on the computer 461 | -- 462 | CAVEAT: shell version detection relies on the standard versioning format for 463 | each shell. If any shell's older (or newer versions) suddenly begin to use a new 464 | scheme, the version may be displayed incorrectly. 465 | -- 466 | */ 467 | void detect_shell(void) { 468 | FILE *shell_file; 469 | char *shell_name; 470 | char vers_str[MAX_STRLEN]; 471 | 472 | if (!(shell_name = getenv("SHELL"))) { 473 | if (error) 474 | ERR_REPORT("Could not detect a shell - $SHELL not defined."); 475 | 476 | return; 477 | } 478 | 479 | if (STREQ(shell_name, "/bin/sh")) { 480 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 481 | } else if (strstr(shell_name, "bash")) { 482 | shell_file = popen("bash --version | head -1", "r"); 483 | fgets(vers_str, MAX_STRLEN, shell_file); 484 | snprintf(shell_str, MAX_STRLEN, "bash %.*s", 17, vers_str + 10); 485 | pclose(shell_file); 486 | } else if (strstr(shell_name, "zsh")) { 487 | shell_file = popen("zsh --version", "r"); 488 | fgets(vers_str, MAX_STRLEN, shell_file); 489 | snprintf(shell_str, MAX_STRLEN, "zsh %.*s", 5, vers_str + 4); 490 | pclose(shell_file); 491 | } else if (strstr(shell_name, "csh")) { 492 | shell_file = popen("csh --version | head -1", "r"); 493 | fgets(vers_str, MAX_STRLEN, shell_file); 494 | snprintf(shell_str, MAX_STRLEN, "csh %.*s", 7, vers_str + 5); 495 | pclose(shell_file); 496 | } else if (strstr(shell_name, "fish")) { 497 | shell_file = popen("fish --version", "r"); 498 | fgets(vers_str, MAX_STRLEN, shell_file); 499 | snprintf(shell_str, MAX_STRLEN, "fish %.*s", 13, vers_str + 6); 500 | pclose(shell_file); 501 | } else if (strstr(shell_name, "dash") || strstr(shell_name, "ash") || strstr(shell_name, "ksh")) { 502 | /* i don't have a version detection system for these, yet */ 503 | safe_strncpy(shell_str, shell_name, MAX_STRLEN); 504 | } 505 | 506 | return; 507 | } 508 | 509 | /* detect_res 510 | detects the combined resolution of all monitors attached to the computer 511 | */ 512 | void detect_res(void) { 513 | int width = 0, height = 0; 514 | Display *disp; 515 | Screen *screen; 516 | 517 | if ((disp = XOpenDisplay(NULL))) { 518 | screen = XDefaultScreenOfDisplay(disp); 519 | width = WidthOfScreen(screen); 520 | height = HeightOfScreen(screen); 521 | 522 | snprintf(res_str, MAX_STRLEN, "%dx%d", width, height); 523 | 524 | XCloseDisplay(disp); 525 | } else { 526 | safe_strncpy(res_str, "No X Server", MAX_STRLEN); 527 | 528 | if (error) 529 | ERR_REPORT("Could not open an X display (detect_res)"); 530 | } 531 | 532 | return; 533 | } 534 | 535 | /* detect_de 536 | detects the desktop environment currently running on top of the OS 537 | */ 538 | void detect_de(void) { 539 | char *curr_de; 540 | 541 | if ((curr_de = getenv("XDG_CURRENT_DESKTOP"))) { 542 | safe_strncpy(de_str, curr_de, MAX_STRLEN); 543 | } else { 544 | if (getenv("GNOME_DESKTOP_SESSION_ID")) { 545 | safe_strncpy(de_str, "Gnome", MAX_STRLEN); 546 | } else if (getenv("MATE_DESKTOP_SESSION_ID")) { 547 | safe_strncpy(de_str, "MATE", MAX_STRLEN); 548 | } else if (getenv("KDE_FULL_SESSION")) { 549 | /* KDE_SESSION_VERSION only exists on KDE4+, so 550 | getenv will return NULL on KDE <= 3. 551 | */ 552 | snprintf(de_str, MAX_STRLEN, "KDE%s", getenv("KDE_SESSION_VERSION")); 553 | } else if (error) { 554 | ERR_REPORT("No desktop environment found."); 555 | } 556 | } 557 | 558 | return; 559 | } 560 | 561 | /* detect_wm 562 | detects the window manager currently running on top of the OS 563 | */ 564 | void detect_wm(void) { 565 | Display *disp; 566 | Atom actual_type; 567 | int actual_format; 568 | unsigned long nitems; 569 | unsigned long bytes; 570 | char *wm_name = '\0'; 571 | Window *wm_check_window; 572 | 573 | if ((disp = XOpenDisplay(NULL))) { 574 | if (!(XGetWindowProperty(disp, DefaultRootWindow(disp), 575 | XInternAtom(disp, "_NET_SUPPORTING_WM_CHECK", true), 0, KB, false, 576 | XA_WINDOW, &actual_type, &actual_format, &nitems, &bytes, 577 | (unsigned char **)&wm_check_window))) { 578 | if (wm_check_window && 579 | !(XGetWindowProperty(disp, *wm_check_window, XInternAtom(disp, "_NET_WM_NAME", true), 0, 580 | KB, false, XInternAtom(disp, "UTF8_STRING", true), &actual_type, 581 | &actual_format, &nitems, &bytes, (unsigned char **)&wm_name))) { 582 | safe_strncpy(wm_str, wm_name, MAX_STRLEN); 583 | XFree(wm_name); 584 | } else if (error) { 585 | ERR_REPORT("No _NET_WM_NAME property found."); 586 | } 587 | 588 | XFree(wm_check_window); 589 | } else if (error) { 590 | ERR_REPORT("No WM detected (non-EWMH compliant?)"); 591 | } 592 | 593 | XCloseDisplay(disp); 594 | } else if (error) { 595 | ERR_REPORT("Could not open an X display. (detect_wm)"); 596 | } 597 | 598 | return; 599 | } 600 | 601 | /* detect_wm_theme 602 | detects the theme associated with the WM detected in detect_wm() 603 | -- 604 | CAVEAT: This function relies on the presence of 'detectwmtheme', a shell script. 605 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 606 | -- 607 | */ 608 | void detect_wm_theme(void) { 609 | char exec_str[MAX_STRLEN] = "false"; 610 | char config_file[MAX_STRLEN]; 611 | char *home; 612 | FILE *wm_theme_file; 613 | 614 | snprintf(wm_theme_str, MAX_STRLEN, "Unknown"); 615 | home = getenv("HOME"); 616 | 617 | if (!home) { 618 | ERR_REPORT("Environment variable HOME not set."); 619 | } else { 620 | if (STREQ("Awesome", wm_str)) { 621 | snprintf(config_file, MAX_STRLEN, "%s/.config/awesome/rc.lua", home); 622 | snprintf(exec_str, MAX_STRLEN, 623 | "grep -e '^[^-].*\\(theme\\|beautiful\\).*lua' '%s' | grep " 624 | "'[a-zA-Z0-9]\\+/[a-zA-Z0-9]\\+.lua' -o | head -n1 | cut -d'/' -f1", 625 | config_file); 626 | } else if (STRCASEEQ("BlackBox", wm_str)) { 627 | snprintf(config_file, MAX_STRLEN, "%s/.blackboxrc", home); 628 | if (FILE_EXISTS(config_file)) { 629 | snprintf(exec_str, MAX_STRLEN, "awk -F\"/\" '/styleFile/ {print $NF}' '%s'", config_file); 630 | } 631 | } else if (STREQ("Cinnamon", wm_str)) { 632 | safe_strncpy(exec_str, "gsettings get org.cinnamon.theme name", MAX_STRLEN); 633 | } else if (STREQ("Compiz", wm_str) || BEGINS_WITH(wm_str, "Mutter") || 634 | STREQ("GNOME Shell", wm_str)) { 635 | if (command_in_path("gsettings")) { 636 | safe_strncpy(exec_str, "gsettings get org.gnome.desktop.wm.preferences theme", MAX_STRLEN); 637 | } else if (command_in_path("gconftool-2")) { 638 | safe_strncpy(exec_str, "gconftool-2 -g /apps/metacity/general/theme", MAX_STRLEN); 639 | } 640 | } else if (STREQ("E16", wm_str)) { 641 | snprintf(config_file, MAX_STRLEN, "%s/.e16/e_config--0.0.cfg", home); 642 | if (FILE_EXISTS(config_file)) { 643 | snprintf(exec_str, MAX_STRLEN, "awk -F\"= \" '/theme.name/ {print $2}' '%s'", config_file); 644 | } 645 | } else if (STREQ("E17", wm_str) || STREQ("Enlightenment", wm_str)) { 646 | snprintf(config_file, MAX_STRLEN, "%s/.e/e/config/standard/e.cfg", home); 647 | if (FILE_EXISTS(config_file) && command_in_path("eet")) { 648 | snprintf(exec_str, MAX_STRLEN, 649 | "cfg=\"$(eet -d '%s' config | awk '/value \"file\" string.*.edj/{ print $4 }')\"; " 650 | "cfg=\"${cfg##*/}\"; " 651 | "echo \"${cfg%%.*}\"", 652 | config_file); 653 | } else { 654 | char *tmp = getenv("E_CONF_PROFILE"); 655 | if (tmp) { 656 | safe_strncpy(wm_theme_str, tmp, MAX_STRLEN); 657 | } 658 | } 659 | } else if (STREQ("Emerald", wm_str)) { 660 | snprintf(config_file, MAX_STRLEN, "%s/.emerald/theme/theme.ini", home); 661 | if (FILE_EXISTS(config_file)) { 662 | snprintf(exec_str, MAX_STRLEN, 663 | "for a in /usr/share/emerald/themes/* \"%s/.emerald/themes\"/*; do" 664 | " cmp \"%s\" \"$a/theme.ini\" &>/dev/null && basename \"$a\"; " 665 | "done", 666 | home, config_file); 667 | } 668 | } else if (STRCASEEQ("FluxBox", wm_str)) { 669 | snprintf(config_file, MAX_STRLEN, "%s/.fluxbox/init", home); 670 | if (FILE_EXISTS(config_file)) { 671 | snprintf(exec_str, MAX_STRLEN, "awk -F\"/\" '/styleFile/ {print $NF}' '%s'", config_file); 672 | } 673 | } else if (STREQ("IceWM", wm_str)) { 674 | snprintf(config_file, MAX_STRLEN, "%s/.icewm/theme", home); 675 | if (FILE_EXISTS(config_file)) { 676 | snprintf(exec_str, MAX_STRLEN, "awk -F\"[\\\",/]\" '!/#/ {print $2}' '%s'", config_file); 677 | } 678 | } else if (BEGINS_WITH(wm_str, "KWin")) { 679 | FILE *f = NULL; 680 | char kde_config_dir[MAX_STRLEN] = "Unknown"; 681 | char kde_theme[MAX_STRLEN] = "Unknown"; 682 | char *env; 683 | const char *kde_config_cmd = NULL; 684 | 685 | env = getenv("KDE_CONFIG_DIR"); 686 | if (env) { 687 | safe_strncpy(kde_config_dir, env, MAX_STRLEN); 688 | } else { 689 | if (command_in_path("kde5-config")) { 690 | kde_config_cmd = "kde5-config --localprefix"; 691 | } else if (command_in_path("kde4-config")) { 692 | kde_config_cmd = "kde4-config --localprefix"; 693 | } 694 | if (command_in_path("kde-config")) { 695 | kde_config_cmd = "kde-config --localprefix"; 696 | } 697 | 698 | if (kde_config_cmd) { 699 | f = popen(kde_config_cmd, "r"); 700 | fgets(kde_config_dir, MAX_STRLEN, f); 701 | pclose(f); 702 | } 703 | } 704 | 705 | if (!STREQ("Unknown", kde_config_dir)) { 706 | snprintf(exec_str, MAX_STRLEN, 707 | "awk '/PluginLib=kwin3_/{gsub(/PluginLib=kwin3_/,\"\",$0); print $0; exit}' " 708 | "'%s/share/config/kwinrc'", 709 | kde_config_dir); 710 | f = popen(exec_str, "r"); 711 | fgets(kde_theme, MAX_STRLEN, f); 712 | pclose(f); 713 | 714 | if (STREQ("", kde_theme) || STREQ("\n", kde_theme)) { 715 | snprintf(config_file, MAX_STRLEN, "%s/share/config/kdebugrc", kde_config_dir); 716 | if (FILE_EXISTS(config_file)) { 717 | snprintf(exec_str, MAX_STRLEN, 718 | "awk '/(decoration)/ {gsub(/\\[/,\"\",$1); print $1; exit}' '%s'", 719 | config_file); 720 | f = popen(exec_str, "r"); 721 | fgets(kde_theme, MAX_STRLEN, f); 722 | pclose(f); 723 | 724 | if (STREQ("", kde_theme) || STREQ("\n", kde_theme)) { 725 | safe_strncpy(kde_theme, "Unknown", MAX_STRLEN); 726 | } 727 | } 728 | } 729 | } 730 | 731 | safe_strncpy(exec_str, "false", MAX_STRLEN); 732 | safe_strncpy(wm_theme_str, kde_theme, MAX_STRLEN); 733 | } else if (STREQ("Marco", wm_str) || STREQ("Metacity (Marco)", wm_str)) { 734 | safe_strncpy(exec_str, "gsettings get org.mate.Marco.general theme", MAX_STRLEN); 735 | } else if (STREQ("Metacity", wm_str)) { 736 | safe_strncpy(exec_str, "gconftool-2 -g /apps/metacity/general/theme 2>/dev/null", MAX_STRLEN); 737 | } else if (STRCASEEQ("OpenBox", wm_str)) { 738 | snprintf(config_file, MAX_STRLEN, "%s/.config/openbox/lxde-rc.xml", home); 739 | if (!(FILE_EXISTS(config_file) && STREQ(de_str, "LXDE"))) { 740 | config_file[0] = '\0'; 741 | } 742 | 743 | if (config_file[0] == '\0') { 744 | snprintf(config_file, MAX_STRLEN, "%s/.config/openbox/rc.xml", home); 745 | if (!FILE_EXISTS(config_file)) { 746 | config_file[0] = '\0'; 747 | } 748 | } 749 | 750 | if (config_file[0] != '\0') { 751 | snprintf(exec_str, MAX_STRLEN, "awk -F\"[<,>]\" '/ /dev/null", de_str); 806 | gtk_file = popen(exec_str, "r"); 807 | fscanf(gtk_file, "%s%s%s%s", gtk2_str, gtk3_str, gtk_icons_str, gtk_font_str); 808 | pclose(gtk_file); 809 | 810 | unquote(gtk2_str); 811 | unquote(gtk3_str); 812 | unquote(gtk_icons_str); 813 | unquote(gtk_font_str); 814 | 815 | if (STREQ(gtk3_str, "Unknown")) 816 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK2), %s (Icons)", gtk2_str, gtk_icons_str); 817 | else if (STREQ(gtk2_str, "Unknown")) 818 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK3), %s (Icons)", gtk3_str, gtk_icons_str); 819 | else 820 | snprintf(gtk_str, MAX_STRLEN, "%s (GTK2), %s (GTK3)", gtk2_str, gtk3_str); 821 | 822 | snprintf(icon_str, MAX_STRLEN, "%s", gtk_icons_str); 823 | 824 | snprintf(font_str, MAX_STRLEN, "%s", gtk_font_str); 825 | 826 | return; 827 | } 828 | -------------------------------------------------------------------------------- /src/plat/sun/detect.c: -------------------------------------------------------------------------------- 1 | /* detect.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c on Solaris are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* Solaris-specific includes */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | /* program includes */ 28 | #include "../../arrays.h" 29 | #include "../../colors.h" 30 | #include "../../misc.h" 31 | #include "../../disp.h" 32 | #include "../../util.h" 33 | #include "../../error_flag.h" 34 | 35 | /* detect_distro 36 | detects the computer's distribution 37 | */ 38 | void detect_distro(void) { 39 | struct utsname distro_info; 40 | 41 | uname(&distro_info); 42 | snprintf(distro_str, MAX_STRLEN, "%s", distro_info.sysname); 43 | 44 | return; 45 | } 46 | 47 | /* detect_host 48 | detects the computer's hostname and active user and formats them 49 | */ 50 | void detect_host(void) { 51 | char *given_user = "Unknown"; 52 | char given_host[MAX_STRLEN] = "Unknown"; 53 | struct utsname host_info; 54 | 55 | given_user = getlogin(); 56 | uname(&host_info); 57 | safe_strncpy(given_host, host_info.nodename, MAX_STRLEN); 58 | 59 | snprintf(host_str, MAX_STRLEN, "%s%s%s%s@%s%s%s%s", host_color, given_user, TNRM, TWHT, TNRM, 60 | host_color, given_host, TNRM); 61 | 62 | return; 63 | } 64 | 65 | /* detect_kernel 66 | detects the computer's kernel 67 | */ 68 | void detect_kernel(void) { 69 | struct utsname kern_info; 70 | 71 | uname(&kern_info); 72 | snprintf(kernel_str, MAX_STRLEN, "%s", kern_info.release); 73 | 74 | return; 75 | } 76 | 77 | /* detect_uptime 78 | detects the computer's uptime 79 | */ 80 | void detect_uptime(void) { 81 | long uptime = 0, currtime = 0, boottime = 0; 82 | unsigned int secs = 0; 83 | unsigned int mins = 0; 84 | unsigned int hrs = 0; 85 | unsigned int days = 0; 86 | struct utmpx *ent; 87 | 88 | currtime = time(NULL); 89 | 90 | while ((ent = getutxent())) { 91 | if (STREQ("system boot", ent->ut_line)) { 92 | boottime = ent->ut_tv.tv_sec; 93 | } 94 | } 95 | 96 | uptime = currtime - boottime; 97 | 98 | split_uptime(uptime, &secs, &mins, &hrs, &days); 99 | 100 | if (days > 0) 101 | snprintf(uptime_str, MAX_STRLEN, "%dd %dh %dm %ds", days, hrs, mins, secs); 102 | else 103 | snprintf(uptime_str, MAX_STRLEN, "%dh %dm %ds", hrs, mins, secs); 104 | 105 | return; 106 | } 107 | 108 | /* detect_pkgs 109 | detects the number of packages installed on the computer 110 | */ 111 | void detect_pkgs(void) { 112 | FILE *pkgs_file; 113 | int packages = 0; 114 | 115 | pkgs_file = popen("pkg list | wc -l", "r"); 116 | fscanf(pkgs_file, "%d", &packages); 117 | pclose(pkgs_file); 118 | 119 | snprintf(pkgs_str, MAX_STRLEN, "%d", packages); 120 | 121 | return; 122 | } 123 | 124 | /* detect_cpu 125 | detects the computer's CPU brand/name-string 126 | */ 127 | void detect_cpu(void) { 128 | FILE *cpu_file; 129 | 130 | cpu_file = popen("psrinfo -pv | tail -1 | tr -d '\\t\\n'", "r"); 131 | fgets(cpu_str, MAX_STRLEN, cpu_file); 132 | pclose(cpu_file); 133 | 134 | return; 135 | } 136 | 137 | /* detect_gpu 138 | detects the computer's GPU brand/name-string 139 | */ 140 | void detect_gpu(void) { 141 | FILE *gpu_file; 142 | 143 | gpu_file = popen("detectgpu 2>/dev/null", "r"); 144 | fgets(gpu_str, MAX_STRLEN, gpu_file); 145 | pclose(gpu_file); 146 | 147 | return; 148 | } 149 | 150 | /* detect_disk 151 | detects the computer's total disk capacity and usage 152 | */ 153 | void detect_disk(void) { 154 | struct statvfs disk_info; 155 | unsigned long disk_total = 0, disk_used = 0, disk_percentage = 0; 156 | 157 | if (!(statvfs(getenv("HOME"), &disk_info))) { 158 | disk_total = ((disk_info.f_blocks * disk_info.f_bsize) / GB); 159 | disk_used = (((disk_info.f_blocks - disk_info.f_bfree) * disk_info.f_bsize) / GB); 160 | disk_percentage = (((float)disk_used / disk_total) * 100); 161 | snprintf(disk_str, MAX_STRLEN, "%ldG / %ldG (%ld%%)", disk_used, disk_total, disk_percentage); 162 | } else if (error) { 163 | ERR_REPORT("Could not stat $HOME for filesystem statistics."); 164 | } 165 | 166 | return; 167 | } 168 | 169 | /* detect_mem 170 | detects the computer's total and used RAM 171 | */ 172 | void detect_mem(void) { 173 | long long total_mem = 0; 174 | 175 | total_mem = (long long)sysconf(_SC_PHYS_PAGES) * (long long)sysconf(_SC_PAGE_SIZE); 176 | total_mem /= MB; 177 | 178 | /* sar -r 1 to get free pages? */ 179 | 180 | snprintf(mem_str, MAX_STRLEN, "%lld%s", total_mem, "MB"); 181 | 182 | return; 183 | } 184 | 185 | /* detect_shell 186 | detects the shell currently running on the computer 187 | -- 188 | CAVEAT: shell version detection relies on the standard versioning format for 189 | each shell. If any shell's older (or newer versions) suddenly begin to use a new 190 | scheme, the version may be displayed incorrectly. 191 | -- 192 | */ 193 | void detect_shell(void) { 194 | FILE *shell_file; 195 | char *shell_name; 196 | char vers_str[MAX_STRLEN]; 197 | 198 | shell_name = getenv("SHELL"); 199 | 200 | if (shell_name == NULL) { 201 | if (error) 202 | ERR_REPORT("Could not detect a shell."); 203 | 204 | return; 205 | } 206 | 207 | if (STREQ(shell_name, "/bin/sh")) { 208 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 209 | } else if (strstr(shell_name, "bash")) { 210 | shell_file = popen("bash --version | head -1", "r"); 211 | fgets(vers_str, MAX_STRLEN, shell_file); 212 | snprintf(shell_str, MAX_STRLEN, "bash %.*s", 17, vers_str + 10); 213 | pclose(shell_file); 214 | } else if (strstr(shell_name, "zsh")) { 215 | shell_file = popen("zsh --version", "r"); 216 | fgets(vers_str, MAX_STRLEN, shell_file); 217 | snprintf(shell_str, MAX_STRLEN, "zsh %.*s", 5, vers_str + 4); 218 | pclose(shell_file); 219 | } else if (strstr(shell_name, "csh")) { 220 | shell_file = popen("csh --version | head -1", "r"); 221 | fgets(vers_str, MAX_STRLEN, shell_file); 222 | snprintf(shell_str, MAX_STRLEN, "csh %.*s", 7, vers_str + 5); 223 | pclose(shell_file); 224 | } else if (strstr(shell_name, "fish")) { 225 | shell_file = popen("fish --version", "r"); 226 | fgets(vers_str, MAX_STRLEN, shell_file); 227 | snprintf(shell_str, MAX_STRLEN, "fish %.*s", 13, vers_str + 6); 228 | pclose(shell_file); 229 | } else if (strstr(shell_name, "dash") || strstr(shell_name, "ash") || strstr(shell_name, "ksh")) { 230 | /* i don't have a version detection system for these, yet */ 231 | safe_strncpy(shell_str, shell_name, MAX_STRLEN); 232 | } 233 | 234 | return; 235 | } 236 | 237 | /* detect_res 238 | detects the combined resolution of all monitors attached to the computer 239 | */ 240 | void detect_res(void) { 241 | int width = 0; 242 | int height = 0; 243 | Display *disp; 244 | Screen *screen; 245 | 246 | if ((disp = XOpenDisplay(NULL))) { 247 | screen = XDefaultScreenOfDisplay(disp); 248 | width = WidthOfScreen(screen); 249 | height = HeightOfScreen(screen); 250 | snprintf(res_str, MAX_STRLEN, "%dx%d", width, height); 251 | XCloseDisplay(disp); 252 | } else { 253 | safe_strncpy(res_str, "No X Server", MAX_STRLEN); 254 | if (error) 255 | ERR_REPORT("Problem detecting X display resolution."); 256 | } 257 | 258 | return; 259 | } 260 | 261 | /* detect_de 262 | detects the desktop environment currently running on top of the OS 263 | */ 264 | void detect_de(void) { 265 | char *curr_de; 266 | 267 | if ((curr_de = getenv("XDG_CURRENT_DESKTOP"))) { 268 | safe_strncpy(de_str, curr_de, MAX_STRLEN); 269 | } else { 270 | if (getenv("GNOME_DESKTOP_SESSION_ID")) { 271 | safe_strncpy(de_str, "Gnome", MAX_STRLEN); 272 | } else if (getenv("MATE_DESKTOP_SESSION_ID")) { 273 | safe_strncpy(de_str, "MATE", MAX_STRLEN); 274 | } else if (getenv("KDE_FULL_SESSION")) { 275 | /* KDE_SESSION_VERSION only exists on KDE4+, so 276 | getenv will return NULL on KDE <= 3. 277 | */ 278 | snprintf(de_str, MAX_STRLEN, "KDE%s", getenv("KDE_SESSION_VERSION")); 279 | } else if (error) { 280 | ERR_REPORT("No desktop environment found."); 281 | } 282 | } 283 | 284 | return; 285 | } 286 | 287 | /* detect_wm 288 | detects the window manager currently running on top of the OS 289 | -- 290 | CAVEAT: This function relies on the presence of 'detectwm', a shell script. 291 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 292 | -- 293 | */ 294 | void detect_wm(void) { 295 | Display *disp; 296 | Atom actual_type; 297 | int actual_format; 298 | unsigned long nitems; 299 | unsigned long bytes; 300 | char *wm_name = '\0'; 301 | Window *wm_check_window; 302 | 303 | if ((disp = XOpenDisplay(NULL))) { 304 | if (!(XGetWindowProperty(disp, DefaultRootWindow(disp), 305 | XInternAtom(disp, "_NET_SUPPORTING_WM_CHECK", true), 0, KB, false, 306 | XA_WINDOW, &actual_type, &actual_format, &nitems, &bytes, 307 | (unsigned char **)&wm_check_window))) { 308 | if (!(XGetWindowProperty(disp, *wm_check_window, XInternAtom(disp, "_NET_WM_NAME", true), 0, 309 | KB, false, XInternAtom(disp, "UTF8_STRING", true), &actual_type, 310 | &actual_format, &nitems, &bytes, (unsigned char **)&wm_name))) { 311 | safe_strncpy(wm_str, wm_name, MAX_STRLEN); 312 | XFree(wm_name); 313 | } else if (error) { 314 | ERR_REPORT("No _NET_WM_NAME property found."); 315 | } 316 | 317 | XFree(wm_check_window); 318 | } else if (error) { 319 | ERR_REPORT("WM cannot be detected without EWMH compliance."); 320 | } 321 | 322 | XCloseDisplay(disp); 323 | } else if (error) { 324 | ERR_REPORT("Could not open an X display."); 325 | } 326 | 327 | return; 328 | } 329 | 330 | /* detect_wm_theme 331 | detects the theme associated with the WM detected in detect_wm() 332 | -- 333 | CAVEAT: This function relies on the presence of 'detectwmtheme', a shell script. 334 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 335 | -- 336 | */ 337 | void detect_wm_theme(void) { 338 | char exec_str[MAX_STRLEN]; 339 | FILE *wm_theme_file; 340 | 341 | snprintf(exec_str, MAX_STRLEN, "detectwmtheme %s 2> /dev/null", wm_str); 342 | 343 | wm_theme_file = popen(exec_str, "r"); 344 | fgets(wm_theme_str, MAX_STRLEN, wm_theme_file); 345 | pclose(wm_theme_file); 346 | 347 | return; 348 | } 349 | 350 | /* detect_gtk 351 | detects the theme, icon(s), and font(s) associated with a GTK DE (if present) 352 | -- 353 | CAVEAT: This function relies on the presence of 'detectgtk', a shell script. 354 | If it isn't present somewhere in the PATH, the WM Theme will be set as 'Unknown' 355 | -- 356 | */ 357 | void detect_gtk(void) { 358 | safe_strncpy(gtk_str, "Not implemented", MAX_STRLEN); 359 | 360 | return; 361 | } 362 | -------------------------------------------------------------------------------- /src/plat/win32/bitmap.c: -------------------------------------------------------------------------------- 1 | /* bitmap.c 2 | ** Author: djcj 3 | ** ------------- 4 | ** 5 | ** The screenshot functions used by screenfetch-c on Windows are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #include 10 | 11 | int createBitmapFile(LPCTSTR lpszFileName, HBITMAP hBitmap, HDC hdc) { 12 | BITMAP bitmap; 13 | BITMAPFILEHEADER bitmapFileHeader; 14 | 15 | if (!GetObject(hBitmap, sizeof(BITMAP), &bitmap)) { 16 | return -1; 17 | } 18 | 19 | int infoHeaderSize = sizeof(BITMAPINFOHEADER); 20 | int rgbQuadSize = sizeof(RGBQUAD); 21 | int bits = bitmap.bmPlanes * bitmap.bmBitsPixel; 22 | int infoHeaderSizeImage = ((bitmap.bmWidth * bits + 31) & ~31) / 8 * bitmap.bmHeight; 23 | 24 | PBITMAPINFO pBitmapInfo = 25 | (PBITMAPINFO)LocalAlloc(LPTR, infoHeaderSize + rgbQuadSize * (1 << bits)); 26 | 27 | pBitmapInfo->bmiHeader.biSize = infoHeaderSize; 28 | pBitmapInfo->bmiHeader.biBitCount = bitmap.bmBitsPixel; 29 | pBitmapInfo->bmiHeader.biClrImportant = 0; 30 | pBitmapInfo->bmiHeader.biClrUsed = 0; 31 | pBitmapInfo->bmiHeader.biCompression = BI_RGB; 32 | pBitmapInfo->bmiHeader.biHeight = bitmap.bmHeight; 33 | pBitmapInfo->bmiHeader.biWidth = bitmap.bmWidth; 34 | pBitmapInfo->bmiHeader.biPlanes = bitmap.bmPlanes; 35 | pBitmapInfo->bmiHeader.biSizeImage = infoHeaderSizeImage; 36 | 37 | PBITMAPINFOHEADER pBitmapInfoHeader = (PBITMAPINFOHEADER)pBitmapInfo; 38 | LPBYTE mem = GlobalAlloc(GMEM_FIXED, pBitmapInfoHeader->biSizeImage); 39 | 40 | if (!mem) { 41 | return -1; 42 | } 43 | 44 | if (!GetDIBits(hdc, hBitmap, 0, pBitmapInfoHeader->biHeight, mem, pBitmapInfo, DIB_RGB_COLORS)) { 45 | return -1; 46 | } 47 | 48 | int fileHeaderSize = sizeof(BITMAPFILEHEADER); 49 | int fileAndInfoHeaderSize = 50 | fileHeaderSize + infoHeaderSize + pBitmapInfoHeader->biClrUsed * rgbQuadSize; 51 | 52 | bitmapFileHeader.bfType = 'B' + ('M' << 8); 53 | bitmapFileHeader.bfOffBits = fileAndInfoHeaderSize; 54 | bitmapFileHeader.bfSize = fileAndInfoHeaderSize + pBitmapInfoHeader->biSizeImage; 55 | bitmapFileHeader.bfReserved1 = 0; 56 | bitmapFileHeader.bfReserved2 = 0; 57 | 58 | HANDLE handleFile = 59 | CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 60 | 61 | if (handleFile == INVALID_HANDLE_VALUE) { 62 | return -1; 63 | } 64 | 65 | if (!WriteFile(handleFile, &bitmapFileHeader, fileHeaderSize, NULL, NULL)) { 66 | return -1; 67 | } 68 | 69 | if (!WriteFile(handleFile, pBitmapInfoHeader, 70 | infoHeaderSize + pBitmapInfoHeader->biClrUsed * rgbQuadSize, NULL, NULL)) { 71 | return -1; 72 | } 73 | 74 | if (!WriteFile(handleFile, mem, pBitmapInfoHeader->biSizeImage, NULL, NULL)) { 75 | return -1; 76 | } 77 | 78 | if (!CloseHandle(handleFile)) { 79 | return -1; 80 | } 81 | 82 | GlobalFree(mem); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /src/plat/win32/bitmap.h: -------------------------------------------------------------------------------- 1 | /* bitmap.h 2 | ** Author: djcj 3 | ** ------------- 4 | ** 5 | ** Function prototypes for bitmap.c. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_BITMAP_H 10 | #define SCREENFETCH_C_BITMAP_H 11 | 12 | #include 13 | 14 | int createBitmapFile(LPCTSTR lpszFileName, HBITMAP hBitmap, HDC hdc); 15 | 16 | #endif /* SCREENFETCH_C_BITMAP_H */ 17 | -------------------------------------------------------------------------------- /src/plat/win32/detect.c: -------------------------------------------------------------------------------- 1 | /* detect.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** The detection functions used by screenfetch-c on Windows (Cygwin) are implemented here. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #ifndef __MINGW32__ 18 | #include 19 | #endif 20 | 21 | /* Windows-specific includes */ 22 | #include 23 | 24 | #ifdef __CYGWIN__ 25 | /* Cygwin wets itself without an explicit external linkage to popen */ 26 | extern FILE *popen(const char *command, const char *type); 27 | extern int pclose(FILE *stream); 28 | #endif 29 | 30 | /* program includes */ 31 | #include "../../arrays.h" 32 | #include "../../colors.h" 33 | #include "../../misc.h" 34 | #include "../../disp.h" 35 | #include "../../util.h" 36 | #include "../../error_flag.h" 37 | 38 | /* detect_distro 39 | detects the computer's distribution (Windows version) 40 | */ 41 | void detect_distro(void) { 42 | OSVERSIONINFO vers_info; 43 | int major, minor; 44 | 45 | vers_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 46 | GetVersionEx(&vers_info); 47 | major = vers_info.dwMajorVersion; 48 | minor = vers_info.dwMinorVersion; 49 | 50 | /* if distro_str was NOT set by the -D flag */ 51 | if (STREQ(distro_str, "Unknown")) { 52 | switch (major) { 53 | case 10: 54 | safe_strncpy(distro_str, "Microsoft Windows 10", MAX_STRLEN); 55 | break; 56 | case 6: 57 | switch (minor) { 58 | case 3: 59 | safe_strncpy(distro_str, "Microsoft Windows 8.1", MAX_STRLEN); 60 | break; 61 | case 2: 62 | safe_strncpy(distro_str, "Microsoft Windows 8", MAX_STRLEN); 63 | break; 64 | case 1: 65 | safe_strncpy(distro_str, "Microsoft Windows 7", MAX_STRLEN); 66 | break; 67 | case 0: 68 | safe_strncpy(distro_str, "Microsoft Windows Vista", MAX_STRLEN); 69 | break; 70 | } 71 | break; 72 | case 5: 73 | switch (minor) { 74 | case 1: 75 | safe_strncpy(distro_str, "Microsoft Windows XP", MAX_STRLEN); 76 | break; 77 | case 0: 78 | safe_strncpy(distro_str, "Microsoft Windows 2000", MAX_STRLEN); 79 | break; 80 | } 81 | break; 82 | default: 83 | safe_strncpy(distro_str, "Microsoft Windows", MAX_STRLEN); 84 | break; 85 | } 86 | } 87 | 88 | // TODO: This should really go somewhere else. 89 | if (major == 10 || (major == 6 && (minor == 3 || minor == 2))) { 90 | safe_strncpy(host_color, TLBL, MAX_STRLEN); 91 | } else { 92 | safe_strncpy(host_color, TRED, MAX_STRLEN); 93 | } 94 | 95 | return; 96 | } 97 | 98 | /* detect_host 99 | detects the computer's hostname and active user and formats them 100 | */ 101 | void detect_host(void) { 102 | char *given_user = "Unknown"; 103 | char given_host[MAX_STRLEN] = "Unknown"; 104 | 105 | given_user = malloc(sizeof(char) * MAX_STRLEN); 106 | if (!given_user) { 107 | ERR_REPORT("Memory allocation failed in detect_host."); 108 | exit(1); 109 | } 110 | 111 | DWORD username_len = MAX_STRLEN; 112 | GetUserName(given_user, &username_len); 113 | #ifdef __MINGW32__ 114 | DWORD hostname_len = MAX_STRLEN; 115 | GetComputerNameEx(ComputerNameDnsHostname, given_host, &hostname_len); 116 | #else 117 | gethostname(given_host, MAX_STRLEN); 118 | #endif 119 | 120 | snprintf(host_str, MAX_STRLEN, "%s%s%s%s@%s%s%s%s", host_color, given_user, TNRM, TWHT, TNRM, 121 | host_color, given_host, TNRM); 122 | 123 | free(given_user); 124 | 125 | return; 126 | } 127 | 128 | /* detect_kernel 129 | detects the computer's kernel 130 | */ 131 | void detect_kernel(void) { 132 | OSVERSIONINFO kern_info; 133 | SYSTEM_INFO arch_info; 134 | char arch_str[MAX_STRLEN]; 135 | 136 | ZeroMemory(&kern_info, sizeof(OSVERSIONINFO)); 137 | kern_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 138 | GetVersionEx(&kern_info); 139 | 140 | GetNativeSystemInfo(&arch_info); 141 | 142 | if (arch_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { 143 | safe_strncpy(arch_str, "AMD64", MAX_STRLEN); 144 | } else if (arch_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) { 145 | safe_strncpy(arch_str, "ARM", MAX_STRLEN); 146 | } else if (arch_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { 147 | safe_strncpy(arch_str, "IA64", MAX_STRLEN); 148 | } else if (arch_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { 149 | safe_strncpy(arch_str, "x86", MAX_STRLEN); 150 | } else { 151 | safe_strncpy(arch_str, "Unknown", MAX_STRLEN); 152 | } 153 | 154 | snprintf(kernel_str, MAX_STRLEN, "Windows NT %d.%d build %d (%s)", (int)kern_info.dwMajorVersion, 155 | (int)kern_info.dwMinorVersion, (int)kern_info.dwBuildNumber, arch_str); 156 | 157 | return; 158 | } 159 | 160 | /* detect_uptime 161 | detects the computer's uptime 162 | */ 163 | void detect_uptime(void) { 164 | long uptime = 0; 165 | unsigned int secs = 0; 166 | unsigned int mins = 0; 167 | unsigned int hrs = 0; 168 | unsigned int days = 0; 169 | 170 | uptime = GetTickCount(); /* known problem: will rollover after 49.7 days */ 171 | uptime /= 1000; 172 | 173 | split_uptime(uptime, &secs, &mins, &hrs, &days); 174 | 175 | if (days > 0) 176 | snprintf(uptime_str, MAX_STRLEN, "%dd %dh %dm %ds", days, hrs, mins, secs); 177 | else 178 | snprintf(uptime_str, MAX_STRLEN, "%dh %dm %ds", hrs, mins, secs); 179 | 180 | return; 181 | } 182 | 183 | /* detect_pkgs 184 | detects the number of packages installed on the computer 185 | */ 186 | void detect_pkgs(void) { 187 | #ifndef __MINGW32__ /* maybe count Chocolatey packages? */ 188 | const char *pattern; 189 | glob_t globbuf; 190 | 191 | #if defined(__MSYS__) 192 | /* MSYS2 */ 193 | /* ignores: ALPM_DB_VERSION */ 194 | pattern = "/var/lib/pacman/local/*-*"; 195 | #else 196 | /* Cygwin */ 197 | /* ignores: installed.db setup.rc timestamp */ 198 | pattern = "/etc/setup/*.lst.*"; 199 | #endif 200 | 201 | globbuf.gl_offs = 1; 202 | glob(pattern, GLOB_DOOFFS, NULL, &globbuf); 203 | snprintf(pkgs_str, MAX_STRLEN, "%d", (int)globbuf.gl_pathc); 204 | globfree(&globbuf); 205 | #endif /* !__MINGW32__ */ 206 | 207 | return; 208 | } 209 | 210 | /* detect_cpu 211 | detects the computer's CPU brand/name-string 212 | */ 213 | void detect_cpu(void) { 214 | HKEY hkey; 215 | DWORD str_size = MAX_STRLEN; 216 | 217 | RegOpenKey(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hkey); 218 | RegQueryValueEx(hkey, "ProcessorNameString", 0, NULL, (BYTE *)cpu_str, &str_size); 219 | 220 | return; 221 | } 222 | 223 | /* detect_gpu 224 | detects the computer's GPU brand/name-string 225 | */ 226 | void detect_gpu(void) { 227 | HKEY hkey; 228 | DWORD str_size = MAX_STRLEN; 229 | 230 | RegOpenKey(HKEY_LOCAL_MACHINE, 231 | "SYSTEM\\ControlSet001\\Control\\Class\\" 232 | "{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\Settings", 233 | &hkey); 234 | RegQueryValueEx(hkey, "Device Description", 0, NULL, (BYTE *)gpu_str, &str_size); 235 | 236 | return; 237 | } 238 | 239 | /* detect_disk 240 | detects the computer's total disk capacity and usage 241 | */ 242 | void detect_disk(void) { 243 | char *disk_unit; 244 | long long totalBytes, freeBytes, usedBytes, disk_used, disk_total, disk_percentage; 245 | 246 | char drive[MAX_STRLEN]; 247 | #ifdef __MINGW32__ 248 | char buf[MAX_STRLEN]; 249 | 250 | if (GetSystemDirectory(buf, MAX_STRLEN)) { 251 | snprintf(drive, MAX_STRLEN, "%c:\\", buf[0]); 252 | } else { 253 | if (GetEnvironmentVariable("SystemDrive", buf, MAX_STRLEN)) { 254 | snprintf(drive, MAX_STRLEN, "%c:\\", buf[0]); 255 | } else { 256 | snprintf(drive, MAX_STRLEN, "C:\\"); 257 | } 258 | } 259 | #else 260 | FILE *disk_file; 261 | 262 | disk_file = popen("cygpath -w / | head -c3", "r"); 263 | fscanf(disk_file, "%s", (char *)drive); 264 | pclose(disk_file); 265 | #endif 266 | 267 | if (GetDiskFreeSpaceEx(drive, NULL, (PULARGE_INTEGER)&totalBytes, (PULARGE_INTEGER)&freeBytes)) { 268 | usedBytes = totalBytes - freeBytes; 269 | 270 | if (usedBytes >= GB) { 271 | disk_used = usedBytes / GB; 272 | disk_unit = "G"; 273 | } else { 274 | disk_used = usedBytes / MB; 275 | disk_unit = "M"; 276 | } 277 | 278 | disk_total = totalBytes / GB; 279 | disk_percentage = (usedBytes * 100) / totalBytes; 280 | 281 | snprintf(disk_str, MAX_STRLEN, "%lld%s / %lldG (%lld%%) [%s]", disk_used, disk_unit, disk_total, 282 | disk_percentage, drive); 283 | } 284 | 285 | return; 286 | } 287 | 288 | /* detect_mem 289 | detects the computer's total and used RAM 290 | */ 291 | void detect_mem(void) { 292 | long long total_mem = 0; 293 | long long used_mem = 0; 294 | MEMORYSTATUSEX mem_stat; 295 | 296 | mem_stat.dwLength = sizeof(mem_stat); 297 | GlobalMemoryStatusEx(&mem_stat); 298 | 299 | total_mem = (long long)mem_stat.ullTotalPhys / MB; 300 | used_mem = total_mem - ((long long)mem_stat.ullAvailPhys / MB); 301 | 302 | snprintf(mem_str, MAX_STRLEN, "%lld%s / %lld%s", used_mem, "MB", total_mem, "MB"); 303 | 304 | return; 305 | } 306 | 307 | /* detect_shell 308 | detects the shell currently running on the computer 309 | -- 310 | CAVEAT: shell version detection relies on the standard versioning format for 311 | each shell. If any shell's older (or newer versions) suddenly begin to use a new 312 | scheme, the version may be displayed incorrectly. 313 | -- 314 | */ 315 | void detect_shell(void) { 316 | char *shell_name; 317 | #ifndef __MINGW32__ 318 | FILE *shell_file; 319 | char vers_str[MAX_STRLEN]; 320 | #endif 321 | 322 | shell_name = getenv("SHELL"); 323 | 324 | if (shell_name == NULL) { 325 | if (error) 326 | ERR_REPORT("Could not detect a shell."); 327 | 328 | return; 329 | } 330 | 331 | #ifndef __MINGW32__ 332 | if (STREQ(shell_name, "/bin/sh")) { 333 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 334 | } else if (strstr(shell_name, "bash")) { 335 | shell_file = popen("bash --version | head -1", "r"); 336 | fgets(vers_str, MAX_STRLEN, shell_file); 337 | snprintf(shell_str, MAX_STRLEN, "bash %.*s", 17, vers_str + 10); 338 | pclose(shell_file); 339 | } else if (strstr(shell_name, "zsh")) { 340 | shell_file = popen("zsh --version", "r"); 341 | fgets(vers_str, MAX_STRLEN, shell_file); 342 | snprintf(shell_str, MAX_STRLEN, "zsh %.*s", 5, vers_str + 4); 343 | pclose(shell_file); 344 | } else if (strstr(shell_name, "csh")) { 345 | shell_file = popen("csh --version | head -1", "r"); 346 | fgets(vers_str, MAX_STRLEN, shell_file); 347 | snprintf(shell_str, MAX_STRLEN, "csh %.*s", 7, vers_str + 5); 348 | pclose(shell_file); 349 | } else if (strstr(shell_name, "fish")) { 350 | shell_file = popen("fish --version", "r"); 351 | fgets(vers_str, MAX_STRLEN, shell_file); 352 | snprintf(shell_str, MAX_STRLEN, "fish %.*s", 13, vers_str + 6); 353 | pclose(shell_file); 354 | } else if (strstr(shell_name, "dash") || strstr(shell_name, "ash") || strstr(shell_name, "ksh")) { 355 | /* i don't have a version detection system for these, yet */ 356 | safe_strncpy(shell_str, shell_name, MAX_STRLEN); 357 | } 358 | #else /* __MINGW32__ */ 359 | /* limited shell detection when running in Cygwin or MSYS2 */ 360 | if (strstr(shell_name, "cmd.exe")) { 361 | safe_strncpy(shell_str, "Command Prompt (cmd.exe)", MAX_STRLEN); 362 | } else if (strstr(shell_name, "PowerShell")) { 363 | safe_strncpy(shell_str, "Windows PowerShell", MAX_STRLEN); 364 | } else if (strstr(shell_name, "/bin/sh")) { 365 | safe_strncpy(shell_str, "POSIX sh", MAX_STRLEN); 366 | } else if (strstr(shell_name, "bash")) { 367 | snprintf(shell_str, MAX_STRLEN, "bash"); 368 | } else if (strstr(shell_name, "zsh")) { 369 | snprintf(shell_str, MAX_STRLEN, "zsh"); 370 | } else if (strstr(shell_name, "csh")) { 371 | snprintf(shell_str, MAX_STRLEN, "csh"); 372 | } else if (strstr(shell_name, "fish")) { 373 | snprintf(shell_str, MAX_STRLEN, "fish"); 374 | } else if (strstr(shell_name, "dash")) { 375 | snprintf(shell_str, MAX_STRLEN, "dash"); 376 | } else if (strstr(shell_name, "ash")) { 377 | snprintf(shell_str, MAX_STRLEN, "ash"); 378 | } else if (strstr(shell_name, "ksh")) { 379 | snprintf(shell_str, MAX_STRLEN, "ksh"); 380 | } 381 | #endif 382 | 383 | return; 384 | } 385 | 386 | /* detect_res 387 | detects the combined resolution of all monitors attached to the computer 388 | */ 389 | void detect_res(void) { 390 | int width = 0; 391 | int height = 0; 392 | 393 | width = GetSystemMetrics(SM_CXVIRTUALSCREEN); 394 | height = GetSystemMetrics(SM_CYVIRTUALSCREEN); 395 | 396 | snprintf(res_str, MAX_STRLEN, "%dx%d", width, height); 397 | 398 | return; 399 | } 400 | 401 | /* detect_de 402 | detects the desktop environment currently running on top of the OS. 403 | On Windows, this will always be either Luna, Aero, or Metro. 404 | */ 405 | void detect_de(void) { 406 | OSVERSIONINFO vers_info; 407 | int major, minor; 408 | 409 | vers_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 410 | GetVersionEx(&vers_info); 411 | major = vers_info.dwMajorVersion; 412 | minor = vers_info.dwMinorVersion; 413 | 414 | if (major == 10) 415 | safe_strncpy(de_str, "Modern UI/Metro", MAX_STRLEN); 416 | else if (major == 6 && minor >= 2) 417 | safe_strncpy(de_str, "Metro", MAX_STRLEN); 418 | else if (major == 6 && minor <= 1) 419 | safe_strncpy(de_str, "Aero", MAX_STRLEN); 420 | else if (major == 5) 421 | safe_strncpy(de_str, "Luna", MAX_STRLEN); 422 | 423 | return; 424 | } 425 | 426 | /* detect_wm 427 | detects the window manager currently running on top of the OS. 428 | On Windows, this will always be DWM/Explorer. 429 | */ 430 | void detect_wm(void) { 431 | safe_strncpy(wm_str, "DWM/Explorer", MAX_STRLEN); 432 | 433 | return; 434 | } 435 | 436 | /* detect_wm_theme 437 | On Windows, detects the current theme running on DWM. 438 | */ 439 | void detect_wm_theme(void) { 440 | char tmp_theme[MAX_STRLEN] = "Unknown"; 441 | char *suffix; 442 | HKEY hkey; 443 | DWORD str_size = MAX_STRLEN; 444 | 445 | RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes", &hkey); 446 | RegQueryValueEx(hkey, "CurrentTheme", 0, NULL, (BYTE *)tmp_theme, &str_size); 447 | 448 | /* if we successfully retrieved a theme from the registry */ 449 | if (!STREQ(tmp_theme, "Unknown")) { 450 | safe_strncpy(tmp_theme, basename(tmp_theme), MAX_STRLEN); 451 | suffix = tmp_theme + strlen(tmp_theme) - 6; 452 | 453 | /* if our retrieved theme ends with .theme, truncate it */ 454 | if (STREQ(suffix, ".theme")) { 455 | tmp_theme[strlen(tmp_theme) - 6] = '\0'; 456 | } 457 | } 458 | 459 | safe_strncpy(wm_theme_str, tmp_theme, MAX_STRLEN); 460 | 461 | return; 462 | } 463 | 464 | /* detect_gtk 465 | On Windows, detects the font associated with Cygwin's terminal (mintty) 466 | */ 467 | void detect_gtk(void) { 468 | #ifdef __MINGW32__ 469 | snprintf(gtk_str, MAX_STRLEN, "none"); 470 | #else 471 | FILE *gtk_file; 472 | char font_str[MAX_STRLEN] = "Unknown"; 473 | 474 | gtk_file = popen("grep '^Font=.*' < $HOME/.minttyrc | " 475 | "grep -o '[0-9A-z ]*$' | tr -d '\\r\\n'", 476 | "r"); 477 | fgets(font_str, MAX_STRLEN, gtk_file); 478 | pclose(gtk_file); 479 | 480 | snprintf(gtk_str, MAX_STRLEN, "%s (Font)", font_str); 481 | #endif 482 | 483 | return; 484 | } 485 | -------------------------------------------------------------------------------- /src/scripts/detectgpu: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # detectgpu 3 | # attempt to detect and output the name and model of the computer's GPU 4 | # only meant to be run on Linux/*BSD 5 | # Original Author: Brett Bohnenkamper (KittyKatt) in screenfetch-dev 6 | # Modified to stand alone by William Woodruff (woodruffw) in screenfetch-c 7 | 8 | if [ -n "$(type -p lspci)" ]; then 9 | # gpu_info=$(lspci 2> /dev/null | grep VGA) 10 | # gpu=$(echo "$gpu_info" | grep -oE '\[.*\]' | sed 's/\[//;s/\]//') 11 | # gpu=$(echo "${gpu}" | sed -n '1h;2,$H;${g;s/\n/, /g;p}') 12 | 13 | # better gpu detection with g/awk than sed 14 | # sed requires '[manufactor] dummy info [model name]' 15 | # here 'manufactor' and 'model name' have to be in '[]', 16 | # otherwise the output will be awkward. g/awk seperates 17 | # the output from the first '[' onwards. Try to parse this with sed and g/awk: 18 | # 01:05.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] RS780L Radeon 3000 19 | 20 | gpu=$(lspci | awk -F '[' '/VGA/ {gsub("]","");OFS="";print $2,$3}') 21 | 22 | elif [[ -n "$(type -p glxinfo)" && -z "$gpu" ]]; then 23 | gpu_info=$(glxinfo 2>/dev/null) 24 | gpu=$(echo "$gpu_info" | grep "OpenGL renderer string") 25 | gpu=$(echo "$gpu" | cut -d ':' -f2) 26 | gpu="${gpu:1}" 27 | gpu_info=$(echo "$gpu_info" | grep "OpenGL vendor string") 28 | fi 29 | 30 | if [ -n "$gpu" ];then 31 | if [ $(echo "$gpu_info" | grep -i nvidia | wc -l) -gt 0 ] ; then 32 | gpu_info="NVidia " 33 | elif [ $(echo "$gpu_info" | grep -i intel | wc -l) -gt 0 ] ; then 34 | gpu_info="Intel " 35 | elif [ $(echo "$gpu_info" | grep -i amd | wc -l) -gt 0 ] ; then 36 | gpu_info="AMD " 37 | elif [[ $(echo "$gpu_info" | grep -i ati | wc -l) -gt 0 || $(echo "$gpu_info" | grep -i radeon | wc -l) -gt 0 ]] ; then 38 | gpu_info="ATI " 39 | else 40 | gpu_info=$(echo "$gpu_info" | cut -d ':' -f2) 41 | gpu_info="${gpu_info:1} " 42 | fi 43 | gpu="${gpu}" 44 | else 45 | gpu="Unknown" 46 | fi 47 | 48 | echo ${gpu} 49 | -------------------------------------------------------------------------------- /src/scripts/detectgtk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # detectgtk 3 | # detect and output any GTK information, if present 4 | # only meant to be run on Linux/*BSD 5 | # DEPENDS UPON: detectde for the name of the DE 6 | # Original Author: Brett Bohnenkamper (KittyKatt) in screenfetch-dev 7 | # Modified to stand alone by William Woodruff (woodruffw) in screenfetch-c 8 | 9 | gtk2Theme="Unknown" 10 | gtk3Theme="Unknown" 11 | gtkIcons="Unknown" 12 | gtkFont="Unknown" 13 | 14 | DE="${1,,}" 15 | 16 | home_gtkrc_two="$HOME/.gtkrc-2.0" 17 | usr_gtkrc_two='/usr/share/gtk-2.0/gtkrc' 18 | home_gtkrc_mine="$HOME/.gtkrc.mine" 19 | 20 | case $DE in 21 | 'kde'*) 22 | if type - p kde4-config >/dev/null 2>&1; then 23 | KDE_CONFIG_DIR=$(kde4-config --localprefix) 24 | if [[ -d ${KDE_CONFIG_DIR} ]]; then 25 | if [[ -f "${KDE_CONFIG_DIR}/share/config/kdeglobals" ]]; then 26 | KDE_CONFIG_FILE="${KDE_CONFIG_DIR}/share/config/kdeglobals" 27 | fi 28 | fi 29 | elif type -p kde5-config >/dev/null 2>&1; then 30 | KDE_CONFIG_DIR=$(kde5-config --localprefix) 31 | if [[ -d ${KDE_CONFIG_DIR} ]]; then 32 | if [[ -f "${KDE_CONFIG_DIR}/share/config/kdeglobals" ]]; then 33 | KDE_CONFIG_FILE="${KDE_CONFIG_DIR}/share/config/kdeglobals" 34 | fi 35 | fi 36 | elif type -p kde-config >/dev/null 2>&1; then 37 | KDE_CONFIG_DIR=$(kde-config --localprefix) 38 | if [[ -d ${KDE_CONFIG_DIR} ]]; then 39 | if [[ -f "${KDE_CONFIG_DIR}/share/config/kdeglobals" ]]; then 40 | KDE_CONFIG_FILE="${KDE_CONFIG_DIR}/share/config/kdeglobals" 41 | fi 42 | fi 43 | fi 44 | if [[ -n ${KDE_CONFIG_FILE} ]]; then 45 | if grep -q "widgetStyle=" "${KDE_CONFIG_FILE}"; then 46 | gtk2Theme=$(awk -F "=" '/widgetStyle=/ {print $2}' "${KDE_CONFIG_FILE}") 47 | elif grep -q "colorScheme=" "${KDE_CONFIG_FILE}"; then 48 | gtk2Theme=$(awk -F "=" '/colorScheme=/ {print $2}' "${KDE_CONFIG_FILE}") 49 | fi 50 | if grep -q "Theme=" "${KDE_CONFIG_FILE}"; then 51 | gtkIcons=$(awk -F "=" '/Theme=/ {print $2}' "${KDE_CONFIG_FILE}") 52 | fi 53 | if grep -q "Font=" "${KDE_CONFIG_FILE}"; then 54 | gtkFont=$(awk -F "=" '/font=/ {print $2}' "${KDE_CONFIG_FILE}") 55 | fi 56 | fi 57 | if [[ -f ${home_gtkrc_two} ]]; then 58 | gtk2Theme=$(grep '^gtk-theme-name' ${home_gtkrc_two} | awk -F '=' '{print $2}') 59 | gtk2Theme=${gtk2Theme//\"/} 60 | gtkIcons=$(grep '^gtk-icon-theme-name' ${home_gtkrc_two} | awk -F '=' '{print $2}') 61 | gtkIcons=${gtkIcons//\"/} 62 | gtkFont=$(grep 'font_name' ${home_gtkrc_two} | awk -F '=' '{print $2}') 63 | gtkFont=${gtkFont//\"/} 64 | fi 65 | if [[ -f $HOME/.config/gtk-3.0/settings.ini ]]; then 66 | gtk3Theme=$(grep '^gtk-theme-name=' $HOME/.config/gtk-3.0/settings.ini | awk -F '=' '{print $2}') 67 | fi 68 | ;; 69 | 'cinnamon'*) 70 | if type -p gsettings >/dev/null 2>&1; then 71 | gtk3Theme=$(gsettings get org.gnome.desktop.interface gtk-theme) 72 | gtk3Theme=${gtk3Theme//"'"} 73 | gtk2Theme=${gtk3Theme} 74 | gtkIcons=$(gsettings get org.gnome.desktop.interface icon-theme) 75 | gtkIcons=${gtkIcons//"'"} 76 | gtkFont=$(gsettings get org.gnome.desktop.interface font-name) 77 | gtkFont=${gtkFont//"'"} 78 | if [ "$background_detect" == "1" ]; then gtkBackground=$(gsettings get org.gnome.desktop.background picture-uri); fi 79 | fi 80 | ;; 81 | 'gnome'*|'unity'*) 82 | if type -p gsettings >/dev/null 2>&1; then 83 | gtk3Theme=$(gsettings get org.gnome.desktop.interface gtk-theme) 84 | gtk3Theme=${gtk3Theme//"'"} 85 | gtk2Theme=${gtk3Theme} 86 | gtkIcons=$(gsettings get org.gnome.desktop.interface icon-theme) 87 | gtkIcons=${gtkIcons//"'"} 88 | gtkFont=$(gsettings get org.gnome.desktop.interface font-name) 89 | gtkFont=${gtkFont//"'"} 90 | if [ "$background_detect" == "1" ]; then gtkBackground=$(gsettings get org.gnome.desktop.background picture-uri); fi 91 | elif type -p gconftool-2 >/dev/null 2>&1; then 92 | gtk2Theme=$(gconftool-2 -g /desktop/gnome/interface/gtk_theme) 93 | gtkIcons=$(gconftool-2 -g /desktop/gnome/interface/icon_theme) 94 | gtkFont=$(gconftool-2 -g /desktop/gnome/interface/font_name) 95 | if [ "$background_detect" == "1" ]; then 96 | gtkBackgroundFull=$(gconftool-2 -g /desktop/gnome/background/picture_filename) 97 | gtkBackground=$(echo "$gtkBackgroundFull" | awk -F "/" '{print $NF}') 98 | fi 99 | fi 100 | ;; 101 | 'mate'*) 102 | #if type -p gsettings >/dev/null 2&>1; then 103 | gtk3Theme=$(gsettings get org.mate.interface gtk-theme) 104 | # gtk3Theme=${gtk3Theme//"'"} 105 | gtk2Theme=${gtk3Theme} 106 | gtkIcons=$(gsettings get org.mate.interface icon-theme) 107 | gtkIcons=${gtkIcons//"'"} 108 | gtkFont=$(gsettings get org.mate.interface font-name) 109 | gtkFont=${gtkFont//"'"} 110 | #fi 111 | ;; 112 | 'xfce'*) 113 | if type -p xfconf-query >/dev/null 2>&1; then 114 | gtk2Theme=$(xfconf-query -c xsettings -p /Net/ThemeName) 115 | fi 116 | if type -p xfconf-query >/dev/null 2>&1; then 117 | gtkIcons=$(xfconf-query -c xsettings -p /Net/IconThemeName) 118 | fi 119 | if type -p xfconf-query >/dev/null 2>&1; then 120 | gtkFont=$(xfconf-query -c xsettings -p /Gtk/FontName) 121 | fi 122 | ;; 123 | 'lxde'*) 124 | if [ -f ${XDG_CONFIG_HOME:-${HOME}/.config}/lxde/config ]; then 125 | lxdeconf="/lxde/config" 126 | elif [ $distro == "Trisquel" ]; then 127 | lxdeconf="" 128 | elif [ "$distro" == "FreeBSD" ]; then 129 | lxdeconf="" 130 | else 131 | lxdeconf="/lxsession/LXDE/desktop.conf" 132 | fi 133 | # TODO: Clean me. 134 | if grep -q "sNet\/ThemeName" ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf 2>/dev/null; then 135 | gtk2Theme=$(awk -F '=' '/sNet\/ThemeName/ {print $2}' ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf) 136 | fi 137 | if grep -q IconThemeName ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf 2>/dev/null; then 138 | gtkIcons=$(awk -F '=' '/sNet\/IconThemeName/ {print $2}' ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf) 139 | fi 140 | if grep -q FontName ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf 2>/dev/null; then 141 | gtkFont=$(awk -F '=' '/sGtk\/FontName/ {print $2}' ${XDG_CONFIG_HOME:-${HOME}/.config}$lxdeconf) 142 | fi 143 | ;; 144 | # /home/me/.config/rox.sourceforge.net/ROX-Session/Settings.xml 145 | *) # Lightweight or No DE Found 146 | if [ -f ${home_gtkrc_two} ]; then 147 | if grep -q gtk-theme ${home_gtkrc_two}; then 148 | gtk2Theme=$(awk -F '"' '/^gtk-theme/ {print $2}' ${home_gtkrc_two}) 149 | fi 150 | if grep -q icon-theme ${home_gtkrc_two}; then 151 | gtkIcons=$(awk -F '"' '/^gtk-icon-theme/ {print $2}' ${home_gtkrc_two}) 152 | fi 153 | if grep -q font ${home_gtkrc_two}; then 154 | gtkFont=$(awk -F '"' '/^gtk-font-name/ {print $2}' ${home_gtkrc_two}) 155 | fi 156 | fi 157 | # $HOME/.gtkrc.mine theme detect only 158 | if [[ -f ${home_gtkrc_mine} && ! -f ${home_gtkrc_two} ]]; then 159 | if grep -q "^include" ${home_gtkrc_mine}; then 160 | gtk2Theme=$(grep '^include.*gtkrc' ${home_gtkrc_mine} | awk -F "/" '{ print $5 }') 161 | fi 162 | if grep -q "^gtk-icon-theme-name" ${home_gtkrc_mine}; then 163 | gtkIcons=$(grep '^gtk-icon-theme-name' ${home_gtkrc_mine} | awk -F '"' '{print $2}') 164 | fi 165 | fi 166 | # /usr/share/gtk-2.0/gtkrc 167 | if [[ -f ${usr_gtkrc_two} && ! -f ${home_gtkrc_mine} && ! -f ${home_gtkrc_two} ]]; then 168 | if grep -q gtk-theme ${usr_gtkrc_two}; then 169 | gtk2Theme=$(awk -F '"' '/^gtk-theme/ {print $2}' ${usr_gtkrc_two}) 170 | fi 171 | if grep -q icon-theme ${usr_gtkrc_two}; then 172 | gtkIcons=$(awk -F '"' '/^gtk-icon-theme/ {print $2}' ${usr_gtkrc_two}) 173 | fi 174 | if grep -q font ${usr_gtkrc_two}; then 175 | gtkFont=$(awk -F '"' '/^gtk-font-name/ {print $2}' ${usr_gtkrc_two}) 176 | fi 177 | fi 178 | # /etc/gtk-2.0/gtkrc compatability 179 | etc_gtkrc_two='/etc/gtk-2.0/gtkrc' 180 | if [[ -f ${etc_gtkrc_two} && ! -f ${home_gtkrc_two} && ! -f ${home_gtkrc_mine} && ! -f ${usr_gtkrc_two} ]]; then 181 | if grep -q gtk-theme-name ${etc_gtkrc_two}; then 182 | gtk2Theme=$(awk -F '"' '/^gtk-theme-name/ {print $2}' ${etc_gtkrc_two}) 183 | fi 184 | if grep -q gtk-fallback-theme-name ${etc_gtkrc_two} && ! [ "x$gtk2Theme" = "x" ]; then 185 | gtk2Theme=$(awk -F '"' '/^gtk-fallback-theme-name/ {print $2}' ${etc_gtkrc_two}) 186 | fi 187 | if grep -q icon-theme ${etc_gtkrc_two}; then 188 | gtkIcons=$(awk -F '"' '/^icon-theme/ {print $2}' ${etc_gtkrc_two}) 189 | fi 190 | if grep -q gtk-fallback-icon-theme ${etc_gtkrc_two} && ! [ "x$gtkIcons" = "x" ]; then 191 | gtkIcons=$(awk -F '"' '/^gtk-fallback-icon-theme/ {print $2}' ${etc_gtkrc_two}) 192 | fi 193 | if grep -q font ${etc_gtkrc_two}; then 194 | gtkFont=$(awk -F '"' '/^gtk-font-name/ {print $2}' ${etc_gtkrc_two}) 195 | fi 196 | fi 197 | # EXPERIMENTAL gtk3 Theme detection 198 | home_conf_gtk_three="$HOME/.config/gtk-3.0/settings.ini" 199 | if [ -f ${home_conf_gtk_three} ]; then 200 | if grep -q gtk-theme-name ${home_conf_gtk_three}; then 201 | gtk3Theme=$(awk -F '=' '/^gtk-theme-name/ {print $2}' ${home_conf_gtk_three}) 202 | fi 203 | fi 204 | # Proper gtk3 Theme detection 205 | #if [ $(which gsettings) ] && [ "$distro" != "Mac OS X" ]; then 206 | # gtk3Theme="$(gsettings get org.gnome.desktop.interface gtk-theme | tr -d \"\'\")" 207 | #fi 208 | # gsettings and xfconf-query should only be used in their desktop environments 209 | #if type -p gsettings >/dev/null 2>&1; then 210 | # gtk3Theme=$(gsettings get org.gnome.desktop.interface gtk-theme 2>/dev/null) 211 | # gtk3Theme=${gtk3Theme//"'"} 212 | #fi 213 | # ROX-Filer icon detect only 214 | if [ -a ${XDG_CONFIG_HOME:-${HOME}/.config}/rox.sourceforge.net/ROX-Filer/Options ]; then 215 | gtkIcons=$(awk -F '[>,<]' '/^icon_theme/ {print $3}' ${XDG_CONFIG_HOME:-${HOME}/.config}/rox.sourceforge.net/ROX-Filer/Options) 216 | fi 217 | # E17 detection 218 | if [ $E_ICON_THEME ]; then 219 | gtkIcons=${E_ICON_THEME} 220 | gtk2Theme="Not available." 221 | gtkFont="Not available." 222 | fi 223 | # Background Detection (feh, nitrogen) 224 | if [ "$background_detect" == "1" ]; then 225 | if [ -a $HOME/.fehbg ]; then 226 | gtkBackgroundFull=$(awk -F "'" '/feh --bg/{print $2}' $HOME/.fehbg 2>/dev/null) 227 | gtkBackground=$(echo "$gtkBackgroundFull" | awk -F "/" '{print $NF}') 228 | elif [ -a ${XDG_CONFIG_HOME:-${HOME}/.config}/nitrogen/bg-saved.cfg ]; then 229 | gtkBackground=$(awk -F "/" '/file=/ {print $NF}' ${XDG_CONFIG_HOME:-${HOME}/.config}/nitrogen/bg-saved.cfg) 230 | fi 231 | fi 232 | ;; 233 | esac 234 | 235 | echo $gtk2Theme 236 | echo $gtk3Theme 237 | echo $gtkIcons 238 | echo $gtkFont 239 | 240 | 241 | -------------------------------------------------------------------------------- /src/scripts/detectwm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # detectwm 3 | # detect and output the name of the Window Manager, if present 4 | # only meant to be run on Linux/*BSD 5 | # Original Author: Brett Bohnenkamper (KittyKatt) in screenfetch-dev 6 | # Modified to stand alone by William Woodruff (woodruffw) in screenfetch-c 7 | 8 | wmnames=( fluxbox openbox blackbox xfwm4 metacity kwin icewm pekwm fvwm dwm awesome wmaker stumpwm musca i3 xmonad ratpoison scrotwm spectrwm wmfs wmii beryl subtle e16 enlightenment sawfish emerald monsterwm dminiwm compiz Finder herbstluftwm ) 9 | WM="Unknown" 10 | if [[ -n ${DISPLAY} ]]; then 11 | if type -p xprop >/dev/null 2>&1; then 12 | WM=$(xprop -root _NET_SUPPORTING_WM_CHECK) 13 | if [[ "$WM" =~ 'Unknown' ]]; then 14 | WM="Unknown" 15 | elif [[ "$WM" =~ 'Unknown' ]]; then 16 | WM="Unknown" 17 | elif [[ "$WM" =~ '[Ii]nvalid window id format' ]]; then 18 | WM="Unknown" 19 | elif [[ "$WM" =~ "no such" ]]; then 20 | WM="Unknown" 21 | else 22 | WM=${WM//* } 23 | WM=$(xprop -id ${WM} 8s _NET_WM_NAME) 24 | WM=$(echo $(WM=${WM//*= }; echo ${WM//\"})) 25 | fi 26 | fi 27 | if [[ ${WM} == "Unknown" ]]; then 28 | for each in $wmnames; do 29 | PID="$(pgrep -U ${UID} $each)" 30 | if [ "$PID" ]; then 31 | case $each in 32 | 'awesome') WM="Awesome";; 33 | 'beryl') WM="Beryl";; 34 | 'blackbox') WM="Blackbox";; 35 | 'cinnamon') WM="Cinnamon";; 36 | 'compiz') WM="Compiz";; 37 | 'dminiwm') WM="dminiwm";; 38 | 'dwm') WM="DWM";; 39 | 'e16') WM="E16";; 40 | 'emerald') WM="Emerald";; 41 | 'enlightenment') WM="E17";; 42 | 'fluxbox') WM="FluxBox";; 43 | 'fvwm') WM="FVWM";; 44 | 'herbstluftwm') WM="herbstluftwm";; 45 | 'icewm') WM="IceWM";; 46 | 'kwin') WM="KWin";; 47 | 'metacity') WM="Metacity";; 48 | 'monsterwm') WM="monsterwm";; 49 | 'musca') WM="Musca";; 50 | 'openbox') WM="OpenBox";; 51 | 'pekwm') WM="PekWM";; 52 | 'ratpoison') WM="Ratpoison";; 53 | 'sawfish') WM="Sawfish";; 54 | 'scrotwm') WM="ScrotWM";; 55 | 'spectrwm') WM="SpectrWM";; 56 | 'stumpwm') WM="StumpWM";; 57 | 'subtle') WM="subtle";; 58 | 'wmaker') WM="WindowMaker";; 59 | 'wmfs') WM="WMFS";; 60 | 'wmii') WM="wmii";; 61 | 'xfwm4') WM="Xfwm4";; 62 | 'xmonad') WM="XMonad";; 63 | 'i3') WM="i3";; 64 | esac 65 | fi 66 | if [[ ${WM} != "Unknown" ]]; then 67 | break 1 68 | fi 69 | done 70 | else 71 | if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then 72 | if [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -gt 1 ]] || [[ ${BASH_VERSINFO[0]} -gt 4 ]]; then 73 | WM=${WM,,} 74 | else 75 | WM="$(tr '[:upper:]' '[:lower:]' <<< ${WM})" 76 | fi 77 | else 78 | WM="$(tr '[:upper:]' '[:lower:]' <<< ${WM})" 79 | fi 80 | case ${WM} in 81 | 'awesome') WM="Awesome";; 82 | 'beryl') WM="Beryl";; 83 | 'blackbox') WM="Blackbox";; 84 | 'cinnamon') WM="Cinnamon";; 85 | 'compiz') WM="Compiz";; 86 | 'dminiwm') WM="dminiwm";; 87 | 'dwm') WM="DWM";; 88 | 'e16') WM="E16";; 89 | 'emerald') WM="Emerald";; 90 | 'enlightenment') WM="E17";; 91 | 'fluxbox') WM="FluxBox";; 92 | 'fvwm') WM="FVWM";; 93 | 'herbstluftwm') WM="herbstluftwm";; 94 | 'icewm') WM="IceWM";; 95 | 'kwin') WM="KWin";; 96 | 'metacity') WM="Metacity";; 97 | 'monsterwm') WM="monsterwm";; 98 | 'musca') WM="Musca";; 99 | 'openbox') WM="OpenBox";; 100 | 'pekwm') WM="PekWM";; 101 | 'ratpoison') WM="Ratpoison";; 102 | 'sawfish') WM="Sawfish";; 103 | 'scrotwm') WM="ScrotWM";; 104 | 'spectrwm') WM="SpectrWM";; 105 | 'stumpwm') WM="StumpWM";; 106 | 'subtle') WM="subtle";; 107 | 'wmaker') WM="WindowMaker";; 108 | 'wmfs') WM="WMFS";; 109 | 'wmii') WM="wmii";; 110 | 'xfwm4') WM="Xfwm4";; 111 | 'xmonad') WM="XMonad";; 112 | 'i3') WM="i3";; 113 | esac 114 | fi 115 | fi 116 | 117 | printf $WM -------------------------------------------------------------------------------- /src/scripts/detectwmtheme: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # detectwmtheme 3 | # detect and output the name of the theme used in the Window Manager, if present 4 | # only meant to be run on Linux/*BSD 5 | # DEPENDS UPON: detectwm for the name of the WM 6 | # Original Author: Brett Bohnenkamper (KittyKatt) in screenfetch-dev 7 | # Modified to stand alone by William Woodruff (woodruffw) in screenfetch-c 8 | 9 | Win_theme="Unknown" 10 | WM=$1 11 | case $WM in 12 | 'Awesome') if [ -f ${XDG_CONFIG_HOME:-${HOME}/.config}/awesome/rc.lua ]; then Win_theme="$(grep -e '^[^-].*\(theme\|beautiful\).*lua' ${XDG_CONFIG_HOME:-${HOME}/.config}/awesome/rc.lua | grep '[a-zA-Z0-9]\+/[a-zA-Z0-9]\+.lua' -o | cut -d'/' -f1 | head -n1)"; fi;; 13 | 'BlackBox') if [ -f $HOME/.blackboxrc ]; then Win_theme="$(awk -F"/" '/styleFile/ {print $NF}' $HOME/.blackboxrc)"; fi;; 14 | 'Beryl') Win_theme="Unknown";; 15 | 'Cinnamon') Win_theme="$(gsettings get org.cinnamon.theme name)";; 16 | 'Compiz'|'Mutter'*|'GNOME Shell') 17 | if type -p gsettings >/dev/null 2>&1; then 18 | Win_theme="$(gsettings get org.gnome.desktop.wm.preferences theme)" 19 | Win_theme=${Win_theme//"'"} 20 | elif type -p gconftool-2 >/dev/null 2>&1; then 21 | Win_theme=$(gconftool-2 -g /apps/metacity/general/theme) 22 | fi 23 | ;; 24 | 'dminiwm') Win_theme="Unknown";; 25 | 'DWM') Win_theme="Unknown";; 26 | 'E16') Win_theme="$(awk -F"= " '/theme.name/ {print $2}' $HOME/.e16/e_config--0.0.cfg)";; 27 | 'E17'|'Enlightenment') 28 | if [ "$(which eet 2>/dev/null)" ]; then 29 | econfig="$(eet -d $HOME/.e/e/config/standard/e.cfg config | awk '/value \"file\" string.*.edj/{ print $4 }')" 30 | econfigend="${econfig##*/}" 31 | Win_theme=${econfigend%.*} 32 | fi 33 | ;; 34 | #E17 doesn't store cfg files in text format so for now get the profile as opposed to theme. atyoung 35 | #TODO: Find a way to extract and read E17 .cfg files ( google seems to have nothing ). atyoung 36 | 'E17') Win_theme=${E_CONF_PROFILE};; 37 | 'Emerald') if [ -f $HOME/.emerald/theme/theme.ini ]; then Win_theme="$(for a in /usr/share/emerald/themes/* $HOME/.emerald/themes/*; do cmp "$HOME/.emerald/theme/theme.ini" "$a/theme.ini" &>/dev/null && basename "$a"; done)"; fi;; 38 | 'Finder') Win_theme="Unknown";; 39 | 'FluxBox'|'Fluxbox') if [ -f $HOME/.fluxbox/init ]; then Win_theme="$(awk -F"/" '/styleFile/ {print $NF}' $HOME/.fluxbox/init)"; fi;; 40 | 'FVWM') Win_theme="Unknown";; 41 | 'i3') Win_theme="Unknown";; 42 | 'IceWM') if [ -f $HOME/.icewm/theme ]; then Win_theme="$(awk -F"[\",/]" '!/#/ {print $2}' $HOME/.icewm/theme)"; fi;; 43 | 'KWin'*) 44 | if [[ -z $KDE_CONFIG_DIR ]]; then 45 | if type -p kde5-config >/dev/null 2>&1; then 46 | KDE_CONFIG_DIR=$(kde5-config --localprefix) 47 | elif type -p kde4-config >/dev/null 2>&1; then 48 | KDE_CONFIG_DIR=$(kde4-config --localprefix) 49 | elif type -p kde-config >/dev/null 2>&1; then 50 | KDE_CONFIG_DIR=$(kde-config --localprefix) 51 | fi 52 | fi 53 | if [[ -n $KDE_CONFIG_DIR ]]; then 54 | Win_theme=$(awk '/PluginLib=kwin3_/{gsub(/PluginLib=kwin3_/,"",$0); print $0; exit}' $KDE_CONFIG_DIR/share/config/kwinrc) 55 | if [[ -z $Win_theme ]]; then 56 | if [[ -f $KDE_CONFIG_DIR/share/config/kdebugrc ]]; then 57 | Win_theme=$(awk '/(decoration)/ {gsub(/\[/,"",$1); print $1; exit}' $KDE_CONFIG_DIR/share/config/kdebugrc) 58 | if [[ -z $Win_theme ]]; then 59 | Win_theme="Not Found" 60 | fi 61 | else 62 | Win_theme="Not Found" 63 | fi 64 | fi 65 | if [[ $Win_theme != 'Not Found' ]]; then 66 | if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then 67 | if [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -gt 1 ]] || [[ ${BASH_VERSINFO[0]} -gt 4 ]]; then 68 | Win_theme=${Win_theme^} 69 | else 70 | Win_theme="$(tr '[:lower:]' '[:upper:]' <<< ${Win_theme:0:1})${Win_theme:1}" 71 | fi 72 | else 73 | Win_theme="$(tr '[:lower:]' '[:upper:]' <<< ${Win_theme:0:1})${Win_theme:1}" 74 | fi 75 | fi 76 | fi 77 | ;; 78 | 'Marco') 79 | Win_theme="$(gsettings get org.mate.Marco.general theme)" 80 | Win_theme=${Win_theme//"'"} 81 | ;; 82 | 'Metacity') if [ "`gconftool-2 -g /apps/metacity/general/theme`" ]; then Win_theme="$(gconftool-2 -g /apps/metacity/general/theme)"; fi ;; 83 | 'monsterwm') Win_theme="Unknown";; 84 | 'Musca') Win_theme="Unknown";; 85 | 'OpenBox'|'Openbox') 86 | if [ -f ${XDG_CONFIG_HOME:-${HOME}/.config}/openbox/rc.xml ]; then 87 | Win_theme="$(awk -F"[<,>]" '/]" '/ 8 | #include 9 | 10 | int main(void) { 11 | ; 12 | } 13 | -------------------------------------------------------------------------------- /src/tests/x11test.c: -------------------------------------------------------------------------------- 1 | /* x11test.c 2 | * Author: William Woodruff 3 | * 4 | * Tests for the presence of the X11 headers. 5 | */ 6 | 7 | #include 8 | 9 | int main(void) { 10 | ; 11 | } 12 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* util.c 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Utility functions used by screenfetch-c. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | /* standard includes */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* program includes */ 17 | #include "disp.h" 18 | #include "misc.h" 19 | #include "error_flag.h" 20 | 21 | #if defined(__CYGWIN__) || defined(__MSYS__) || defined(__MINGW32__) 22 | #include 23 | #include "plat/win32/bitmap.h" 24 | #endif 25 | 26 | /* safe_strncpy 27 | calls strncpy with the given params, then inserts a terminating NULL 28 | returns a pointer to a string containing the copied data 29 | */ 30 | char *safe_strncpy(char *destination, const char *source, size_t num) { 31 | char *ret = strncpy(destination, source, num); 32 | ret[num - 1] = '\0'; 33 | return ret; 34 | } 35 | 36 | /* split_uptime 37 | splits param uptime into individual time-units 38 | argument long uptime: the uptime, in seconds, to be split 39 | arguments int *secs..*days: pointers to ints for storing the uptime 40 | -- 41 | CAVEAT: uptime MUST be in seconds 42 | -- 43 | */ 44 | void split_uptime(long uptime, unsigned int *secs, unsigned int *mins, unsigned int *hrs, 45 | unsigned int *days) { 46 | *secs = (unsigned int)uptime % 60; 47 | *mins = (unsigned int)(uptime / 60) % 60; 48 | *hrs = (unsigned int)(uptime / 3600) % 24; 49 | *days = (unsigned int)(uptime / 86400); 50 | 51 | return; 52 | } 53 | 54 | /* take_screenshot 55 | takes a screenshot and saves it to $HOME/screenfetch_screenshot.png 56 | */ 57 | void take_screenshot(bool verbose) { 58 | #if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__MINGW32__) 59 | int call_status = 1; 60 | char file_loc[MAX_STRLEN]; 61 | #endif 62 | 63 | printf("%s", "Taking shot in 3.."); 64 | fflush(stdout); 65 | sleep(1); 66 | printf("%s", "2.."); 67 | fflush(stdout); 68 | sleep(1); 69 | printf("%s", "1.."); 70 | fflush(stdout); 71 | sleep(1); 72 | printf("%s\n", "0"); 73 | 74 | #if defined(__CYGWIN__) || defined(__MSYS__) || defined(__MINGW32__) 75 | HDC screen_dc = GetDC(NULL); 76 | HDC mem_dc = CreateCompatibleDC(screen_dc); 77 | 78 | int horiz = GetDeviceCaps(screen_dc, HORZRES); 79 | int vert = GetDeviceCaps(screen_dc, VERTRES); 80 | 81 | HBITMAP bitmap = CreateCompatibleBitmap(screen_dc, horiz, vert); 82 | HBITMAP old_bitmap = SelectObject(mem_dc, bitmap); 83 | 84 | BitBlt(mem_dc, 0, 0, horiz, vert, screen_dc, 0, 0, SRCCOPY); 85 | bitmap = SelectObject(mem_dc, old_bitmap); 86 | 87 | if (createBitmapFile("screenfetch_screenshot.bmp", bitmap, mem_dc) == 0) { 88 | VERBOSE_OUT("Screenshot successfully saved.", ""); 89 | } else { 90 | ERR_REPORT("Problem saving screenshot."); 91 | } 92 | 93 | DeleteDC(screen_dc); 94 | DeleteDC(mem_dc); 95 | 96 | #elif defined(__APPLE__) && defined(__MACH__) 97 | call_status = system("screencapture -x ~/screenfetch_screenshot.png 2> /dev/null"); 98 | #else 99 | call_status = system("scrot ~/screenfetch_screenshot.png 2> /dev/null"); 100 | #endif 101 | 102 | #if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__MINGW32__) 103 | safe_strncpy(file_loc, getenv("HOME"), MAX_STRLEN); 104 | strncat(file_loc, "/screenfetch_screenshot.png", MAX_STRLEN); 105 | 106 | if (FILE_EXISTS(file_loc) && verbose) { 107 | VERBOSE_OUT("Screenshot successfully saved.", ""); 108 | } else if (call_status && error) { 109 | ERR_REPORT("Problem saving screenshot."); 110 | } 111 | #endif 112 | 113 | return; 114 | } 115 | 116 | /* returns 1 if command is in PATH, otherwise 0 117 | */ 118 | #ifdef __linux 119 | int command_in_path(const char *command) { 120 | char *env, *env_copy, *str, *token; 121 | char *file = NULL; 122 | int j, len, rv = 0; 123 | 124 | env = getenv("PATH"); 125 | 126 | if (!command || !env) { 127 | return 0; 128 | } 129 | 130 | env_copy = strdup(env); 131 | 132 | /* though not really needed, stop after 9999 iterations 133 | to prevent any potential endless loop 134 | */ 135 | for (j = 0, str = env_copy; j < 9999; ++j, str = NULL) { 136 | len = strlen(command); 137 | token = strtok(str, ":"); 138 | 139 | if (token == NULL || len == 0) { 140 | rv = 0; 141 | break; 142 | } 143 | 144 | file = malloc(strlen(token) + len + 2); 145 | sprintf(file, "%s/%s", token, command); 146 | 147 | if (FILE_EXISTS(file)) { 148 | rv = 1; 149 | free(file); 150 | break; 151 | } 152 | free(file); 153 | } 154 | 155 | free(env_copy); 156 | return rv; 157 | } 158 | #endif /* __linux */ 159 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* util.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Function prototypes for util.c. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | **/ 8 | 9 | #ifndef SCREENFETCH_C_UTIL_H 10 | #define SCREENFETCH_C_UTIL_H 11 | 12 | char *safe_strncpy(char *destination, const char *source, size_t num); 13 | void split_uptime(long uptime, unsigned int *secs, unsigned int *mins, unsigned int *hrs, 14 | unsigned int *days); 15 | void take_screenshot(bool verbose); 16 | #ifdef __linux 17 | int command_in_path(const char *command); 18 | #endif /* __linux */ 19 | 20 | #endif /* SCREENFETCH_C_UTIL_H */ 21 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | /* version.h 2 | ** Author: William Woodruff 3 | ** ------------- 4 | ** 5 | ** Macros for screenfetch-c's macjor, minor, and release numbers. 6 | ** Like the rest of screenfetch-c, this file is licensed under the MIT license. 7 | */ 8 | 9 | #ifndef SCREENFETCH_C_VERSION_H 10 | #define SCREENFETCH_C_VERSION_H 11 | 12 | /* version macros */ 13 | #define SCREENFETCH_C_VERSION_MAJOR "1" 14 | #define SCREENFETCH_C_VERSION_MINOR "6" 15 | #define SCREENFETCH_C_VERSION_RELEASE "0" 16 | 17 | #endif /* SCREENFETCH_C_VERSION_H */ 18 | --------------------------------------------------------------------------------