├── .browserslistrc ├── .editorconfig ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── COPYING ├── FEATURES.md ├── README.md ├── angular.json ├── binding.gyp ├── build-src ├── after_install.sh ├── after_remove.sh ├── build-release.ts ├── check-release.ts ├── dummy.sh ├── electron-builder.ts ├── fan_table_format.ts ├── inc-version.sh └── package-files.txt ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── screenshots ├── de │ ├── Akku_Netz_TCC.png │ ├── ControlCenter_TCC.png │ ├── DarkTheme_TCC.png │ ├── Profil_Einstellungen_TCC.png │ ├── Profile_TCC.png │ ├── Systemmonitor_TCC.png │ └── Tools_TCC.png ├── en │ ├── ControlCenter_TCC.png │ ├── DarkTheme_TCC.png │ ├── Mains_Battery_TCC.png │ ├── Profile_Settings_TCC.png │ ├── Profiles_TCC.png │ ├── Systemmonitor_TCC.png │ └── Tools_TCC.png └── metainfo │ ├── dark-dashboard.png │ ├── dark-profile-overview.png │ ├── light-aquaris-blue.png │ ├── light-custom-fan.png │ └── light-kbd-bl.png ├── src ├── cameractrls │ ├── cameractrls.py │ └── v4l2_kernel_names.json ├── common │ ├── classes │ │ ├── ChargingPriorityController.ts │ │ ├── ChargingProfileController.ts │ │ ├── ConfigHandler.spec.ts │ │ ├── ConfigHandler.ts │ │ ├── CpuController.spec.ts │ │ ├── CpuController.ts │ │ ├── DBusDisplayBrightnessGnome.ts │ │ ├── DMIController.ts │ │ ├── DeviceIDs.ts │ │ ├── DisplayBacklightController.ts │ │ ├── DriveController.spec.ts │ │ ├── DriveController.ts │ │ ├── FanChartProperties.ts │ │ ├── FanUtils.ts │ │ ├── FnLockController.ts │ │ ├── IntelPStateController.ts │ │ ├── IntelRAPLController.ts │ │ ├── LogicalCpuController.ts │ │ ├── PowerController.ts │ │ ├── PowerSupplyController.ts │ │ ├── StateUtils.ts │ │ ├── SysFsController.ts │ │ ├── SysFsProperties.ts │ │ ├── SysFsPropertyIO.ts │ │ ├── SysFsPropertyInteger.spec.ts │ │ ├── SysFsPropertyIntegerHex.spec.ts │ │ ├── SysFsPropertyNumList.spec.ts │ │ ├── SysFsPropertyNumListExplicit.spec.ts │ │ ├── SysFsPropertyString.spec.ts │ │ ├── SysFsPropertyStringList.spec.ts │ │ ├── TccDBusController.ts │ │ ├── TccPaths.ts │ │ ├── UsbController.spec.ts │ │ ├── UsbController.ts │ │ ├── Utils.ts │ │ ├── Vendor.service.ts │ │ ├── XDisplayRefreshRateController.ts │ │ └── availability.service.ts │ ├── jasmine.json │ └── models │ │ ├── DefaultProfiles.ts │ │ ├── DisplayFreqRes.ts │ │ ├── IDeviceProperty.ts │ │ ├── IDrive.ts │ │ ├── ISystemProfileInfo.ts │ │ ├── TccAutosave.ts │ │ ├── TccFanTable.ts │ │ ├── TccGpuValues.ts │ │ ├── TccPowerSettings.ts │ │ ├── TccProfile.ts │ │ ├── TccSettings.ts │ │ ├── TccWebcamSettings.ts │ │ └── profiles │ │ └── LegacyProfiles.ts ├── dist-data │ ├── com.tuxedocomputers.tcc.metainfo.xml │ ├── com.tuxedocomputers.tccd.conf │ ├── com.tuxedocomputers.tccd.policy │ ├── com.tuxedocomputers.tomte.policy │ ├── hardwarelist.json │ ├── tccd-sleep.service │ ├── tccd.service │ ├── tuxedo-control-center-tray.desktop │ ├── tuxedo-control-center.desktop │ ├── tuxedo-control-center_256.png │ └── tuxedo-control-center_256.svg ├── e-app │ ├── AquarisAPI.ts │ ├── LCT21001.ts │ ├── NgTranslations.ts │ ├── TccTray.ts │ ├── UserConfig.ts │ ├── main.ts │ └── tsconfig.json ├── native-lib │ ├── TuxedoIOAPI.ts │ ├── tuxedo_io_lib │ │ ├── tuxedo_io_api.hh │ │ └── tuxedo_io_ioctl.h │ └── tuxedo_io_napi.cc ├── ng-app │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── aquaris-control │ │ │ ├── aquaris-control.component.html │ │ │ ├── aquaris-control.component.scss │ │ │ ├── aquaris-control.component.spec.ts │ │ │ └── aquaris-control.component.ts │ │ ├── change-crypt-password │ │ │ ├── change-crypt-password.component.html │ │ │ ├── change-crypt-password.component.scss │ │ │ ├── change-crypt-password.component.spec.ts │ │ │ └── change-crypt-password.component.ts │ │ ├── charging-settings │ │ │ ├── charging-settings.component.html │ │ │ ├── charging-settings.component.scss │ │ │ └── charging-settings.component.ts │ │ ├── compatibility.service.spec.ts │ │ ├── compatibility.service.ts │ │ ├── config.service.spec.ts │ │ ├── config.service.ts │ │ ├── cpu-dashboard │ │ │ ├── cpu-dashboard.component.html │ │ │ ├── cpu-dashboard.component.scss │ │ │ ├── cpu-dashboard.component.spec.ts │ │ │ └── cpu-dashboard.component.ts │ │ ├── dashboard.resolver.ts │ │ ├── dbus.service.spec.ts │ │ ├── dbus.service.ts │ │ ├── dialog-choice │ │ │ ├── dialog-choice.component.html │ │ │ ├── dialog-choice.component.scss │ │ │ └── dialog-choice.component.ts │ │ ├── dialog-confirm │ │ │ ├── dialog-confirm.component.html │ │ │ ├── dialog-confirm.component.scss │ │ │ └── dialog-confirm.component.ts │ │ ├── dialog-input-text │ │ │ ├── dialog-input-text.component.html │ │ │ ├── dialog-input-text.component.scss │ │ │ └── dialog-input-text.component.ts │ │ ├── dialog-waiting │ │ │ ├── dialog-waiting.component.html │ │ │ ├── dialog-waiting.component.scss │ │ │ ├── dialog-waiting.component.spec.ts │ │ │ └── dialog-waiting.component.ts │ │ ├── fan-graph │ │ │ ├── fan-graph.component.html │ │ │ ├── fan-graph.component.scss │ │ │ ├── fan-graph.component.spec.ts │ │ │ └── fan-graph.component.ts │ │ ├── fan-slider │ │ │ ├── fan-slider.component.html │ │ │ ├── fan-slider.component.scss │ │ │ ├── fan-slider.component.spec.ts │ │ │ └── fan-slider.component.ts │ │ ├── global-settings │ │ │ ├── global-settings.component.html │ │ │ ├── global-settings.component.scss │ │ │ ├── global-settings.component.spec.ts │ │ │ └── global-settings.component.ts │ │ ├── info │ │ │ ├── info.component.html │ │ │ ├── info.component.scss │ │ │ ├── info.component.spec.ts │ │ │ └── info.component.ts │ │ ├── keyboard-backlight │ │ │ ├── keyboard-backlight.component.html │ │ │ ├── keyboard-backlight.component.scss │ │ │ ├── keyboard-backlight.component.spec.ts │ │ │ └── keyboard-backlight.component.ts │ │ ├── keyboard-visual │ │ │ ├── keyboard-visual.component.html │ │ │ ├── keyboard-visual.component.scss │ │ │ ├── keyboard-visual.component.spec.ts │ │ │ └── keyboard-visual.component.ts │ │ ├── loader.resolver.ts │ │ ├── main-gui │ │ │ ├── main-gui.component.html │ │ │ ├── main-gui.component.scss │ │ │ ├── main-gui.component.spec.ts │ │ │ └── main-gui.component.ts │ │ ├── node.service.spec.ts │ │ ├── node.service.ts │ │ ├── power-state.service.ts │ │ ├── prime-dialog │ │ │ ├── prime-dialog.component.html │ │ │ ├── prime-dialog.component.scss │ │ │ ├── prime-dialog.component.spec.ts │ │ │ └── prime-dialog.component.ts │ │ ├── prime-select │ │ │ ├── prime-select.component.html │ │ │ ├── prime-select.component.scss │ │ │ ├── prime-select.component.spec.ts │ │ │ └── prime-select.component.ts │ │ ├── profile-conflict-dialog │ │ │ ├── profile-conflict-dialog.component.html │ │ │ ├── profile-conflict-dialog.component.scss │ │ │ ├── profile-conflict-dialog.component.ts │ │ │ ├── profile-conflict-dialog.module.ts │ │ │ └── profile-conflict-dialog.service.ts │ │ ├── profile-details-edit │ │ │ ├── profile-details-edit.component-theme.scss │ │ │ ├── profile-details-edit.component.html │ │ │ ├── profile-details-edit.component.scss │ │ │ ├── profile-details-edit.component.spec.ts │ │ │ └── profile-details-edit.component.ts │ │ ├── profile-manager │ │ │ ├── profile-manager.component.html │ │ │ ├── profile-manager.component.scss │ │ │ ├── profile-manager.component.spec.ts │ │ │ └── profile-manager.component.ts │ │ ├── profile-overview-tile │ │ │ ├── profile-overview-tile.component-theme.scss │ │ │ ├── profile-overview-tile.component.html │ │ │ ├── profile-overview-tile.component.scss │ │ │ ├── profile-overview-tile.component.spec.ts │ │ │ └── profile-overview-tile.component.ts │ │ ├── program-management.service.spec.ts │ │ ├── program-management.service.ts │ │ ├── settings.resolver.ts │ │ ├── shutdown-timer │ │ │ ├── shutdown-timer.component.html │ │ │ ├── shutdown-timer.component.scss │ │ │ ├── shutdown-timer.component.spec.ts │ │ │ └── shutdown-timer.component.ts │ │ ├── state.service.spec.ts │ │ ├── state.service.ts │ │ ├── support │ │ │ ├── support.component.html │ │ │ ├── support.component.scss │ │ │ ├── support.component.spec.ts │ │ │ └── support.component.ts │ │ ├── sys-fs.service.spec.ts │ │ ├── sys-fs.service.ts │ │ ├── tcc-dbus-client.service.spec.ts │ │ ├── tcc-dbus-client.service.ts │ │ ├── tomte-gui │ │ │ ├── tomte-gui.component.html │ │ │ ├── tomte-gui.component.scss │ │ │ ├── tomte-gui.component.spec.ts │ │ │ └── tomte-gui.component.ts │ │ ├── tools │ │ │ ├── tool.component.spec.ts │ │ │ ├── tool.component.ts │ │ │ ├── tools.component.html │ │ │ └── tools.component.scss │ │ ├── utils.service.spec.ts │ │ ├── utils.service.ts │ │ ├── webcam-preview │ │ │ ├── webcam-preview.component.html │ │ │ ├── webcam-preview.component.scss │ │ │ ├── webcam-preview.component.spec.ts │ │ │ └── webcam-preview.component.ts │ │ ├── webcam-settings │ │ │ ├── webcam-settings.component-theme.scss │ │ │ ├── webcam-settings.component.html │ │ │ ├── webcam-settings.component.scss │ │ │ ├── webcam-settings.component.spec.ts │ │ │ └── webcam-settings.component.ts │ │ ├── webcam.service.ts │ │ └── x11.resolver.ts │ ├── assets │ │ ├── .gitkeep │ │ ├── fontawesome-free-5.9.0-web │ │ │ ├── LICENSE.txt │ │ │ ├── css │ │ │ │ ├── all.css │ │ │ │ └── all.min.css │ │ │ └── webfonts │ │ │ │ ├── fa-brands-400.eot │ │ │ │ ├── fa-brands-400.svg │ │ │ │ ├── fa-brands-400.ttf │ │ │ │ ├── fa-brands-400.woff │ │ │ │ ├── fa-brands-400.woff2 │ │ │ │ ├── fa-regular-400.eot │ │ │ │ ├── fa-regular-400.svg │ │ │ │ ├── fa-regular-400.ttf │ │ │ │ ├── fa-regular-400.woff │ │ │ │ ├── fa-regular-400.woff2 │ │ │ │ ├── fa-solid-900.eot │ │ │ │ ├── fa-solid-900.svg │ │ │ │ ├── fa-solid-900.ttf │ │ │ │ ├── fa-solid-900.woff │ │ │ │ └── fa-solid-900.woff2 │ │ ├── fonts │ │ │ ├── TitilliumWeb-Black.ttf │ │ │ ├── TitilliumWeb-Bold.ttf │ │ │ ├── TitilliumWeb-BoldItalic.ttf │ │ │ ├── TitilliumWeb-ExtraLight.ttf │ │ │ ├── TitilliumWeb-ExtraLightItalic.ttf │ │ │ ├── TitilliumWeb-Italic.ttf │ │ │ ├── TitilliumWeb-Light.ttf │ │ │ ├── TitilliumWeb-LightItalic.ttf │ │ │ ├── TitilliumWeb-Regular.ttf │ │ │ ├── TitilliumWeb-SemiBold.ttf │ │ │ ├── TitilliumWeb-SemiBoldItalic.ttf │ │ │ ├── material-icons.css │ │ │ └── material-icons.woff2 │ │ ├── images │ │ │ ├── anydesk-logo-icon.svg │ │ │ ├── aquaris_logo.svg │ │ │ ├── contact.svg │ │ │ ├── cpu.svg │ │ │ ├── displaylight.svg │ │ │ ├── english.svg │ │ │ ├── generalconfig.svg │ │ │ ├── german.svg │ │ │ ├── icon_allprofiles.svg │ │ │ ├── icon_aquaris.svg │ │ │ ├── icon_batterycharger.svg │ │ │ ├── icon_batterymode.svg │ │ │ ├── icon_changecryptpassword.svg │ │ │ ├── icon_close.svg │ │ │ ├── icon_copy.svg │ │ │ ├── icon_cpu.svg │ │ │ ├── icon_dashboard.svg │ │ │ ├── icon_download.svg │ │ │ ├── icon_fan.svg │ │ │ ├── icon_gear.svg │ │ │ ├── icon_gpu.svg │ │ │ ├── icon_help.svg │ │ │ ├── icon_imprint.svg │ │ │ ├── icon_info.svg │ │ │ ├── icon_kb_backlight.svg │ │ │ ├── icon_kb_backlight3.svg │ │ │ ├── icon_kb_backlight4.svg │ │ │ ├── icon_kb_backlight5.svg │ │ │ ├── icon_language.svg │ │ │ ├── icon_logbook.svg │ │ │ ├── icon_minimize.svg │ │ │ ├── icon_monitor.svg │ │ │ ├── icon_online.svg │ │ │ ├── icon_pluggedin.svg │ │ │ ├── icon_power.svg │ │ │ ├── icon_profile_breezy.svg │ │ │ ├── icon_profile_custom.svg │ │ │ ├── icon_profile_default.svg │ │ │ ├── icon_profile_energysaver.svg │ │ │ ├── icon_profile_performance.svg │ │ │ ├── icon_profile_quiet3.svg │ │ │ ├── icon_profile_quiet4.svg │ │ │ ├── icon_remotesupport.svg │ │ │ ├── icon_reset.svg │ │ │ ├── icon_restoresystem.svg │ │ │ ├── icon_save.svg │ │ │ ├── icon_settings.svg │ │ │ ├── icon_speedometer.svg │ │ │ ├── icon_stopwatch.svg │ │ │ ├── icon_support.svg │ │ │ ├── icon_systemdiagnose.svg │ │ │ ├── icon_temperature.svg │ │ │ ├── icon_theme.svg │ │ │ ├── icon_tomte.svg │ │ │ ├── icon_tools.svg │ │ │ ├── icon_trash.svg │ │ │ ├── icon_update.svg │ │ │ ├── icon_webcam.svg │ │ │ ├── information.svg │ │ │ ├── support.svg │ │ │ ├── systemoverview.svg │ │ │ ├── tcc_logo_complete.svg │ │ │ └── userinfo.svg │ │ ├── locale │ │ │ ├── lang.de.xlf │ │ │ ├── lang.en.xlf │ │ │ └── lang.xlf │ │ ├── taskbar_icon_free.svg │ │ ├── tcc_logo.svg │ │ ├── tuxedo-control-center_256.png │ │ └── tuxedo-logo.svg │ ├── common │ │ └── formErrorStateMatcher.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── global-styles.scss │ ├── index.html │ ├── main.ts │ ├── native │ │ ├── child_process.js │ │ ├── crypto.js │ │ ├── fs.js │ │ ├── http.js │ │ ├── https.js │ │ ├── net.js │ │ ├── os.js │ │ ├── path.js │ │ ├── stream.js │ │ ├── timers.js │ │ └── x11.js │ ├── polyfills.ts │ ├── styles.scss │ ├── tcc-changelog-theme.scss │ ├── tcc-charts-theme.scss │ ├── tcc-color-picker-theme.scss │ ├── tcc-gauge-theme.scss │ ├── tcc-general-defs-theme.scss │ ├── test.ts │ └── themes │ │ ├── tuxedo-dark-theme.scss │ │ └── tuxedo-light-theme.scss ├── package.json ├── service-app │ ├── classes │ │ ├── ChargingWorker.ts │ │ ├── CpuPowerWorker.ts │ │ ├── CpuWorker.ts │ │ ├── DaemonListener.ts │ │ ├── DaemonWorker.ts │ │ ├── DisplayBacklightWorker.ts │ │ ├── DisplayRefreshRateWorker.ts │ │ ├── FanControlLogic.spec.ts │ │ ├── FanControlLogic.ts │ │ ├── FanControlWorker.ts │ │ ├── GpuInfoWorker.ts │ │ ├── KeyboardBacklightListener.ts │ │ ├── NVIDIAPowerCTRLListener.ts │ │ ├── ODMPowerLimitWorker.ts │ │ ├── ODMProfileWorker.ts │ │ ├── PrimeWorker.ts │ │ ├── SingleProcess.ts │ │ ├── StateSwitcherWorker.ts │ │ ├── TccDBusInterface.ts │ │ ├── TccDBusService.ts │ │ ├── TuxedoControlCenterDaemon.ts │ │ ├── WebcamWorker.ts │ │ └── YCbCr420WorkaroundWorker.ts │ ├── jasmine.json │ ├── main.ts │ └── tsconfig.json └── udev │ └── 99-webcam.rules ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /build 6 | /tmp 7 | /out-tsc 8 | /usr 9 | # Only exists if Bazel was run 10 | /bazel-out 11 | 12 | # dependencies 13 | /node_modules 14 | 15 | # profiling files 16 | chrome-profiler-events.json 17 | speed-measure-plugin.json 18 | 19 | # IDEs and editors 20 | /.idea 21 | .project 22 | .classpath 23 | .c9/ 24 | *.launch 25 | .settings/ 26 | *.sublime-workspace 27 | 28 | # IDE - VSCode 29 | .vscode/* 30 | !.vscode/settings.json 31 | !.vscode/tasks.json 32 | !.vscode/launch.json 33 | !.vscode/extensions.json 34 | .history/* 35 | 36 | # misc 37 | /.sass-cache 38 | /connect.lock 39 | /coverage 40 | /libpeerconnection.log 41 | npm-debug.log 42 | yarn-error.log 43 | testem.log 44 | /typings 45 | 46 | # System Files 47 | .DS_Store 48 | Thumbs.db 49 | 50 | src/ng-app/assets/CHANGELOG.md -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "tcc main process", 6 | "type": "node", 7 | "request": "launch", 8 | "cwd": "${workspaceRoot}", 9 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", 10 | "windows": { 11 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" 12 | }, 13 | "runtimeArgs": [ 14 | "./dist/tuxedo-control-center" 15 | ], 16 | "program": "${workspaceRoot}/src/e-app/main.ts", 17 | "outFiles": [ 18 | "${workspaceRoot}/dist/tuxedo-control-center/e-app/e-app/main.js" 19 | ], 20 | "sourceMaps": true 21 | }, 22 | { 23 | "name": "tcc render process", 24 | "type": "chrome", 25 | "request": "launch", 26 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", 27 | "windows": { 28 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" 29 | }, 30 | "runtimeArgs": [ 31 | "${workspaceRoot}/dist/tuxedo-control-center" 32 | ], 33 | "webRoot": "${workspaceRoot}/dist", 34 | "sourceMaps": true, 35 | "sourceMapPathOverrides": { 36 | "webpack:///./*": "${workspaceRoot}/*" 37 | }, 38 | "internalConsoleOptions": "openOnSessionStart" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "array": "c", 4 | "string": "c", 5 | "string_view": "c", 6 | "new": "cpp" 7 | }, 8 | "xliffSync.baseFile": "lang.xlf", 9 | "editor.tabSize": 4, 10 | "editor.insertSpaces": true, 11 | "editor.detectIndentation": false 12 | } -------------------------------------------------------------------------------- /FEATURES.md: -------------------------------------------------------------------------------- 1 | # Feature list 2 | 3 | ## Current 4 | 5 | - ### Per profile control of 6 | - CPU frequency parameters 7 | - Display brightness 8 | - Webcam status (on/off) 9 | - Fan profiles 10 | 11 | - ### States 12 | - Assignment of one profile that gets activated per state 13 | - Two available states 'Mains powered' & 'Battery powered' 14 | 15 | - ### Support 16 | - systeminfos.sh download and start 17 | - Anydesk installation and start 18 | - ### Info 19 | - General info 20 | - Changelog 21 | - ### App language support 22 | 23 | --- 24 | 25 | ## Coming soon.. 26 | - ### ??? 27 | 28 | --- 29 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "TuxedoIOAPI", 5 | "sources": [ "src/native-lib/tuxedo_io_napi.cc" ], 6 | "include_dirs": [ " /dev/null 2>&1 || true 5 | systemctl disable tuxedofancontrol > /dev/null 2>&1 || true 6 | 7 | DIST_DATA=/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/dist-data 8 | 9 | rm /usr/share/applications/tuxedo-control-center.desktop || true 10 | cp ${DIST_DATA}/tuxedo-control-center.desktop /usr/share/applications/tuxedo-control-center.desktop || true 11 | 12 | mkdir -p /etc/skel/.config/autostart || true 13 | cp ${DIST_DATA}/tuxedo-control-center-tray.desktop /etc/skel/.config/autostart/tuxedo-control-center-tray.desktop || true 14 | 15 | cp ${DIST_DATA}/com.tuxedocomputers.tccd.policy /usr/share/polkit-1/actions/com.tuxedocomputers.tccd.policy || true 16 | cp ${DIST_DATA}/com.tuxedocomputers.tccd.conf /usr/share/dbus-1/system.d/com.tuxedocomputers.tccd.conf || true 17 | 18 | cp ${DIST_DATA}/com.tuxedocomputers.tomte.policy /usr/share/polkit-1/actions/com.tuxedocomputers.tomte.policy || true 19 | 20 | # Copy and enable services 21 | cp ${DIST_DATA}/tccd.service /etc/systemd/system/tccd.service || true 22 | cp ${DIST_DATA}/tccd-sleep.service /etc/systemd/system/tccd-sleep.service || true 23 | systemctl daemon-reload 24 | systemctl enable tccd tccd-sleep 25 | systemctl restart tccd 26 | 27 | # set up udev rules 28 | mv ${DIST_DATA}/99-webcam.rules /etc/udev/rules.d/99-webcam.rules 29 | udevadm control --reload-rules && udevadm trigger 30 | 31 | # --- 32 | # Original electron-builder after-install.tpl 33 | # --- 34 | ln -sf '/opt/tuxedo-control-center/tuxedo-control-center' '/usr/bin/tuxedo-control-center' || true 35 | 36 | # SUID chrome-sandbox for Electron 5+ 37 | chmod 4755 '/opt/tuxedo-control-center/chrome-sandbox' || true 38 | 39 | update-mime-database /usr/share/mime || true 40 | update-desktop-database /usr/share/applications || true 41 | -------------------------------------------------------------------------------- /build-src/after_remove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Stop, disable and remove services 4 | systemctl disable tccd tccd-sleep || true 5 | systemctl stop tccd || true 6 | rm /etc/systemd/system/tccd.service || true 7 | rm /etc/systemd/system/tccd-sleep.service || true 8 | systemctl daemon-reload || true 9 | 10 | # Remove log and config files if pure uninstall 11 | if [ "$1" = "remove" ] || [ "$1" = "purge" ] || [ "$1" = "0" ]; then 12 | rm -rf /var/log/tcc/ || true 13 | rm -rf /var/log/tccd/ || true 14 | rm -rf /etc/tcc/ || true 15 | fi 16 | 17 | # Remove policy kit and desktop files 18 | rm /usr/share/polkit-1/actions/com.tuxedocomputers.tccd.policy || true 19 | rm /usr/share/polkit-1/actions/com.tuxedocomputers.tomte.policy || true 20 | rm /usr/share/applications/tuxedo-control-center.desktop || true 21 | rm /etc/skel/.config/autostart/tuxedo-control-center-tray.desktop || true 22 | rm /usr/share/dbus-1/system.d/com.tuxedocomputers.tccd.conf || true 23 | 24 | # remove udev rule 25 | rm /etc/udev/rules.d/99-webcam.rules || true 26 | 27 | # Delete the link to the binary 28 | rm -f '/usr/bin/tuxedo-control-center' 29 | -------------------------------------------------------------------------------- /build-src/build-release.ts: -------------------------------------------------------------------------------- 1 | import * as util from 'util'; 2 | import * as child_process from 'child_process'; 3 | const execp = util.promisify(child_process.exec); 4 | 5 | const tccPackage = require('../package.json'); 6 | 7 | async function getGitDescribe() { 8 | return (await execp("git describe")).stdout.trim(); 9 | } 10 | 11 | async function getCurrentBranch() { 12 | return (await execp('git branch --show-current')).stdout.trim(); 13 | } 14 | 15 | async function setVersion(version: string) { 16 | version.replace('"', ''); 17 | await execp(`npm run ver "${version} --allow-same-version"`); 18 | } 19 | 20 | async function main() { 21 | 22 | let automaticVersion = false; 23 | let isStart = false; 24 | let isEnd = false; 25 | 26 | process.argv.forEach((parameter, index, array) => { 27 | if (parameter.includes('autoversion')) { 28 | automaticVersion = true; 29 | } 30 | }); 31 | 32 | const previousVersion = tccPackage.version; 33 | try { 34 | 35 | let filenameAddition = ''; 36 | if (automaticVersion) { 37 | let gitDescribe = await getGitDescribe(); 38 | let gitBranch = await getCurrentBranch(); 39 | let version = gitDescribe.slice(1); 40 | 41 | const addBranchNameToFilename = version.includes('-') && 42 | gitBranch !== ''; 43 | 44 | if (addBranchNameToFilename) { 45 | filenameAddition = `_${gitBranch}`; 46 | } 47 | 48 | console.log(`Set build version: '${version}'`); 49 | await setVersion(version); 50 | } 51 | 52 | console.log('Run production build'); 53 | console.log((await execp("npm run build-prod")).stdout); 54 | console.log('Run electron-builder'); 55 | console.log((await execp(`npm run electron-builder "fnameadd=${filenameAddition}"`)).stdout); 56 | 57 | } catch (err) { 58 | console.log('Error on build => ' + err); 59 | process.exit(1); 60 | } finally { 61 | if (automaticVersion) { 62 | console.log(`Restore version: '${previousVersion}' `); 63 | await setVersion(previousVersion); 64 | } 65 | } 66 | } 67 | 68 | main().then(() => { 69 | process.exit(0); 70 | }).catch(err => { 71 | console.log("error => " + err); 72 | process.exit(1); 73 | }) -------------------------------------------------------------------------------- /build-src/dummy.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/build-src/dummy.sh -------------------------------------------------------------------------------- /build-src/fan_table_format.ts: -------------------------------------------------------------------------------- 1 | import * as process from 'process'; 2 | import * as readline from 'readline'; 3 | import { SIGINT, SIGTERM } from 'constants'; 4 | 5 | const dataList: string[] = []; 6 | 7 | process.stdin.on('data', (dataChunk: Buffer) => { 8 | dataList.push(dataChunk.toString()); 9 | }); 10 | 11 | process.on('SIGINT', () => { 12 | const data = dataList.join(''); 13 | const lines: string[] = data.split('\n'); 14 | let pairs = lines.map(line => line.split(RegExp('[ \t]+'))); 15 | pairs = pairs.filter(pair => pair.length === 2); 16 | const stringEntries = pairs.map(pair => ({ temp: pair[0].trim(), speed: pair[1].trim() })); 17 | for (const entry of stringEntries) { 18 | if (entry.speed === '') { entry.speed = '0'; } 19 | process.stdout.write('{ temp: ' + entry.temp + ', speed: ' + entry.speed + ' },\n'); 20 | } 21 | process.exit(SIGINT); 22 | }); 23 | -------------------------------------------------------------------------------- /build-src/inc-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npm version --no-git-tag-version $1 $2 3 | cd src 4 | npm version --no-git-tag-version $1 $2 5 | -------------------------------------------------------------------------------- /build-src/package-files.txt: -------------------------------------------------------------------------------- 1 | usr/share/metainfo/com.tuxedocomputers.tcc.metainfo.xml -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | 'browserName': 'chrome', 17 | 'chromeOptions': { 18 | 'args': [ '--headless' ] 19 | } 20 | }, 21 | directConnect: true, 22 | baseUrl: 'http://localhost:4200/', 23 | framework: 'jasmine', 24 | jasmineNodeOpts: { 25 | showColors: true, 26 | defaultTimeoutInterval: 30000, 27 | print: function() {} 28 | }, 29 | onPrepare() { 30 | require('ts-node').register({ 31 | project: require('path').join(__dirname, './tsconfig.json') 32 | }); 33 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 34 | } 35 | }; -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should be able to run e2e tests', () => { 12 | page.navigateTo(); 13 | expect(true).toBeTruthy(); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es2018", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/tuxedo-control-center'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['ChromeHeadless'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /screenshots/de/Akku_Netz_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/Akku_Netz_TCC.png -------------------------------------------------------------------------------- /screenshots/de/ControlCenter_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/ControlCenter_TCC.png -------------------------------------------------------------------------------- /screenshots/de/DarkTheme_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/DarkTheme_TCC.png -------------------------------------------------------------------------------- /screenshots/de/Profil_Einstellungen_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/Profil_Einstellungen_TCC.png -------------------------------------------------------------------------------- /screenshots/de/Profile_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/Profile_TCC.png -------------------------------------------------------------------------------- /screenshots/de/Systemmonitor_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/Systemmonitor_TCC.png -------------------------------------------------------------------------------- /screenshots/de/Tools_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/de/Tools_TCC.png -------------------------------------------------------------------------------- /screenshots/en/ControlCenter_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/ControlCenter_TCC.png -------------------------------------------------------------------------------- /screenshots/en/DarkTheme_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/DarkTheme_TCC.png -------------------------------------------------------------------------------- /screenshots/en/Mains_Battery_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/Mains_Battery_TCC.png -------------------------------------------------------------------------------- /screenshots/en/Profile_Settings_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/Profile_Settings_TCC.png -------------------------------------------------------------------------------- /screenshots/en/Profiles_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/Profiles_TCC.png -------------------------------------------------------------------------------- /screenshots/en/Systemmonitor_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/Systemmonitor_TCC.png -------------------------------------------------------------------------------- /screenshots/en/Tools_TCC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/en/Tools_TCC.png -------------------------------------------------------------------------------- /screenshots/metainfo/dark-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/metainfo/dark-dashboard.png -------------------------------------------------------------------------------- /screenshots/metainfo/dark-profile-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/metainfo/dark-profile-overview.png -------------------------------------------------------------------------------- /screenshots/metainfo/light-aquaris-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/metainfo/light-aquaris-blue.png -------------------------------------------------------------------------------- /screenshots/metainfo/light-custom-fan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/metainfo/light-custom-fan.png -------------------------------------------------------------------------------- /screenshots/metainfo/light-kbd-bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/screenshots/metainfo/light-kbd-bl.png -------------------------------------------------------------------------------- /src/cameractrls/v4l2_kernel_names.json: -------------------------------------------------------------------------------- 1 | [["auto_exposure", "exposure_auto"], ["exposure_time_absolute", "exposure_absolute"], ["exposure_dynamic_framerate", "exposure_auto_priority"], ["white_balance_automatic", "white_balance_temperature_auto"]] 2 | -------------------------------------------------------------------------------- /src/common/classes/ChargingPriorityController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { SysFsPropertyString, SysFsPropertyStringList } from './SysFsProperties'; 21 | import { SysFsController } from './SysFsController'; 22 | 23 | export class ChargingPriorityController extends SysFsController { 24 | 25 | constructor(public readonly basePath: string) { 26 | super(); 27 | } 28 | 29 | readonly chargingPriosAvailable = new SysFsPropertyStringList(path.join(this.basePath, 'charging_prios_available')); 30 | readonly chargingPrio = new SysFsPropertyString(path.join(this.basePath, 'charging_prio')); 31 | } -------------------------------------------------------------------------------- /src/common/classes/ChargingProfileController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { SysFsPropertyString, SysFsPropertyStringList } from './SysFsProperties'; 21 | import { SysFsController } from './SysFsController'; 22 | 23 | export class ChargingProfileController extends SysFsController { 24 | 25 | constructor(public readonly basePath: string) { 26 | super(); 27 | } 28 | 29 | readonly chargingProfilesAvailable = new SysFsPropertyStringList(path.join(this.basePath, 'charging_profiles_available')); 30 | readonly chargingProfile = new SysFsPropertyString(path.join(this.basePath, 'charging_profile')); 31 | } -------------------------------------------------------------------------------- /src/common/classes/CpuController.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import 'jasmine'; 20 | const mock = require('mock-fs'); 21 | 22 | import { CpuController } from './CpuController'; 23 | 24 | describe('CpuController', () => { 25 | 26 | // Mock file structure in memory 27 | beforeEach(() => { 28 | mock({ 29 | '/sys/devices/system/cpu': { 30 | 'possible': '0-1', 31 | 'present': '0-1', 32 | 'cpu0': { 33 | 'online': '1', 34 | cpufreq: { 'scaling_cur_freq': '800000' } 35 | }, 36 | 'cpu1': { 37 | 'online': '1', 38 | cpufreq: { 'scaling_cur_freq': '800000' } 39 | } 40 | } 41 | }); 42 | }); 43 | 44 | afterEach(() => { 45 | mock.restore(); 46 | }); 47 | 48 | it('should add paths to properties correctly', () => { 49 | const cpu = new CpuController('/sys/devices/system/cpu'); 50 | expect(cpu.basePath).toBe('/sys/devices/system/cpu'); 51 | expect(cpu.online.readPath).toBe('/sys/devices/system/cpu/online'); 52 | expect(cpu.cores.length).toBe(2); 53 | expect(cpu.cores[0].cpuPath).toBe('/sys/devices/system/cpu/cpu0'); 54 | expect(cpu.cores[0].online.readPath).toBe('/sys/devices/system/cpu/cpu0/online'); 55 | expect(cpu.cores[0].online.readValue()).toBe(true); 56 | expect(cpu.cores[1].online.readValue()).toBe(true); 57 | expect(cpu.cores[1].scalingGovernor.readPath).toBe('/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor'); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /src/common/classes/DMIController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { SysFsPropertyString } from './SysFsProperties'; 21 | import { SysFsController } from './SysFsController'; 22 | 23 | export class DMIController extends SysFsController { 24 | 25 | constructor(public readonly basePath: string) { 26 | super(); 27 | } 28 | 29 | readonly boardName = new SysFsPropertyString(path.join(this.basePath, 'board_name')); 30 | readonly productSKU = new SysFsPropertyString(path.join(this.basePath, 'product_sku')); 31 | readonly boardVendor = new SysFsPropertyString(path.join(this.basePath, 'board_vendor')); 32 | readonly chassisVendor = new SysFsPropertyString(path.join(this.basePath, 'chassis_vendor')); 33 | readonly sysVendor = new SysFsPropertyString(path.join(this.basePath, 'sys_vendor')); 34 | } -------------------------------------------------------------------------------- /src/common/classes/DisplayBacklightController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { SysFsPropertyInteger } from './SysFsProperties'; 21 | import { SysFsController } from './SysFsController'; 22 | 23 | // Exception for amd backlight driver (amdgpu_bl) 24 | // amdgpu brightness workaround, scale actual_brightness [0, 0xffff] to [0, 0xff] 25 | // if it appears to return a high value 26 | class SysFsPropertyAmdgpuBrightness extends SysFsPropertyInteger { 27 | public readValue(): number { 28 | return this.checkAndScaleValue(super.readValue()); 29 | } 30 | 31 | public readValueNT(): number { 32 | return this.checkAndScaleValue(super.readValueNT()); 33 | } 34 | 35 | private checkAndScaleValue(value: number): number { 36 | if (value === undefined) { 37 | return undefined; 38 | } else if (value > 0xff) { 39 | return Math.round(0xff * (value / 0xffff)); 40 | } else { 41 | return value; 42 | } 43 | } 44 | } 45 | 46 | export class DisplayBacklightController extends SysFsController { 47 | 48 | constructor(public readonly basePath: string, public readonly driver: string) { 49 | super(); 50 | 51 | // Workaround 52 | if (driver.includes('amdgpu_bl')) { 53 | this.brightness = new SysFsPropertyAmdgpuBrightness( 54 | path.join(this.basePath, this.driver, 'actual_brightness'), 55 | path.join(this.basePath, this.driver, 'brightness')); 56 | } 57 | } 58 | 59 | readonly brightness = new SysFsPropertyInteger( 60 | path.join(this.basePath, this.driver, 'actual_brightness'), 61 | path.join(this.basePath, this.driver, 'brightness')); 62 | 63 | readonly maxBrightness = new SysFsPropertyInteger(path.join(this.basePath, this.driver, 'max_brightness')); 64 | } 65 | -------------------------------------------------------------------------------- /src/common/classes/FanUtils.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2021 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | function interpolatePoints( 21 | points: { temp: number; speed: number }[], 22 | x: number 23 | ): number { 24 | const first = points[0]; 25 | const last = points[points.length - 1]; 26 | if (x <= first.temp) { 27 | return first.speed; 28 | } 29 | if (x >= last.temp) { 30 | return last.speed; 31 | } 32 | const i = 33 | points.findIndex((p, idx) => p.temp >= x || idx === points.length - 1) - 34 | 1; 35 | const { temp: x1, speed: y1 } = points[i]; 36 | const { temp: x2, speed: y2 } = points[i + 1]; 37 | const m = (y2 - y1) / (x2 - x1); 38 | const b = y1 - m * x1; 39 | return Math.round(m * x + b); 40 | } 41 | 42 | export function interpolatePointsArray( 43 | points: { temp: number; speed: number }[] 44 | ): number[] { 45 | return Array.from({ length: 101 }, (_, i) => interpolatePoints(points, i)); 46 | } 47 | 48 | 49 | export function formatTemp(value: number, usingFahrenheit: boolean): string { 50 | if (usingFahrenheit) { 51 | return `${Math.round(((value * 1.8) + 32))} °F`; 52 | } 53 | else { 54 | return `${value} °C`; 55 | } 56 | } 57 | 58 | export function formatSpeed(value: number | string): string { 59 | return `${value} %`; 60 | } 61 | 62 | /** 63 | * Ensure minimum fan speed if temperature is high 64 | */ 65 | export function manageCriticalTemperature(temp: number, speed: number): number { 66 | return temp >= 90 67 | ? Math.max(40, speed) 68 | : temp >= 80 69 | ? Math.max(30, speed) 70 | : speed; 71 | } 72 | -------------------------------------------------------------------------------- /src/common/classes/FnLockController.ts: -------------------------------------------------------------------------------- 1 | import { SysFsPropertyBoolean } from "./SysFsProperties"; 2 | 3 | export class FnLockController { 4 | fnLock = new SysFsPropertyBoolean("/sys/devices/platform/tuxedo_keyboard/fn_lock"); 5 | 6 | getFnLockSupported = () => this.fnLock.isAvailable(); 7 | 8 | getFnLockStatus = () => this.fnLock.readValueNT(); 9 | 10 | setFnLockStatus = (status: boolean) => this.fnLock.writeValue(status); 11 | } -------------------------------------------------------------------------------- /src/common/classes/IntelPStateController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { SysFsPropertyBoolean, SysFsPropertyInteger, SysFsPropertyString } from './SysFsProperties'; 21 | 22 | export class IntelPstateController { 23 | constructor(public readonly basePath: string) {} 24 | 25 | public readonly noTurbo = new SysFsPropertyBoolean(path.join(this.basePath, 'no_turbo')); 26 | public readonly maxPerfPct = new SysFsPropertyInteger(path.join(this.basePath, 'max_perf_pct')); 27 | public readonly minPerfPct = new SysFsPropertyInteger(path.join(this.basePath, 'min_perf_pct')); 28 | public readonly numPstates = new SysFsPropertyInteger(path.join(this.basePath, 'num_pstates')); 29 | public readonly status = new SysFsPropertyString(path.join(this.basePath, 'status')); 30 | public readonly turboPct = new SysFsPropertyInteger(path.join(this.basePath, 'turbo_pct')); 31 | } 32 | -------------------------------------------------------------------------------- /src/common/classes/PowerController.ts: -------------------------------------------------------------------------------- 1 | import { IntelRAPLController } from "./IntelRAPLController"; 2 | 3 | export class PowerController { 4 | private intelRAPL: IntelRAPLController; 5 | private RAPLPowerStatus: boolean = false; 6 | private currentEnergy: number; 7 | private lastUpdateTime: number; 8 | 9 | constructor(intelRAPL: IntelRAPLController) { 10 | this.intelRAPL = intelRAPL; 11 | this.RAPLPowerStatus = this.intelRAPL.getIntelRAPLEnergyAvailable(); 12 | this.currentEnergy = 0; 13 | this.lastUpdateTime = Date.now(); 14 | } 15 | 16 | public getCurrentPower(): number { 17 | if (!this.RAPLPowerStatus) return -1; 18 | const energyIncrement = this.intelRAPL.getEnergy() - this.currentEnergy; 19 | const delay = this.getDelay(); 20 | const powerDraw = 21 | delay && this.currentEnergy > 0 22 | ? energyIncrement / delay / 1000000 23 | : -1; 24 | this.currentEnergy += energyIncrement; 25 | return powerDraw; 26 | } 27 | 28 | private getDelay(): number { 29 | const currentTime = Date.now(); 30 | const timeDifference = 31 | this.lastUpdateTime > 0 32 | ? (currentTime - this.lastUpdateTime) / 1000 33 | : -1; 34 | this.lastUpdateTime = currentTime; 35 | return timeDifference; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/common/classes/StateUtils.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as path from 'path'; 20 | import { ProfileStates } from '../models/TccSettings'; 21 | import { PowerSupplyController } from './PowerSupplyController'; 22 | 23 | export function determineState(): ProfileStates { 24 | // Default state 25 | let state: ProfileStates = ProfileStates.AC; 26 | 27 | const pathPowerSupplies = '/sys/class/power_supply'; 28 | const powerSupplyNames = PowerSupplyController.getDeviceList(pathPowerSupplies); 29 | const powerSupplies: PowerSupplyController[] = []; 30 | 31 | // Attempt to find a 'Mains' type power supply 32 | let powerAc: PowerSupplyController; 33 | try { 34 | for (const powerSupplyName of powerSupplyNames) { 35 | const newPowerSupply = new PowerSupplyController(path.join(pathPowerSupplies, powerSupplyName)); 36 | powerSupplies.push(newPowerSupply); 37 | } 38 | powerAc = powerSupplies.find(powerSupply => powerSupply.type.readValue() === 'Mains'); 39 | } catch (err) { } 40 | 41 | 42 | // Attempt to find state depending on 'Mains' online status 43 | if (powerAc !== undefined) { 44 | try { 45 | const acOnline = powerAc.online.readValue(); 46 | if (acOnline) { 47 | state = ProfileStates.AC; 48 | } else { 49 | state = ProfileStates.BAT; 50 | } 51 | } catch (err) { } 52 | } 53 | 54 | return state; 55 | } 56 | -------------------------------------------------------------------------------- /src/common/classes/SysFsController.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import * as fs from 'fs'; 20 | 21 | export abstract class SysFsController { 22 | 23 | public static getDeviceList(sourceDir: string): string[] { 24 | try { 25 | return fs.readdirSync(sourceDir, { withFileTypes: true }) 26 | .map(dirent => dirent.name); 27 | } catch (err) { 28 | return []; 29 | } 30 | } 31 | 32 | public static getDeviceListDirent(sourceDir: string): fs.Dirent[] { 33 | try { 34 | return fs.readdirSync(sourceDir, { withFileTypes: true }); 35 | } catch (err) { 36 | return []; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/common/classes/SysFsPropertyIntegerHex.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import 'jasmine'; 20 | const mock = require('mock-fs'); 21 | import * as fs from 'fs'; 22 | 23 | import { SysFsPropertyIntegerHex } from './SysFsProperties'; 24 | 25 | describe('SysDevPropertyInteger', () => { 26 | 27 | const dev = new SysFsPropertyIntegerHex( 28 | '/sys/bus/usb/drivers/usb/1-2/idProduct', 29 | '/sys/bus/usb/drivers/usb/1-2/idProduct' 30 | ); 31 | 32 | // Mock file structure in memory 33 | beforeEach(() => { 34 | mock({ 35 | '/sys/bus/usb/drivers/usb/1-2/': {} 36 | }); 37 | }); 38 | 39 | afterEach(() => { 40 | mock.restore(); 41 | }); 42 | 43 | it('should throw error if file cannot be read', () => { 44 | expect(() => { dev.readValue(); }).toThrow(); 45 | }); 46 | 47 | it('should not throw and return NaN if value is not an integer', () => { 48 | mock({ '/sys/bus/usb/drivers/usb/1-2/idProduct' : 'no numbers here' }); 49 | expect(() => { dev.readValue(); }).not.toThrow(); 50 | expect(dev.readValue()).toBeNaN(); 51 | }); 52 | 53 | it('should correctly read an integer from file', () => { 54 | mock({ '/sys/bus/usb/drivers/usb/1-2/idProduct' : '04f2' }); 55 | expect(() => { dev.readValue(); }).not.toThrow(); 56 | expect(dev.readValue()).toBe(1266); 57 | }); 58 | 59 | it('should throw if file cannot be written', () => { 60 | expect(() => { dev.writeValue(1234); }).toThrow(); 61 | }); 62 | 63 | it('should write number as a string if file exists', () => { 64 | mock({ '/sys/bus/usb/drivers/usb/1-2/idProduct' : '' }); 65 | expect( () => { dev.writeValue(1234); }).not.toThrow(); 66 | expect(fs.readFileSync('/sys/bus/usb/drivers/usb/1-2/idProduct').toString()).toBe('4d2'); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /src/common/classes/SysFsPropertyNumListExplicit.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2023 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import 'jasmine'; 20 | const mock = require('mock-fs'); 21 | import * as fs from 'fs'; 22 | 23 | import { SysFsPropertyNumListExplicit } from './SysFsProperties'; 24 | 25 | describe('SysDevPropertyNumListExplicit', () => { 26 | 27 | const dev = new SysFsPropertyNumListExplicit('/sys/something/numlist'); 28 | const devSeparator = new SysFsPropertyNumListExplicit('/sys/something/numlist', '/sys/something/numlist', ','); 29 | 30 | // Mock file structure in memory 31 | beforeEach(() => { 32 | mock({ 33 | }); 34 | }); 35 | 36 | afterEach(() => { 37 | mock.restore(); 38 | }); 39 | 40 | it('should read', () => { 41 | mock({ '/sys/something/numlist' : '1 2 3 2 1' }); 42 | expect(() => { dev.readValue(); }).not.toThrow(); 43 | expect(dev.readValue()).toEqual([1, 2, 3, 2, 1]); 44 | }); 45 | 46 | it('should write', () => { 47 | mock({ '/sys/something/numlist' : 'something' }); 48 | expect(() => { dev.writeValue([1, 2, 3, 2, 1]); }).not.toThrow(); 49 | expect(fs.readFileSync('/sys/something/numlist').toString()).toBe('1 2 3 2 1'); 50 | }); 51 | 52 | it('should read with configurable list separator', () => { 53 | mock({ '/sys/something/numlist' : '1,2,3,2,1' }); 54 | expect(() => { devSeparator.readValue(); }).not.toThrow(); 55 | expect(devSeparator.readValue()).toEqual([1, 2, 3, 2, 1]); 56 | }); 57 | 58 | it('should write with configurable list separator', () => { 59 | mock({ '/sys/something/numlist' : 'something' }); 60 | expect(() => { devSeparator.writeValue([1, 2, 3, 2, 1]); }).not.toThrow(); 61 | expect(fs.readFileSync('/sys/something/numlist').toString()).toBe('1,2,3,2,1'); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /src/common/classes/SysFsPropertyString.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import 'jasmine'; 20 | const mock = require('mock-fs'); 21 | import * as fs from 'fs'; 22 | 23 | import { SysFsPropertyString } from './SysFsProperties'; 24 | 25 | describe('SysDevPropertyString', () => { 26 | 27 | const dev = new SysFsPropertyString('/sys/class/backlight/intel_backlight/type'); 28 | 29 | // Mock file structure in memory 30 | beforeEach(() => { 31 | mock({ 32 | '/sys/class': {} 33 | }); 34 | }); 35 | 36 | afterEach(() => { 37 | mock.restore(); 38 | }); 39 | 40 | it('when read should throw error if file does not exist', () => { 41 | expect(() => { dev.readValue(); }).toThrow(); 42 | }); 43 | 44 | it('when written should throw error if file does not exist', () => { 45 | expect(() => { dev.writeValue('something'); }).toThrow(); 46 | }); 47 | 48 | it('should throw error if writing to file while not the owner', () => { 49 | mock({ 50 | '/sys/class/backlight/intel_backlight/type': mock.file({ 51 | content: '', 52 | uid: 0, 53 | gid: 0, 54 | mode: 0o644 55 | }) 56 | }); 57 | expect(() => { dev.writeValue('something'); }).toThrow(); 58 | }); 59 | 60 | it('should not throw error if writing to file while the owner', () => { 61 | mock({ 62 | '/sys/class/backlight/intel_backlight/type': mock.file({ 63 | content: 'something', 64 | mode: 0o644 65 | }) 66 | }); 67 | expect(() => { dev.writeValue('something else'); }).not.toThrow(); 68 | expect(fs.readFileSync('/sys/class/backlight/intel_backlight/type').toString()).toBe('something else'); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /src/common/classes/TccPaths.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | export class TccPaths { 20 | static readonly PID_FILE: string = '/var/run/tccd.pid'; 21 | static readonly TCCD_EXEC_FILE: string = 22 | '/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/service/tccd'; 23 | static readonly TCCD_PYTHON_CAMERACTRL_FILE: string = 24 | '/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/camera/cameractrls.py'; 25 | static readonly SETTINGS_FILE: string = '/etc/tcc/settings'; 26 | static readonly PROFILES_FILE: string = '/etc/tcc/profiles'; 27 | static readonly WEBCAM_FILE: string = '/etc/tcc/webcam'; 28 | static readonly V4L2_NAMES_FILE: string = 29 | '/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/camera/v4l2_kernel_names.json'; 30 | static readonly AUTOSAVE_FILE: string = '/etc/tcc/autosave'; 31 | static readonly FANTABLES_FILE: string = '/etc/tcc/fantables'; 32 | static readonly TCCD_LOG_FILE: string = '/var/log/tccd/log'; 33 | } 34 | -------------------------------------------------------------------------------- /src/common/classes/Vendor.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { execCommandAsync } from "./Utils"; 3 | 4 | @Injectable({ 5 | providedIn: "root", 6 | }) 7 | export class VendorService { 8 | private cpuVendor: string | null = null; 9 | 10 | constructor() { 11 | this.checkCpuVendor().then((vendor) => { 12 | this.cpuVendor = vendor; 13 | }); 14 | } 15 | 16 | async getCpuVendor(): Promise { 17 | if (this.cpuVendor !== null) { 18 | return this.cpuVendor; 19 | } 20 | 21 | const vendor = await this.checkCpuVendor(); 22 | this.cpuVendor = vendor; 23 | 24 | return vendor; 25 | } 26 | 27 | private async checkCpuVendor(): Promise { 28 | const stdout = ( 29 | await execCommandAsync("cat /proc/cpuinfo | grep vendor_id") 30 | ).toString(); 31 | 32 | const outputLines = stdout.split("\n"); 33 | const vendorLine = outputLines.find((line) => 34 | line.includes("vendor_id") 35 | ); 36 | 37 | if (vendorLine) { 38 | const vendor = vendorLine.split(":")[1].trim(); 39 | 40 | if (vendor === "GenuineIntel") { 41 | return "intel"; 42 | } else if (vendor === "AuthenticAMD") { 43 | return "amd"; 44 | } 45 | } 46 | return "unknown"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/common/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "./src/common", 3 | "spec_files": [ 4 | "**/*spec.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/common/models/DisplayFreqRes.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | export interface IDisplayFreqRes 20 | { 21 | displayName: string; 22 | activeMode: IDisplayMode; 23 | // active Mode is also included in displayModes 24 | displayModes: IDisplayMode[]; 25 | } 26 | 27 | export interface IDisplayMode 28 | { 29 | refreshRates: number[]; 30 | xResolution: number; 31 | yResolution: number; 32 | } -------------------------------------------------------------------------------- /src/common/models/IDeviceProperty.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | export interface ISysFsProperty { 20 | readonly readPath: string; 21 | readonly writePath: string; 22 | } 23 | -------------------------------------------------------------------------------- /src/common/models/IDrive.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | export interface IDrive { 21 | name: string; 22 | path: string; 23 | devPath: string; 24 | size: number; 25 | crypt: boolean; 26 | isParent: boolean; 27 | } -------------------------------------------------------------------------------- /src/common/models/ISystemProfileInfo.ts: -------------------------------------------------------------------------------- 1 | import { TUXEDODevice } from "./DefaultProfiles"; 2 | 3 | export interface SystemProfileInfo { 4 | pl: PowerLimit[]; 5 | } 6 | 7 | export interface PowerLimit { 8 | limit: number; 9 | odmName: string; 10 | systemProfile: SystemProfile; 11 | } 12 | 13 | export enum SystemProfile { 14 | ENERGYSAVE, 15 | SILENT, 16 | MAXPERFORMACE, 17 | ENTERTAINMENT 18 | } 19 | 20 | 21 | /* 22 | * Device specific ODM profile Info 23 | */ 24 | export const deviceSystemProfileInfo: Map = new Map(); 25 | 26 | deviceSystemProfileInfo.set(TUXEDODevice.IBP17G6, { 27 | pl:[ 28 | { limit: 24, odmName: "quiet", systemProfile: SystemProfile.SILENT}, 29 | { limit: 26, odmName: "power_saving", systemProfile: SystemProfile.ENERGYSAVE}, 30 | { limit: 36, odmName: "entertainment", systemProfile: SystemProfile.ENTERTAINMENT}, 31 | { limit: 40, odmName: "performance", systemProfile: SystemProfile.MAXPERFORMACE} 32 | ] 33 | }); 34 | 35 | /* 36 | * Power limits (W) Pulse Gen3 37 | * 38 | * Battery mode: 39 | * low-power pl1: 28, pl2: 28 40 | * balanced pl1: 30, pl2: 30 41 | * performace pl1: 35, pl2: 35 42 | * 43 | * USB-C mode: 44 | * low-power pl1: 35, pl2: 35 45 | * balanced pl1: 45, pl2: 54 46 | * performace pl1: 54, pl2: 54 47 | */ 48 | deviceSystemProfileInfo.set(TUXEDODevice.PULSE1403, { 49 | pl:[ 50 | { limit: 15, odmName: "low-power", systemProfile: SystemProfile.SILENT}, 51 | { limit: 35, odmName: "balanced", systemProfile: SystemProfile.ENERGYSAVE}, 52 | { limit: 54, odmName: "performance", systemProfile: SystemProfile.MAXPERFORMACE} 53 | ] 54 | }); 55 | 56 | deviceSystemProfileInfo.set(TUXEDODevice.PULSE1404, { 57 | pl:[ 58 | { limit: 15, odmName: "low-power", systemProfile: SystemProfile.SILENT}, 59 | { limit: 35, odmName: "balanced", systemProfile: SystemProfile.ENERGYSAVE}, 60 | { limit: 54, odmName: "performance", systemProfile: SystemProfile.MAXPERFORMACE} 61 | ] 62 | }); 63 | -------------------------------------------------------------------------------- /src/common/models/TccAutosave.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | export interface ITccAutosave { 20 | displayBrightness: number; 21 | } 22 | 23 | export const defaultAutosave: ITccAutosave = { 24 | displayBrightness: 100 25 | }; 26 | -------------------------------------------------------------------------------- /src/common/models/TccGpuValues.ts: -------------------------------------------------------------------------------- 1 | export interface IiGpuInfo { 2 | temp: number; 3 | coreFrequency: number; 4 | maxCoreFrequency: number; 5 | powerDraw: number; 6 | vendor: string; 7 | } 8 | 9 | export interface IdGpuInfo { 10 | coreFrequency: number; 11 | maxCoreFrequency: number; 12 | powerDraw: number; 13 | maxPowerLimit: number; 14 | enforcedPowerLimit: number; 15 | d0MetricsUsage?: boolean; 16 | } 17 | 18 | export interface IDeviceCounts { 19 | intelIGpuDevices: number; 20 | amdIGpuDevices: number; 21 | amdDGpuDevices: number; 22 | nvidiaDevices: number; 23 | } 24 | -------------------------------------------------------------------------------- /src/common/models/TccPowerSettings.ts: -------------------------------------------------------------------------------- 1 | export interface ICpuPower { 2 | powerDraw: number; 3 | maxPowerLimit?: number; 4 | } -------------------------------------------------------------------------------- /src/common/models/TccWebcamSettings.ts: -------------------------------------------------------------------------------- 1 | export interface WebcamDeviceInformation { 2 | active: boolean; 3 | category: string; 4 | current: string | number | boolean; 5 | default: string | number | boolean; 6 | max?: number; 7 | min?: number; 8 | name: string; 9 | step?: number; 10 | options?: string[]; 11 | title: string; 12 | type: string; 13 | } 14 | 15 | export interface WebcamPreset { 16 | active: boolean; 17 | presetName: string; 18 | webcamId: string; 19 | webcamSettings: WebcamPresetValues; 20 | } 21 | 22 | export interface WebcamPresetValues { 23 | auto_exposure?: string; 24 | backlight_compensation?: boolean; 25 | brightness?: number; 26 | contrast?: number; 27 | exposure_absolute?: number; 28 | exposure_auto?: string; 29 | exposure_auto_priority?: boolean; 30 | exposure_dynamic_framerate?: boolean; 31 | exposure_time_absolute?: number; 32 | fps?: number; 33 | gain?: number; 34 | gamma?: number; 35 | hue?: number; 36 | resolution?: string; 37 | saturation?: number; 38 | sharpness?: number; 39 | white_balance_automatic?: boolean; 40 | white_balance_temperature?: number; 41 | white_balance_temperature_auto?: boolean; 42 | [key: string]: any; 43 | } 44 | 45 | export interface WebcamDevice { 46 | deviceId: string; 47 | id: string; 48 | label: string; 49 | path: string; 50 | } 51 | 52 | export interface WebcamConstraints { 53 | deviceId: string | { exact: string }; 54 | frameRate: number | { exact: number }; 55 | height: number | { exact: number }; 56 | width: number | { exact: number }; 57 | } 58 | 59 | export interface WebcamPath { 60 | [key: string]: string; 61 | } 62 | -------------------------------------------------------------------------------- /src/dist-data/com.tuxedocomputers.tccd.conf: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | system 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/dist-data/com.tuxedocomputers.tccd.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | TUXEDO Computers GmbH 8 | https://www.tuxedocomputers.com/ 9 | 10 | 11 | Run TUXEDO Control Center Daemon 12 | TUXEDO Control Center Daemon ausführen 13 | Authentication is required to run/update the configuration of TUXEDO Control Center Daemon 14 | Zum Ausführen des TUXEDO Control Center Daemons ist eine Authentifizierung erforderlich 15 | 16 | 17 | 18 | 19 | auth_admin_keep 20 | auth_admin_keep 21 | auth_admin_keep 22 | 23 | 24 | /opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/service/tccd 25 | true 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/dist-data/com.tuxedocomputers.tomte.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | TUXEDO Computers GmbH 8 | https://www.tuxedocomputers.com/ 9 | 10 | 11 | Run TUXEDO tomte 12 | TUXEDO tomte ausführen 13 | Authentication is required to run TUXEDO tomte 14 | Zum Ausführen des TUXEDO tomte ist eine Authentifizierung erforderlich 15 | 16 | 17 | 18 | 19 | auth_admin_keep 20 | auth_admin_keep 21 | auth_admin_keep 22 | 23 | 24 | /usr/bin/tuxedo-tomte 25 | true 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/dist-data/tccd-sleep.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TUXEDO Control Center Service (sleep/resume) 3 | Before=sleep.target 4 | StopWhenUnneeded=yes 5 | 6 | [Service] 7 | Type=oneshot 8 | RemainAfterExit=yes 9 | ExecStart=/bin/bash -c "systemctl stop tccd" 10 | ExecStop=/bin/bash -c "systemctl start tccd" 11 | 12 | [Install] 13 | WantedBy=sleep.target -------------------------------------------------------------------------------- /src/dist-data/tccd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TUXEDO Control Center Service 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/service/tccd --start 7 | ExecStop=/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/service/tccd --stop 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | -------------------------------------------------------------------------------- /src/dist-data/tuxedo-control-center-tray.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=TUXEDO Control Center 3 | Comment=Tray icon for TUXEDO Control Center 4 | Exec=/opt/tuxedo-control-center/tuxedo-control-center --tray 5 | Terminal=false 6 | Type=Application 7 | Icon=tuxedo-control-center 8 | Categories=System;TrayIcon 9 | -------------------------------------------------------------------------------- /src/dist-data/tuxedo-control-center.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=TUXEDO Control Center 3 | Comment=An application helping you to tune your TUXEDO 4 | Exec="/opt/tuxedo-control-center/tuxedo-control-center" %U 5 | Terminal=false 6 | Type=Application 7 | Icon=/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/dist-data/tuxedo-control-center_256.svg 8 | StartupWMClass=tuxedo-control-center 9 | Categories=System; 10 | -------------------------------------------------------------------------------- /src/dist-data/tuxedo-control-center_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/dist-data/tuxedo-control-center_256.png -------------------------------------------------------------------------------- /src/e-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/tuxedo-control-center/e-app", 5 | "rootDir": "../", 6 | "module": "commonjs", 7 | "types": ["node"], 8 | "target": "es6" 9 | }, 10 | "exclude": [ 11 | "test.ts", 12 | "**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/ng-app/app/app.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | -------------------------------------------------------------------------------- /src/ng-app/app/app.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | .pagewrap { 20 | height: 100%; 21 | } 22 | -------------------------------------------------------------------------------- /src/ng-app/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | import { ElectronService } from 'ngx-electron'; 5 | 6 | describe('AppComponent', () => { 7 | beforeEach(async(() => { 8 | TestBed.configureTestingModule({ 9 | imports: [ 10 | RouterTestingModule 11 | ], 12 | declarations: [ 13 | AppComponent 14 | ], 15 | providers: [ 16 | ElectronService 17 | ] 18 | }).compileComponents(); 19 | })); 20 | 21 | it('should create the app', () => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | const app = fixture.debugElement.componentInstance; 24 | expect(app).toBeTruthy(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/ng-app/app/app.component.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { Component, HostBinding, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core'; 20 | import { ElectronService } from 'ngx-electron'; 21 | import { fromEvent, Subscription } from 'rxjs'; 22 | import { UtilsService } from './utils.service'; 23 | import { ActivatedRoute } from '@angular/router'; 24 | 25 | @Component({ 26 | selector: 'app-root', 27 | templateUrl: './app.component.html', 28 | styleUrls: ['./app.component.scss'] 29 | }) 30 | export class AppComponent implements OnInit, OnDestroy { 31 | 32 | @HostBinding('class') componentThemeCssClass; 33 | 34 | private subscriptions: Subscription = new Subscription(); 35 | 36 | constructor( 37 | private utils: UtilsService, 38 | private electron: ElectronService, 39 | private cdref: ChangeDetectorRef 40 | ) {} 41 | 42 | ngOnInit(): void { 43 | this.subscriptions.add(this.utils.themeClass.subscribe(themeClassName => { this.componentThemeCssClass = themeClassName; })); 44 | 45 | // Register light/dark update from main process 46 | const observeBrightnessMode = fromEvent(this.electron.ipcRenderer, 'update-brightness-mode'); 47 | this.subscriptions.add(observeBrightnessMode.subscribe(() => this.utils.updateBrightnessMode())); 48 | 49 | // Trigger manual update for initial state 50 | this.utils.updateBrightnessMode(); 51 | } 52 | 53 | ngAfterContentChecked() { 54 | this.cdref.detectChanges(); 55 | } 56 | 57 | ngOnDestroy(): void { 58 | this.subscriptions.unsubscribe(); 59 | } 60 | 61 | public pageDisabled(): boolean { 62 | return this.utils.pageDisabled; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/ng-app/app/aquaris-control/aquaris-control.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AquarisControlComponent } from './aquaris-control.component'; 4 | 5 | describe('AquarisControlComponent', () => { 6 | let component: AquarisControlComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ AquarisControlComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AquarisControlComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/change-crypt-password/change-crypt-password.component.scss: -------------------------------------------------------------------------------- 1 | .current-password-input { 2 | margin-bottom: 1em; 3 | } 4 | 5 | .controls { 6 | margin-top: 1em; 7 | button { 8 | margin-right: 1em; 9 | } 10 | } 11 | 12 | .mat-form-field { 13 | width: 25vw; 14 | } 15 | 16 | .mat-hint { 17 | float: right; 18 | } 19 | 20 | .error-hint { 21 | font-size: 95%; 22 | color: #f44336 !important; 23 | } -------------------------------------------------------------------------------- /src/ng-app/app/change-crypt-password/change-crypt-password.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangeCryptPasswordComponent } from './change-crypt-password.component'; 4 | 5 | describe('ChangeCryptPasswordComponent', () => { 6 | let component: ChangeCryptPasswordComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ChangeCryptPasswordComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangeCryptPasswordComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/compatibility.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { CompatibilityService } from './compatibility.service'; 4 | 5 | describe('CompatibilityService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: CompatibilityService = TestBed.get(CompatibilityService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/config.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ConfigService } from './config.service'; 4 | 5 | describe('ConfigService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: ConfigService = TestBed.get(ConfigService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/cpu-dashboard/cpu-dashboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CpuDashboardComponent } from './cpu-dashboard.component'; 4 | 5 | describe('CpuDashboardComponent', () => { 6 | let component: CpuDashboardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CpuDashboardComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CpuDashboardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/dashboard.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Resolve } from "@angular/router"; 3 | import { Observable, from } from "rxjs"; 4 | import { filter, first } from "rxjs/operators"; 5 | import { PowerStateService } from "./power-state.service"; 6 | 7 | @Injectable({ 8 | providedIn: "root", 9 | }) 10 | export class PowerStateStatusResolver implements Resolve { 11 | constructor(private power: PowerStateService) {} 12 | 13 | resolve(): Observable { 14 | return from(this.power.getDGpuPowerState()).pipe( 15 | filter((value) => value !== undefined), 16 | first() 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/ng-app/app/dbus.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DBusService } from './dbus.service'; 4 | 5 | describe('DbusService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: DBusService = TestBed.get(DBusService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-choice/dialog-choice.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |

{{ data.title }}

21 | 22 |

{{ data.heading }}

23 |

{{ data.description }}

24 |

{{ data.linkHref }}

25 |
26 | 27 | {{ 28 | data.checkboxNoBotherLabel }} 29 |
30 | 31 |
32 |
-------------------------------------------------------------------------------- /src/ng-app/app/dialog-choice/dialog-choice.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | a.link-style { 20 | color: currentColor; 21 | cursor: pointer; 22 | text-decoration: underline; 23 | } 24 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-confirm/dialog-confirm.component.html: -------------------------------------------------------------------------------- 1 | 19 |

{{ data.title }}

20 | 21 |

{{ data.heading }}

22 |

{{ data.description }}

23 |

{{ data.linkHref }}

24 |
25 | 26 | {{ data.checkboxNoBotherLabel }} 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-confirm/dialog-confirm.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | a.link-style { 20 | color: currentColor; 21 | cursor: pointer; 22 | text-decoration: underline; 23 | } 24 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-input-text/dialog-input-text.component.html: -------------------------------------------------------------------------------- 1 | 19 |

{{ data.title }}

20 | 21 |

{{ data.heading }}

22 | 23 | 31 | 32 |

{{ data.description }}

33 |
34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-input-text/dialog-input-text.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/app/dialog-input-text/dialog-input-text.component.scss -------------------------------------------------------------------------------- /src/ng-app/app/dialog-input-text/dialog-input-text.component.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { Component, Inject } from '@angular/core'; 20 | import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; 21 | 22 | export interface InputDialogData { 23 | title: string, 24 | heading: string, 25 | description: string, 26 | prefill: string, 27 | buttonAbortLabel: string, 28 | buttonConfirmLabel: string 29 | } 30 | 31 | @Component({ 32 | selector: 'app-dialog-input-text', 33 | templateUrl: './dialog-input-text.component.html', 34 | styleUrls: ['./dialog-input-text.component.scss'] 35 | }) 36 | export class DialogInputTextComponent { 37 | 38 | constructor( 39 | public dialogRef: MatDialogRef, 40 | @Inject(MAT_DIALOG_DATA) public data: InputDialogData) {} 41 | 42 | closeDialog(result?: string) { 43 | this.dialogRef.close(result); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-waiting/dialog-waiting.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |

{{ data.title }}

21 | 22 |

{{ data.description }}

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-waiting/dialog-waiting.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/app/dialog-waiting/dialog-waiting.component.scss -------------------------------------------------------------------------------- /src/ng-app/app/dialog-waiting/dialog-waiting.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { DialogWaitingComponent } from "./dialog-waiting.component"; 4 | 5 | describe("DialogWaitingComponent", () => { 6 | let component: DialogWaitingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [DialogWaitingComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(DialogWaitingComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it("should create", () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/ng-app/app/dialog-waiting/dialog-waiting.component.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | import { Component, Inject, OnInit } from "@angular/core"; 21 | import { FormControl } from "@angular/forms"; 22 | import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; 23 | import { 24 | DialogChoiceComponent, 25 | WaitingDialogData, 26 | } from "../dialog-choice/dialog-choice.component"; 27 | 28 | @Component({ 29 | selector: "app-dialog-waiting", 30 | templateUrl: "./dialog-waiting.component.html", 31 | styleUrls: ["./dialog-waiting.component.scss"], 32 | }) 33 | export class DialogWaitingComponent { 34 | public ctrlCheckboxNoBother: FormControl; 35 | 36 | constructor( 37 | public dialogRef: MatDialogRef, 38 | @Inject(MAT_DIALOG_DATA) public data: WaitingDialogData 39 | ) { 40 | this.ctrlCheckboxNoBother = new FormControl(false); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/ng-app/app/fan-graph/fan-graph.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 | 23 | 24 |
-------------------------------------------------------------------------------- /src/ng-app/app/fan-graph/fan-graph.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/app/fan-graph/fan-graph.component.scss -------------------------------------------------------------------------------- /src/ng-app/app/fan-graph/fan-graph.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FanGraphComponent } from './fan-graph.component'; 4 | 5 | describe('FanGraphComponent', () => { 6 | let component: FanGraphComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FanGraphComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FanGraphComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/fan-slider/fan-slider.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {{ formatTemperatureLabel(fanTableEntry.temp) }} 33 | 34 | 35 | 36 |
37 | 41 |
42 | 43 |
44 | 46 | 47 |
48 |
-------------------------------------------------------------------------------- /src/ng-app/app/fan-slider/fan-slider.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | .fan-slider-container { 21 | display: flex; 22 | flex-direction: column; 23 | align-items: center; 24 | 25 | margin-top: 20px; 26 | width: 100%; 27 | } 28 | 29 | canvas { 30 | width: 100%; 31 | margin-top: 20px; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/ng-app/app/fan-slider/fan-slider.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { FanSliderComponent } from "./fan-slider.component"; 4 | 5 | describe("FanSliderComponent", () => { 6 | let component: FanSliderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [FanSliderComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(FanSliderComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it("should create", () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/ng-app/app/global-settings/global-settings.component.scss: -------------------------------------------------------------------------------- 1 | .global-settings { 2 | display: block; 3 | position: absolute; 4 | top: 10px; 5 | bottom: 25px; 6 | right: 5px; 7 | left: 0px; 8 | margin: 0px; 9 | padding: 0px; 10 | overflow-y: scroll; 11 | } 12 | 13 | .inner-global-settings { 14 | margin: 0 10px 10px 10px; 15 | } 16 | 17 | header { 18 | width: 100%; 19 | padding-right: 20px; 20 | text-align: left; 21 | font-size: 1.15em; 22 | } 23 | 24 | content.value { 25 | width: 100%; 26 | text-align: left; 27 | font-weight: bold; 28 | font-size: 1.15em; 29 | } 30 | 31 | content.input { 32 | flex: 1; 33 | } 34 | 35 | .margin-top { 36 | margin-top: 0.8rem; 37 | } 38 | 39 | .margin-bottom { 40 | margin-bottom: 0.8rem; 41 | } 42 | 43 | .margin-left { 44 | margin-left: 2em; 45 | } 46 | 47 | .theme-settings-content { 48 | display: flex; 49 | justify-content: space-around; 50 | } 51 | 52 | .hide { 53 | display: none; 54 | } -------------------------------------------------------------------------------- /src/ng-app/app/global-settings/global-settings.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GlobalSettingsComponent } from './global-settings.component'; 4 | 5 | describe('GlobalSettingsComponent', () => { 6 | let component: GlobalSettingsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GlobalSettingsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GlobalSettingsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/info/info.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | .logo { 21 | width: 200px; 22 | } 23 | 24 | .content-container { 25 | max-width: 900px; 26 | margin:auto; 27 | text-align: center; 28 | } 29 | 30 | .updates-table { 31 | width:300px; 32 | margin:auto; 33 | text-align:left; 34 | margin-bottom: 20px; 35 | } 36 | 37 | .update-button { 38 | margin-bottom: 20px; 39 | } 40 | 41 | .infoseparator { 42 | position: static; 43 | width: 200px; 44 | right:0; 45 | margin: auto; 46 | margin-top: 20px; 47 | margin-bottom: 20px; 48 | } 49 | 50 | .accordion-info { 51 | p { 52 | font-size: 1.2em;; 53 | } 54 | } 55 | 56 | table.versions { 57 | tr { 58 | td { 59 | width: 250px; 60 | border-bottom: 1pt solid lightgray; 61 | } 62 | } 63 | } 64 | 65 | .changelog { 66 | max-height: 250px; 67 | overflow-y: scroll; 68 | } 69 | 70 | .language-select { 71 | mat-select-trigger { 72 | display: flex; 73 | justify-content: flex-start; 74 | align-items: center; 75 | 76 | mat-icon { 77 | margin-right: 16px; 78 | } 79 | } 80 | } 81 | 82 | .content-container mat-divider.divider-separator { 83 | position: static; width: 200px; margin: auto; margin-top: 20px; margin-bottom: 20px; 84 | } -------------------------------------------------------------------------------- /src/ng-app/app/info/info.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { InfoComponent } from './info.component'; 4 | 5 | describe('InfoComponent', () => { 6 | let component: InfoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ InfoComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(InfoComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/info/info.component.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { Component, OnInit, VERSION } from '@angular/core'; 20 | import { UtilsService } from '../utils.service'; 21 | 22 | @Component({ 23 | selector: 'app-info', 24 | templateUrl: './info.component.html', 25 | styleUrls: ['./info.component.scss'] 26 | }) 27 | export class InfoComponent implements OnInit { 28 | 29 | public appVersion = this.utils.getAppVersion(); 30 | public nodeVersion = this.utils.getProcessVersions().node; 31 | public electronVersion = this.utils.getProcessVersions().electron; 32 | public chromeVersion = this.utils.getProcessVersions().chrome; 33 | public angularVersion = VERSION.full; 34 | 35 | constructor( 36 | private utils: UtilsService 37 | ) { } 38 | 39 | ngOnInit() { 40 | } 41 | 42 | public changeLanguage(languageId: string) { 43 | if (languageId !== this.getCurrentLanguageId()) { 44 | this.utils.changeLanguage(languageId); 45 | } 46 | } 47 | 48 | public getCurrentLanguageId(): string { 49 | return this.utils.getCurrentLanguageId(); 50 | } 51 | 52 | public getLanguagesMenuArray() { 53 | return this.utils.getLanguagesMenuArray(); 54 | } 55 | 56 | public getLanguageData(langId: string) { 57 | return this.utils.getLanguageData(langId); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ng-app/app/keyboard-backlight/keyboard-backlight.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { KeyboardBacklightComponent } from './keyboard-backlight.component'; 4 | 5 | describe('KeyboardBacklightComponent', () => { 6 | let component: KeyboardBacklightComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ KeyboardBacklightComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(KeyboardBacklightComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/keyboard-visual/keyboard-visual.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2023 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | .keyboard { 21 | width: calc(14/18 * 100%); 22 | margin: 0 auto; 23 | } 24 | 25 | .key-group { 26 | stroke:darkslategrey; 27 | &.key-background-unselected .key_outline { 28 | stroke:darkslategrey; 29 | } 30 | &.key-background-selected .key_outline { 31 | stroke:slategrey; 32 | } 33 | &:hover { 34 | &.key-background-selected .key_outline, 35 | &.key-background-unselected .key_outline { 36 | stroke:LightGrey; 37 | } 38 | } 39 | } 40 | 41 | .unselected { 42 | opacity: 0.2; 43 | } 44 | 45 | .selected { 46 | opacity: 1; 47 | } -------------------------------------------------------------------------------- /src/ng-app/app/keyboard-visual/keyboard-visual.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { KeyboardVisualComponent } from "./keyboard-visual.component"; 4 | 5 | describe("KeyboardVisualComponent", () => { 6 | let component: KeyboardVisualComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [KeyboardVisualComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(KeyboardVisualComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it("should create", () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/ng-app/app/loader.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Resolve } from '@angular/router'; 3 | 4 | import { Observable, of, from } from 'rxjs'; 5 | import { TccDBusClientService } from './tcc-dbus-client.service'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class LoaderResolver implements Resolve> { 11 | constructor(private dbus: TccDBusClientService) {} 12 | 13 | resolve(): Observable { 14 | return from(this.waitForLoading()); 15 | } 16 | 17 | /** 18 | * @returns Promise that resolves to true when loaded, false if timed out 19 | */ 20 | private async waitForLoading() { 21 | return await this.waitForDBusData(2000); 22 | } 23 | 24 | private async waitForDBusData(timeoutMs: number) { 25 | let timedOut = false; 26 | setTimeout(() => { timedOut = true; }, timeoutMs); 27 | 28 | while (!this.dbus.dataLoaded && !timedOut) { 29 | await new Promise(resolve => setTimeout(resolve, 50)); 30 | } 31 | 32 | if (timedOut) { 33 | return false; 34 | } else { 35 | return true; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ng-app/app/main-gui/main-gui.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { MainGuiComponent } from './main-gui.component'; 4 | 5 | describe('MainGuiComponent', () => { 6 | let component: MainGuiComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ MainGuiComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(MainGuiComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/node.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { NodeService } from './node.service'; 4 | 5 | describe('NodeService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: NodeService = TestBed.get(NodeService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/node.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import * as os from 'os'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class NodeService { 9 | 10 | constructor() { } 11 | 12 | public getOs() { 13 | return os; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ng-app/app/power-state.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { AvailabilityService } from "src/common/classes/availability.service"; 3 | import * as path from "path"; 4 | import { amdDGpuDeviceIdString } from "src/common/classes/DeviceIDs"; 5 | import { UtilsService } from "./utils.service"; 6 | 7 | @Injectable({ 8 | providedIn: "root", 9 | }) 10 | export class PowerStateService { 11 | private busPath: string; 12 | 13 | constructor( 14 | public availability: AvailabilityService, 15 | private utils: UtilsService 16 | ) { 17 | if (this.availability.getNvidiaDGpuCount() === 1) { 18 | this.busPath = this.getBusPath("nvidia"); 19 | } else if (this.availability.getAmdDGpuCount() === 1) { 20 | this.busPath = this.getBusPath("amd"); 21 | } 22 | } 23 | 24 | private getBusPath(driver: string): string { 25 | let devicePattern: string; 26 | 27 | if (driver === "nvidia") { 28 | devicePattern = "DRIVER=nvidia"; 29 | } else if (driver === "amd") { 30 | devicePattern = "PCI_ID=" + amdDGpuDeviceIdString; 31 | } 32 | 33 | if (devicePattern) { 34 | const grepCmd = `grep -lx '${devicePattern}' /sys/bus/pci/devices/*/uevent | sed 's|/uevent||'`; 35 | return this.utils.execCmdSync(grepCmd).trim(); 36 | } 37 | return undefined; 38 | } 39 | 40 | public async getDGpuPowerState(): Promise { 41 | if (this.busPath) { 42 | try { 43 | const powerStatePath = path.join(this.busPath, "power_state"); 44 | const powerState = await this.utils.readTextFile( 45 | powerStatePath 46 | ); 47 | 48 | return powerState.trim(); 49 | } catch (err) { 50 | console.error("Failed to get power state of GPU: ", err); 51 | } 52 | } 53 | 54 | return "-1"; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ng-app/app/prime-dialog/prime-dialog.component.scss: -------------------------------------------------------------------------------- 1 | *, *.light { 2 | background: #FFFFFF; 3 | } 4 | 5 | @media (prefers-color-scheme: dark) { 6 | *, *.dark { 7 | background: #252525; 8 | } 9 | } 10 | 11 | .container { 12 | display: flex; 13 | flex-direction: column; 14 | height: 100%; 15 | padding: 24px; 16 | box-sizing: border-box; 17 | } 18 | 19 | .mat-dialog-title { 20 | margin-top: 0; 21 | } 22 | 23 | .mat-dialog-content { 24 | flex-grow: 1; 25 | } 26 | 27 | .content { 28 | overflow-wrap: break-word; 29 | } 30 | 31 | .action-row { 32 | display: flex; 33 | justify-content: flex-end; 34 | align-items: center; 35 | margin-top: auto; 36 | } 37 | 38 | button { 39 | margin-left: 8px; 40 | } 41 | 42 | .mat-progress-bar { 43 | width: 100%; 44 | height: 2px; 45 | margin-bottom: -2px; 46 | } 47 | -------------------------------------------------------------------------------- /src/ng-app/app/prime-dialog/prime-dialog.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { PrimeDialogComponent } from "./prime-dialog.component"; 4 | 5 | describe("PrimeDialogComponent", () => { 6 | let component: PrimeDialogComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PrimeDialogComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PrimeDialogComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it("should create", () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/ng-app/app/prime-select/prime-select.component.scss: -------------------------------------------------------------------------------- 1 | .prime-radio-group { 2 | display: flex; 3 | flex-direction: column; 4 | margin: 15px 0; 5 | align-items: flex-start; 6 | 7 | mat-radio-button { 8 | margin: 5px; 9 | 10 | .inner-label { 11 | padding-left: 8px; 12 | white-space: normal; 13 | 14 | header { 15 | font-size: 1.2em; 16 | font-weight: bolder; 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/ng-app/app/prime-select/prime-select.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { PrimeSelectComponent } from "./prime-select.component"; 4 | 5 | describe("PrimeSelectComponent", () => { 6 | let component: PrimeSelectComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [PrimeSelectComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(PrimeSelectComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it("should create", () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/ng-app/app/profile-conflict-dialog/profile-conflict-dialog.module.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*! 4 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 5 | * 6 | * This file is part of TUXEDO Control Center. 7 | * 8 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * TUXEDO Control Center is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with TUXEDO Control Center. If not, see . 20 | */ 21 | 22 | 23 | import {ProfileConflictComponent} from "./profile-conflict-dialog.component"; 24 | import { ProfileConflictDialogService } from "./profile-conflict-dialog.service"; 25 | import { CommonModule } from '@angular/common'; 26 | import { NgModule} from '@angular/core'; 27 | import { MatDialogModule } from '@angular/material/dialog'; 28 | @NgModule({ 29 | imports: [ 30 | CommonModule, 31 | MatDialogModule 32 | ], 33 | declarations: [ 34 | ProfileConflictComponent 35 | ], 36 | exports: [ProfileConflictComponent], 37 | entryComponents: [ProfileConflictComponent], 38 | providers: [ProfileConflictDialogService] 39 | }) 40 | export class ProfileConflictModule { 41 | } 42 | -------------------------------------------------------------------------------- /src/ng-app/app/profile-conflict-dialog/profile-conflict-dialog.service.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*! 4 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 5 | * 6 | * This file is part of TUXEDO Control Center. 7 | * 8 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * TUXEDO Control Center is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with TUXEDO Control Center. If not, see . 20 | */ 21 | 22 | import { Injectable } from '@angular/core'; 23 | import { Observable } from 'rxjs'; 24 | import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; 25 | import { ProfileConflictComponent, IProfileConflictDialogResult } from "./profile-conflict-dialog.component"; 26 | import { map, max, take } from 'rxjs/operators'; 27 | import { ITccProfile } from 'src/common/models/TccProfile'; 28 | 29 | 30 | 31 | 32 | @Injectable() 33 | export class ProfileConflictDialogService { 34 | 35 | constructor(private dialog: MatDialog) { } 36 | dialogRef: MatDialogRef; 37 | 38 | private open(oldProfile: ITccProfile, newProfile: ITccProfile) 39 | { 40 | this.dialogRef = this.dialog.open(ProfileConflictComponent, { 41 | data: { 42 | oldProfile: oldProfile, 43 | newProfile: newProfile 44 | } 45 | }); 46 | } 47 | 48 | 49 | 50 | private closed(): Observable 51 | { 52 | return this.dialogRef.afterClosed().pipe(take(1), map(res => { 53 | return res; 54 | } 55 | )); 56 | } 57 | 58 | public async openConflictModal(oldProfile: ITccProfile, importedProfile: ITccProfile,) 59 | { 60 | return new Promise((resolve, reject) => { 61 | this.open(oldProfile,importedProfile); 62 | 63 | this.closed().subscribe(confirmed => { 64 | if (confirmed) { 65 | resolve(confirmed); 66 | } 67 | else 68 | { 69 | reject({"action":"canceled","newName":""}); 70 | } 71 | }); 72 | 73 | }); 74 | } 75 | 76 | 77 | } -------------------------------------------------------------------------------- /src/ng-app/app/profile-details-edit/profile-details-edit.component-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin profile-details-edit-theme($theme) { 22 | 23 | $primary: map-get($theme, primary); 24 | $accent: map-get($theme, accent); 25 | $warn: map-get($theme, warn); 26 | $background: map-get($theme, background); 27 | 28 | .profile-details-edit { 29 | 30 | .profile-title { 31 | background-color: mat-color($background, card); 32 | } 33 | 34 | /*.mat-button-toggle { 35 | opacity: 0.8; 36 | color: mat-color($primary, lighter); 37 | } 38 | .mat-button-toggle-checked, .mat-button-toggle-disabled { 39 | opacity: 1.0; 40 | color: mat-color($primary); 41 | background: inherit; 42 | }*/ 43 | } 44 | } -------------------------------------------------------------------------------- /src/ng-app/app/profile-details-edit/profile-details-edit.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ProfileDetailsEditComponent } from './profile-details-edit.component'; 4 | 5 | describe('ProfileDetailsEditComponent', () => { 6 | let component: ProfileDetailsEditComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ProfileDetailsEditComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ProfileDetailsEditComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/profile-manager/profile-manager.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | mat-toolbar { 20 | 21 | mat-toolbar-row { 22 | align-items: center; 23 | button { 24 | margin-right: 10px; 25 | } 26 | 27 | mat-button-toggle-group, .import-export-buttons { 28 | transform: scale(0.7); 29 | transform-origin: right; 30 | 31 | svg { 32 | width: 40px; 33 | height: 40px; 34 | --icon-detail: var(--icon-main); 35 | } 36 | } 37 | 38 | form { 39 | transform: scale(0.8); 40 | transform-origin: bottom left; 41 | } 42 | } 43 | } 44 | .import-export-buttons 45 | { 46 | box-shadow: none; 47 | button 48 | { 49 | margin : 0 !important; 50 | background: none; 51 | border: 0; 52 | cursor: pointer; 53 | } 54 | 55 | } 56 | 57 | .profile-name-input { 58 | width: 250px; 59 | margin-right: 10px; 60 | } 61 | 62 | .desc { 63 | margin-top: 20px; 64 | font-size: 16px; 65 | opacity: 0.7; 66 | } 67 | 68 | .header-divider { 69 | border-bottom: 1px solid; 70 | border-color: rgba($color: #000000, $alpha: 0.12); 71 | } 72 | 73 | .mat-toolbar { 74 | background: none; 75 | } 76 | 77 | .profile-manager-content { 78 | position: absolute; 79 | top: 10px; 80 | bottom: 25px; 81 | right: 5px; 82 | left: 0px; 83 | margin: 0px; 84 | padding: 0px; 85 | overflow-y: auto; 86 | 87 | &.offset { 88 | top: 100px; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/ng-app/app/profile-manager/profile-manager.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ProfileManagerComponent } from './profile-manager.component'; 4 | 5 | describe('ProfileManagerComponent', () => { 6 | let component: ProfileManagerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ProfileManagerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ProfileManagerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/profile-overview-tile/profile-overview-tile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ProfileOverviewTileComponent } from './profile-overview-tile.component'; 4 | 5 | describe('ProfileOverviewTileComponent', () => { 6 | let component: ProfileOverviewTileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ProfileOverviewTileComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ProfileOverviewTileComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/program-management.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ProgramManagementService } from './program-management.service'; 4 | 5 | describe('ProgramManagementService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: ProgramManagementService = TestBed.get(ProgramManagementService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/settings.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Resolve } from "@angular/router"; 3 | import { Observable } from "rxjs"; 4 | import { TccDBusClientService } from "./tcc-dbus-client.service"; 5 | import { filter, first } from "rxjs/operators"; 6 | 7 | @Injectable({ 8 | providedIn: "root", 9 | }) 10 | export class ForceYUV420OutputSwitchResolver implements Resolve { 11 | constructor(private tccdbus: TccDBusClientService) {} 12 | 13 | resolve(): Observable { 14 | return this.tccdbus.forceYUV420OutputSwitchAvailable 15 | .asObservable() 16 | .pipe( 17 | filter((value) => value !== undefined), 18 | first() 19 | ); 20 | } 21 | } 22 | 23 | @Injectable({ 24 | providedIn: "root", 25 | }) 26 | export class ChargingProfilesAvailableResolver implements Resolve { 27 | constructor(private tccdbus: TccDBusClientService) {} 28 | 29 | resolve(): Observable { 30 | return this.tccdbus.chargingProfilesAvailable.asObservable().pipe( 31 | filter((value) => value !== undefined), 32 | first() 33 | ); 34 | } 35 | } 36 | 37 | @Injectable({ 38 | providedIn: "root", 39 | }) 40 | export class PrimeSelectAvailableResolver implements Resolve { 41 | constructor(private tccdbus: TccDBusClientService) {} 42 | 43 | resolve(): Observable { 44 | return this.tccdbus.primeState.asObservable().pipe( 45 | filter((value) => value !== undefined), 46 | first() 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ng-app/app/shutdown-timer/shutdown-timer.component.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 |

This sets a one time shutdown time. It will be automatically cleared on next 22 | boot, or when selecting "Delete Time" below.

23 | 24 |

Set shutdown time: {{ appliedTime }}

25 | 26 | 27 | Hour 28 | 29 | {{ hour.toString().length < 2 ? 0 + hour.toString() : 30 | hour.toString() }} 31 | 32 | 33 | 34 | 35 | Minute 36 | 37 | {{ minute.toString().length < 2 ? 0 + 38 | minute.toString() : minute.toString() }} 39 | 40 | 41 |
42 | 43 |
44 | 45 | 46 |
-------------------------------------------------------------------------------- /src/ng-app/app/shutdown-timer/shutdown-timer.component.scss: -------------------------------------------------------------------------------- 1 | .controls { 2 | button { 3 | margin-right: 1em; 4 | } 5 | } -------------------------------------------------------------------------------- /src/ng-app/app/shutdown-timer/shutdown-timer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ShutdownTimerComponent } from './shutdown-timer.component'; 4 | 5 | describe('ShutdownTimerComponent', () => { 6 | let component: ShutdownTimerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ShutdownTimerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ShutdownTimerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/state.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { StateService } from './state.service'; 4 | 5 | describe('StateService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: StateService = TestBed.get(StateService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/support/support.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | .card-support { 20 | .support-info-text { 21 | text-align: center; 22 | margin-bottom: 20px; 23 | } 24 | 25 | .phone-info, .web-info { 26 | display: flex; 27 | flex-flow: column; 28 | justify-content: space-evenly; 29 | align-items: center; 30 | 31 | width: 100%; 32 | height: 100%; 33 | 34 | mat-icon { 35 | transform: scale(2.5); 36 | } 37 | 38 | .phone-number { 39 | font-size: 1.3em; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/ng-app/app/support/support.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SupportComponent } from './support.component'; 4 | 5 | describe('SupportComponent', () => { 6 | let component: SupportComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SupportComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SupportComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/sys-fs.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { SysFsService } from './sys-fs.service'; 4 | 5 | describe('SysFsService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: SysFsService = TestBed.get(SysFsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/tcc-dbus-client.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { TccDBusClientService } from './tcc-dbus-client.service'; 4 | 5 | describe('TccDbusClientService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: TccDBusClientService = TestBed.get(TccDBusClientService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/tomte-gui/tomte-gui.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | .tomte-list-output-table { 20 | 21 | th, 22 | td 23 | { 24 | text-align: center; 25 | } 26 | th 27 | { 28 | font-size: large; 29 | } 30 | } 31 | 32 | .tomte-gui-title 33 | { 34 | text-align: center; 35 | font-size: 1.2em; 36 | font-weight: bold; 37 | } 38 | 39 | .tomte-local-spinner { 40 | position: fixed; 41 | left: 60%; 42 | top: 60%; 43 | transform: translate(-60%, -50%); 44 | z-index: 1000; 45 | font-size: 8rem; 46 | color: rgb(133, 133, 133); 47 | } 48 | 49 | .tomte-warning-text { 50 | color: rgb(230, 8, 8); 51 | } 52 | 53 | .tomte-gui-overlay { 54 | background-color:rgba(235, 223, 223, 0.116); 55 | position: absolute; 56 | top: 50%; 57 | left: 50%; 58 | -moz-transform: translateX(-50%) translateY(-50%); 59 | -webkit-transform: translateX(-50%) translateY(-50%); 60 | transform: translateX(-50%) translateY(-50%); 61 | } 62 | 63 | .tomte-table-padding 64 | { 65 | padding:20px; 66 | } 67 | 68 | .tomte-yes-button, .tomte-no-button 69 | { 70 | width: 100%; 71 | height: 70px; 72 | border:none; 73 | } 74 | 75 | .tomte-yes-button:disabled, .tomte-no-button:disabled, .tomte-yes-button:disabled:hover, .tomte-no-button:disabled:hover 76 | { 77 | background-color: grey; 78 | color: darkgrey; 79 | } 80 | 81 | .tomte-yes-button 82 | { 83 | background-color: red; 84 | 85 | } 86 | .tomte-yes-button:hover 87 | { 88 | background-color: darkgreen; 89 | } 90 | 91 | .tomte-no-button 92 | { 93 | background-color: green; 94 | } 95 | 96 | .tomte-no-button:hover 97 | { 98 | background-color: darkred; 99 | } -------------------------------------------------------------------------------- /src/ng-app/app/tomte-gui/tomte-gui.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TomteGuiComponent } from './tomte-gui.component'; 4 | 5 | describe('TomteGuiCompontent', () => { 6 | let component: TomteGuiComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TomteGuiComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TomteGuiComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/tools/tool.component.spec.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/app/tools/tool.component.spec.ts -------------------------------------------------------------------------------- /src/ng-app/app/tools/tool.component.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2023 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | import { Component, OnInit } from '@angular/core'; 21 | import { ActivatedRoute, Router } from '@angular/router'; 22 | import { CompatibilityService } from '../compatibility.service'; 23 | 24 | @Component({ 25 | selector: 'app-tools', 26 | templateUrl: './tools.component.html', 27 | styleUrls: ['./tools.component.scss'] 28 | }) 29 | export class ToolsComponent implements OnInit { 30 | constructor( 31 | public compat: CompatibilityService, 32 | private router: Router, 33 | private route: ActivatedRoute) {} 34 | 35 | ngOnInit() { 36 | 37 | } 38 | 39 | gotoComponent(component: string) { 40 | this.router.navigate([ component ], { relativeTo: this.route.parent }); 41 | } 42 | } -------------------------------------------------------------------------------- /src/ng-app/app/tools/tools.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/app/tools/tools.component.scss -------------------------------------------------------------------------------- /src/ng-app/app/utils.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { UtilsService } from './utils.service'; 4 | 5 | describe('UtilsService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: UtilsService = TestBed.get(UtilsService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ng-app/app/webcam-preview/webcam-preview.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
-------------------------------------------------------------------------------- /src/ng-app/app/webcam-preview/webcam-preview.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | .spinner { 20 | position: absolute; 21 | justify-content: center; 22 | align-items: center; 23 | vertical-align: middle; 24 | } 25 | 26 | .webcam { 27 | display: flex; 28 | justify-content: center; 29 | align-items: center; 30 | width: 100%; 31 | height: 100%; 32 | 33 | overflow: hidden !important; 34 | overflow-y: hidden !important; 35 | overflow-x: hidden !important; 36 | } 37 | 38 | *, *.light { 39 | background-color: #F5F5F5; 40 | } 41 | 42 | @media (prefers-color-scheme: dark) { 43 | *, *.dark { 44 | background-color: #252525; 45 | } 46 | } -------------------------------------------------------------------------------- /src/ng-app/app/webcam-preview/webcam-preview.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { WebcamPreviewComponent } from './webcam-preview.component'; 4 | 5 | describe('WebcamPreviewComponent', () => { 6 | let component: WebcamPreviewComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ WebcamPreviewComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(WebcamPreviewComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/webcam-preview/webcam-preview.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeDetectorRef, 3 | Component, 4 | ElementRef, 5 | OnInit, 6 | ViewChild, 7 | } from "@angular/core"; 8 | import { ElectronService } from "ngx-electron"; 9 | import { WebcamConstraints } from "src/common/models/TccWebcamSettings"; 10 | 11 | @Component({ 12 | selector: "app-webcam-preview", 13 | templateUrl: "./webcam-preview.component.html", 14 | styleUrls: ["./webcam-preview.component.scss"], 15 | }) 16 | export class WebcamPreviewComponent implements OnInit { 17 | constructor( 18 | private electron: ElectronService, 19 | private cdref: ChangeDetectorRef 20 | ) {} 21 | 22 | @ViewChild("video", { static: true }) 23 | public video: ElementRef; 24 | mediaDeviceStream: any; 25 | spinnerActive: boolean = false; 26 | 27 | ngOnInit(): void { 28 | this.electron.ipcRenderer.on( 29 | "setting-webcam-with-loading", 30 | async (event, config) => { 31 | document.getElementById("video").style.visibility = "hidden"; 32 | this.spinnerActive = true; 33 | this.cdref.detectChanges(); 34 | this.stopWebcam(); 35 | await this.setWebcamWithConfig(config); 36 | this.electron.ipcRenderer.send("apply-controls"); 37 | setTimeout(async () => { 38 | document.getElementById("video").style.visibility = 39 | "visible"; 40 | this.spinnerActive = false; 41 | this.cdref.detectChanges(); 42 | }, 500); 43 | } 44 | ); 45 | } 46 | 47 | private async setWebcamWithConfig( 48 | config: WebcamConstraints 49 | ): Promise { 50 | await navigator.mediaDevices 51 | .getUserMedia({ 52 | video: config, 53 | }) 54 | .then(async (stream) => { 55 | this.video.nativeElement.srcObject = stream; 56 | this.mediaDeviceStream = stream; 57 | }); 58 | this.mediaDeviceStream.getVideoTracks()[0].onended = () => { 59 | this.electron.ipcRenderer.send("video-ended"); 60 | }; 61 | } 62 | 63 | private stopWebcam() { 64 | this.video.nativeElement.pause(); 65 | if (this.mediaDeviceStream != undefined) { 66 | for (const track of this.mediaDeviceStream.getTracks()) { 67 | track.stop(); 68 | } 69 | } 70 | this.video.nativeElement.srcObject = null; 71 | } 72 | 73 | async ngOnDestroy() { 74 | this.stopWebcam(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/ng-app/app/webcam-settings/webcam-settings.component-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin profile-details-edit-theme($theme) { 22 | 23 | $primary: map-get($theme, primary); 24 | $accent: map-get($theme, accent); 25 | $warn: map-get($theme, warn); 26 | $background: map-get($theme, background); 27 | 28 | .webcam-settings-edit { 29 | .webcam-title { 30 | background-color: mat-color($background, card); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/ng-app/app/webcam-settings/webcam-settings.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { WebcamSettingsComponent } from './webcam-settings.component'; 4 | 5 | describe('WebcamSettingsComponent', () => { 6 | let component: WebcamSettingsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ WebcamSettingsComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(WebcamSettingsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/ng-app/app/webcam.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { FormGroup } from "@angular/forms"; 3 | import { CanDeactivate } from "@angular/router"; 4 | import { UtilsService } from "./utils.service"; 5 | 6 | export interface CanComponentDeactivate { 7 | webcamFormGroup: FormGroup; 8 | } 9 | 10 | @Injectable({ 11 | providedIn: "root", 12 | }) 13 | export class WebcamSettingsGuard 14 | implements CanDeactivate 15 | { 16 | constructor(private utils: UtilsService) {} 17 | loading: boolean = false; 18 | 19 | askUnsavedPreset() { 20 | let config = { 21 | title: $localize`:@@webcamDialogUnsavedChangesTitle:Unsaved changes`, 22 | description: $localize`:@@webcamDialogUnsavedChangesDescription:Changes were not saved. Are you sure that you want to leave before saving?`, 23 | buttonAbortLabel: $localize`:@@dialogReturn:Go back`, 24 | buttonConfirmLabel: $localize`:@@dialogLeave:Leave`, 25 | }; 26 | return this.utils.confirmDialog(config); 27 | } 28 | 29 | public setLoadingStatus(status: boolean) { 30 | this.loading = status; 31 | } 32 | 33 | public async canDeactivate(component: CanComponentDeactivate) { 34 | if (component.webcamFormGroup.dirty) { 35 | let canRoute: boolean; 36 | await this.askUnsavedPreset().then((x) => { 37 | canRoute = x["confirm"]; 38 | }); 39 | return canRoute; 40 | } 41 | 42 | if (this.loading) { 43 | return false; 44 | } 45 | 46 | return true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/ng-app/app/x11.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Resolve } from "@angular/router"; 3 | import { Observable, from } from "rxjs"; 4 | import { filter, first } from "rxjs/operators"; 5 | import { TccDBusClientService } from "./tcc-dbus-client.service"; 6 | 7 | @Injectable({ 8 | providedIn: "root", 9 | }) 10 | export class X11StatusResolver implements Resolve { 11 | constructor(private tccdbus: TccDBusClientService) {} 12 | 13 | resolve(): Observable { 14 | return from(this.tccdbus.isX11.asObservable()).pipe( 15 | filter((value) => value !== undefined), 16 | first() 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/ng-app/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/.gitkeep -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font Awesome Free License 2 | ------------------------- 3 | 4 | Font Awesome Free is free, open source, and GPL friendly. You can use it for 5 | commercial projects, open source projects, or really almost whatever you want. 6 | Full Font Awesome Free license: https://fontawesome.com/license/free. 7 | 8 | # Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) 9 | In the Font Awesome Free download, the CC BY 4.0 license applies to all icons 10 | packaged as SVG and JS file types. 11 | 12 | # Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) 13 | In the Font Awesome Free download, the SIL OFL license applies to all icons 14 | packaged as web and desktop font files. 15 | 16 | # Code: MIT License (https://opensource.org/licenses/MIT) 17 | In the Font Awesome Free download, the MIT license applies to all non-font and 18 | non-icon files. 19 | 20 | # Attribution 21 | Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font 22 | Awesome Free files already contain embedded comments with sufficient 23 | attribution, so you shouldn't need to do anything additional when using these 24 | files normally. 25 | 26 | We've kept attribution comments terse, so we ask that you do not actively work 27 | to remove them from files, especially code. They're a great way for folks to 28 | learn about Font Awesome. 29 | 30 | # Brand Icons 31 | All brand icons are trademarks of their respective owners. The use of these 32 | trademarks does not indicate endorsement of the trademark holder by Font 33 | Awesome, nor vice versa. **Please do not use brand logos for any purpose except 34 | to represent the company, product, or service to which they refer.** 35 | -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fontawesome-free-5.9.0-web/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-Black.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-Bold.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-BoldItalic.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-ExtraLight.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-Italic.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-Light.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-LightItalic.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-Regular.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-SemiBold.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/TitilliumWeb-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/TitilliumWeb-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/material-icons.css: -------------------------------------------------------------------------------- 1 | /* fallback */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | font-display: block; 7 | src: url(./material-icons.woff2) format('woff2'); 8 | } 9 | 10 | .material-icons { 11 | font-family: 'Material Icons'; 12 | font-weight: normal; 13 | font-style: normal; 14 | font-size: 24px; 15 | line-height: 1; 16 | letter-spacing: normal; 17 | text-transform: none; 18 | display: inline-block; 19 | white-space: nowrap; 20 | word-wrap: normal; 21 | direction: ltr; 22 | -moz-font-feature-settings: 'liga'; 23 | -moz-osx-font-smoothing: grayscale; 24 | } -------------------------------------------------------------------------------- /src/ng-app/assets/fonts/material-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/fonts/material-icons.woff2 -------------------------------------------------------------------------------- /src/ng-app/assets/images/anydesk-logo-icon.svg: -------------------------------------------------------------------------------- 1 | anydesk-logo-icon -------------------------------------------------------------------------------- /src/ng-app/assets/images/german.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_allprofiles.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 19 | 20 | 21 | 34 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_batterycharger.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_close.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_download.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 19 | 20 | 21 | 28 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_minimize.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_power.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 20 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_reset.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 20 | 21 | 22 | 23 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_stopwatch.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 19 | 20 | 21 | 22 | 25 | 26 | 29 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/icon_temperature.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 19 | 20 | 21 | 28 | -------------------------------------------------------------------------------- /src/ng-app/assets/images/support.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | 10 | 12 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/ng-app/assets/tuxedo-control-center_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/assets/tuxedo-control-center_256.png -------------------------------------------------------------------------------- /src/ng-app/common/formErrorStateMatcher.ts: -------------------------------------------------------------------------------- 1 | import { FormControl, FormGroupDirective, NgForm } from '@angular/forms'; 2 | import { ErrorStateMatcher } from '@angular/material/core'; 3 | 4 | export class FormErrorStateMatcher implements ErrorStateMatcher { 5 | isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { 6 | const invalidCtrl = !!(control && control.invalid && control.parent.dirty); 7 | const invalidParent = !!(control && control.parent && control.parent.invalid && control.parent.dirty); 8 | 9 | return (invalidCtrl || invalidParent); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/ng-app/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/ng-app/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /src/ng-app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxedocomputers/tuxedo-control-center/094e07c294afbb760da1bcb490b6c585f75e8401/src/ng-app/favicon.ico -------------------------------------------------------------------------------- /src/ng-app/index.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | TUXEDO Control Center 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/ng-app/main.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { enableProdMode } from '@angular/core'; 20 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 21 | 22 | import { AppModule } from './app/app.module'; 23 | import { environment } from './environments/environment'; 24 | 25 | if (environment.production) { 26 | enableProdMode(); 27 | } 28 | 29 | platformBrowserDynamic().bootstrapModule(AppModule, { 30 | providers: [] 31 | }).catch(err => console.error(err)); 32 | -------------------------------------------------------------------------------- /src/ng-app/native/child_process.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('child_process'); -------------------------------------------------------------------------------- /src/ng-app/native/crypto.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('crypto'); -------------------------------------------------------------------------------- /src/ng-app/native/fs.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('fs'); -------------------------------------------------------------------------------- /src/ng-app/native/http.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('http'); -------------------------------------------------------------------------------- /src/ng-app/native/https.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('https'); -------------------------------------------------------------------------------- /src/ng-app/native/net.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('net'); -------------------------------------------------------------------------------- /src/ng-app/native/os.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('os'); -------------------------------------------------------------------------------- /src/ng-app/native/path.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('path'); -------------------------------------------------------------------------------- /src/ng-app/native/stream.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('stream'); -------------------------------------------------------------------------------- /src/ng-app/native/timers.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('timers'); -------------------------------------------------------------------------------- /src/ng-app/native/x11.js: -------------------------------------------------------------------------------- 1 | module.exports = window.require('x11'); -------------------------------------------------------------------------------- /src/ng-app/tcc-changelog-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin tcc-changelog-theme($theme) { 22 | $primary: map-get($theme, primary); 23 | $accent: map-get($theme, accent); 24 | $warn: map-get($theme, warn); 25 | $foreground: map-get($theme, foreground); 26 | $background: map-get($theme, background); 27 | 28 | .changelog { 29 | background-color: mat-color($background, background); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ng-app/tcc-charts-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2021 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin tcc-charts-theme($theme) { 22 | $primary: map-get($theme, primary); 23 | $accent: map-get($theme, accent); 24 | $warn: map-get($theme, warn); 25 | $foreground: map-get($theme, foreground); 26 | $background: map-get($theme, background); 27 | 28 | canvas.tcc-charts { 29 | background-color: mat-color($background, card); 30 | } 31 | 32 | .tcc-charts-text { 33 | color: mat-color($primary); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ng-app/tcc-color-picker-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin tcc-color-picker-theme($theme) { 22 | $primary: map-get($theme, primary); 23 | $accent: map-get($theme, accent); 24 | $warn: map-get($theme, warn); 25 | $foreground: map-get($theme, foreground); 26 | $background: map-get($theme, background); 27 | 28 | .tcc-color-picker+color-picker>.color-picker { 29 | box-shadow: 0px 2px 1px -1px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%); 30 | background-color: mat-color($background, card); 31 | 32 | &.open { 33 | margin: 0 auto; 34 | border-style: none; 35 | 36 | .type-policy { 37 | filter: invert(map-get($theme, --icon-invert)); 38 | } 39 | 40 | .cursor { 41 | filter: invert(map-get($theme, --icon-invert)); 42 | } 43 | 44 | .saturation-lightness { 45 | border-radius: 4px; 46 | } 47 | 48 | .hue { 49 | border-radius: 8px; 50 | } 51 | 52 | .hex-text * { 53 | color: mat-color($foreground, text); 54 | } 55 | 56 | .hsla-text * { 57 | color: mat-color($foreground, text); 58 | } 59 | 60 | .rgba-text * { 61 | color: mat-color($foreground, text); 62 | } 63 | 64 | .box div { 65 | color: mat-color($foreground, text-disabled); 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/ng-app/tcc-general-defs-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | @import '~@angular/material/theming'; 20 | 21 | @mixin tcc-general-defs-theme($theme) { 22 | $primary: map-get($theme, primary); 23 | $accent: map-get($theme, accent); 24 | $warn: map-get($theme, warn); 25 | $foreground: map-get($theme, foreground); 26 | $background: map-get($theme, background); 27 | 28 | 29 | /* 30 | * Definitions for general use of theme colors not warranting their own file 31 | */ 32 | .color-primary { 33 | color: mat-color($primary) !important; 34 | } 35 | 36 | .color-accent { 37 | color: mat-color($accent) !important; 38 | } 39 | 40 | .color-warn { 41 | color: mat-color($warn) !important; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/ng-app/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/ng-app/themes/tuxedo-dark-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | $tuxedo-dark-theme-primary: mat-palette($mat-grey, 400, 50, 600); 20 | $tuxedo-dark-theme-accent: mat-palette($mat-yellow); 21 | $tuxedo-dark-theme-warn: mat-palette($mat-red); 22 | 23 | $tuxedo-control-center-dark-theme: map-merge(mat-dark-theme($tuxedo-dark-theme-primary, $tuxedo-dark-theme-accent, $tuxedo-dark-theme-warn), ( 24 | background: map-merge($mat-dark-theme-background, ( 25 | dialog: #252525, 26 | card: #252525, 27 | status-bar: #151515, 28 | )), 29 | 30 | --icon-invert: 100% 31 | )); 32 | 33 | .dark-theme { 34 | @include angular-material-theme($tuxedo-control-center-dark-theme); 35 | @include component-themes($tuxedo-control-center-dark-theme); 36 | 37 | --icon-main: currentColor; 38 | --icon-detail: #e30016; 39 | 40 | .theme-page-title { 41 | opacity: 0.7; 42 | font-weight: 600; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/ng-app/themes/tuxedo-light-theme.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2020 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | $tuxedo-light-theme-primary: mat-palette($mat-grey, 600, 400, 900); 20 | $tuxedo-light-theme-accent: mat-palette($mat-yellow); 21 | $tuxedo-light-theme-warn: mat-palette($mat-red); 22 | 23 | //$tuxedo-control-center-light-theme: mat-light-theme($tuxedo-light-theme-primary, $tuxedo-light-theme-accent, $tuxedo-light-theme-warn); 24 | 25 | $tuxedo-control-center-light-theme: map-merge(mat-light-theme($tuxedo-light-theme-primary, $tuxedo-light-theme-accent, $tuxedo-light-theme-warn), ( 26 | background: map-merge($mat-light-theme-background, ( 27 | )), 28 | 29 | foreground: map-merge($mat-light-theme-foreground, ( 30 | mat-toolbar-text: #F5F5F5 31 | )), 32 | 33 | --icon-invert: 0% 34 | )); 35 | 36 | 37 | .light-theme { 38 | @include angular-material-theme($tuxedo-control-center-light-theme); 39 | @include component-themes($tuxedo-control-center-light-theme); 40 | 41 | --icon-main: currentColor; 42 | --icon-detail: #e30016; 43 | 44 | .theme-page-title { 45 | opacity: 0.7; 46 | font-weight: 600; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tuxedo-control-center", 3 | "version": "2.1.16", 4 | "main": "./e-app/e-app/main.js", 5 | "bin": "./service-app/main.js", 6 | "license": "GPL-3.0" 7 | } 8 | -------------------------------------------------------------------------------- /src/service-app/classes/DaemonListener.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2024 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { TuxedoControlCenterDaemon } from './TuxedoControlCenterDaemon'; 20 | 21 | export abstract class DaemonListener { 22 | constructor(protected tccd: TuxedoControlCenterDaemon) {} 23 | 24 | public abstract onActiveProfileChanged(): void; 25 | } 26 | -------------------------------------------------------------------------------- /src/service-app/classes/DaemonWorker.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019-2022 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | import { ITccSettings } from '../../common/models/TccSettings'; 20 | import { ITccProfile } from '../../common/models/TccProfile'; 21 | import { TuxedoControlCenterDaemon } from './TuxedoControlCenterDaemon'; 22 | 23 | export abstract class DaemonWorker { 24 | 25 | constructor( 26 | public readonly timeout: number, 27 | // Also inject the state (i.e configs etc..) 28 | protected tccd: TuxedoControlCenterDaemon) {} 29 | 30 | public timer: NodeJS.Timer; 31 | 32 | protected previousProfile: ITccProfile; 33 | protected activeProfile: ITccProfile; 34 | 35 | protected abstract onStart(): void; 36 | protected abstract onWork(): void; 37 | protected abstract onExit(): void; 38 | 39 | public start(): void { this.triggerWork(this.onStart); } 40 | public work(): void { this.triggerWork(this.onWork); } 41 | public exit(): void { this.triggerWork(this.onExit); } 42 | 43 | public updateProfile(activeProfile: ITccProfile): void { 44 | this.activeProfile = activeProfile; 45 | } 46 | 47 | private triggerWork(eventFunction: () => void): void { 48 | eventFunction.call(this); 49 | this.previousProfile = this.activeProfile; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/service-app/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "./src/service-app", 3 | "spec_files": [ 4 | "**/*spec.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/service-app/main.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 TUXEDO Computers GmbH 3 | * 4 | * This file is part of TUXEDO Control Center. 5 | * 6 | * TUXEDO Control Center is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TUXEDO Control Center is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TUXEDO Control Center. If not, see . 18 | */ 19 | 20 | /** 21 | * Start point of TUXEDO Control Center Service 22 | */ 23 | import { TuxedoControlCenterDaemon } from './classes/TuxedoControlCenterDaemon'; 24 | 25 | const tccd = new TuxedoControlCenterDaemon(); 26 | 27 | // Start program 28 | tccd.main().catch((err) => tccd.catchError(err)); 29 | -------------------------------------------------------------------------------- /src/service-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/tuxedo-control-center/service-app", 5 | "rootDir": "../", 6 | "module": "commonjs", 7 | "types": ["node"], 8 | "target": "es6" 9 | }, 10 | "exclude": [ 11 | "test.ts", 12 | "**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/udev/99-webcam.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="video4linux", ACTION=="add", KERNEL=="video[0-9]*", RUN+="/usr/bin/python3 /opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/camera/cameractrls.py -s $devnode,$env{ID_VENDOR_ID},$env{ID_MODEL_ID},/etc/tcc/webcam,/opt/tuxedo-control-center/resources/dist/tuxedo-control-center/data/camera/v4l2_kernel_names.json" 2 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "paths": { 6 | "fs": [ "./src/ng-app/native/fs.js" ], 7 | "path": [ "./src/ng-app/native/path.js" ], 8 | "os": [ "./src/ng-app/native/os.js" ], 9 | "child_process": [ "./src/ng-app/native/child_process.js" ], 10 | "crypto": [ "./src/ng-app/native/crypto.js" ], 11 | "net": [ "./src/ng-app/native/net.js" ], 12 | "stream": [ "./src/ng-app/native/stream.js" ], 13 | "timers": [ "./src/ng-app/native/timers.js" ], 14 | "x11": [ "./src/ng-app/native/x11.js" ], 15 | "http": [ "./src/ng-app/native/http.js" ], 16 | "https": [ "./src/ng-app/native/https.js" ] 17 | } 18 | }, 19 | "files": [ 20 | "src/ng-app/main.ts", 21 | "src/ng-app/polyfills.ts" 22 | ], 23 | "include": [ 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "module": "es2020", 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "moduleResolution": "node", 11 | "experimentalDecorators": true, 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/ng-app/test.ts", 12 | "src/ng-app/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------