mirror of
https://github.com/VirtualDrivers/Virtual-Display-Driver.git
synced 2026-10-20 21:59:55 -05:00
Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb98721da4 | ||
|
|
3e65bc8749 | ||
|
|
8de4f3b000 | ||
|
|
79810cb48d | ||
|
|
a3564fbf01 | ||
|
|
6c125361ac | ||
|
|
266b4a01c3 | ||
|
|
0d36d2a655 | ||
|
|
5dc87774c5 | ||
|
|
68b92409a6 | ||
|
|
80861064e8 | ||
|
|
2fd04a231b | ||
|
|
1ef82c3e6a | ||
|
|
3895ea6b4b | ||
|
|
13bb8cc323 | ||
|
|
f9f95e319c | ||
|
|
22535e68de | ||
|
|
fc73feaa47 | ||
|
|
698c735bdf | ||
|
|
9cb856f645 | ||
|
|
cdc9ed24d3 | ||
|
|
9f90a294ee | ||
|
|
2f3f3c044c | ||
|
|
63c3899826 | ||
|
|
a28ec0eb51 | ||
|
|
d03bf38ff6 | ||
|
|
4bc7e80234 | ||
|
|
25a53cab3a | ||
|
|
88d36bc1b5 | ||
|
|
68712353e3 | ||
|
|
ec5c792903 |
No files matched your search
@@ -0,0 +1,141 @@
|
||||
name: Virtual Display Driver Signpath Request
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Release]
|
||||
platform: [x64, ARM64]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Check Chocolatey installation
|
||||
run: choco --version
|
||||
|
||||
- name: Install Visual Studio 2022 dependencies
|
||||
run: |
|
||||
choco install visualstudio2022-workload-manageddesktop -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install visualstudio2022-workload-nativedesktop -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install visualstudio2022-workload-vctools -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install windowsdriverkit11 -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
- name: Build the driver
|
||||
run: |
|
||||
msbuild "Virtual Display Driver (HDR)/MTTVDD.sln" /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }}
|
||||
|
||||
- name: List build directory
|
||||
run: dir "Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD"
|
||||
|
||||
- name: Upload built driver
|
||||
id: upload_artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Built-Driver-${{ matrix.configuration }}-${{ matrix.platform }}
|
||||
path: |
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\MttVDD.dll
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\MttVDD.inf
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\mttvdd.cat
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\vdd_settings.xml
|
||||
|
||||
- name: Generate release tag
|
||||
id: generate_tag
|
||||
run: |
|
||||
$releaseTag = (Get-Date).ToString('yy.MM.dd')
|
||||
echo "RELEASE_TAG=$releaseTag" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Show generated release tag
|
||||
run: |
|
||||
echo "Generated Release Tag: ${{ env.RELEASE_TAG }}"
|
||||
|
||||
- name: Verify Built Artifacts
|
||||
run: dir 'Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD'
|
||||
|
||||
|
||||
- name: Submit signing request to SignPath
|
||||
id: signpath_request
|
||||
uses: signpath/github-action-submit-signing-request@v1
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
|
||||
project-slug: '${{ vars.SIGNPATH_PROJECT_SLUG }}'
|
||||
signing-policy-slug: '${{ vars.SIGNPATH_POLICY_SLUG }}'
|
||||
github-artifact-id: '${{ steps.upload_artifact.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: '${{ vars.SIGNPATH_OUTPUT_DIR }}'
|
||||
parameters: |
|
||||
Version: ${{ toJSON(matrix.configuration) }}
|
||||
Release_Tag: "${{ env.RELEASE_TAG }}"
|
||||
|
||||
- name: Verify Signed Artifacts
|
||||
run: dir '${{ vars.SIGNPATH_OUTPUT_DIR }}'
|
||||
|
||||
- name: Upload signed artifacts
|
||||
id: upload_signed_artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Signed-Driver-${{ matrix.configuration }}-${{ matrix.platform }}
|
||||
path: |
|
||||
${{ vars.SIGNPATH_OUTPUT_DIR }}\MttVDD.dll
|
||||
${{ vars.SIGNPATH_OUTPUT_DIR }}\MttVDD.inf
|
||||
${{ vars.SIGNPATH_OUTPUT_DIR }}\mttvdd.cat
|
||||
${{ vars.SIGNPATH_OUTPUT_DIR }}\vdd_settings.xml
|
||||
|
||||
- name: Prepare Setup Repository
|
||||
run: |
|
||||
git clone https://${{ secrets.READ_REPO }}@github.com/VirtualDisplay/vdd-innosetupscript.git inno-setup
|
||||
|
||||
- name: Prepare Setup
|
||||
run: |
|
||||
copy "${{ vars.SIGNPATH_OUTPUT_DIR }}\*" inno-setup\input\
|
||||
$platform = "${{ matrix.platform }}"
|
||||
(Get-Content "inno-setup\Setup.iss") |
|
||||
ForEach-Object { $_ -replace '1.0.0', '${{ env.RELEASE_TAG }}' } |
|
||||
Set-Content "inno-setup\Setup.iss"
|
||||
|
||||
if ($platform -eq 'ARM64') {
|
||||
(Get-Content "inno-setup\Setup.iss") |
|
||||
ForEach-Object { $_ -replace 'x64compatible', 'arm64' } |
|
||||
Set-Content "inno-setup\Setup.iss"
|
||||
|
||||
(Get-Content "inno-setup\Setup.iss") |
|
||||
ForEach-Object { $_ -replace '-x64', '-arm64' } |
|
||||
Set-Content "inno-setup\Setup.iss"
|
||||
|
||||
if (Test-Path "inno-setup\input\Companion\VDDSysTray.exe") {Remove-Item "inno-setup\input\Companion\VDDSysTray.exe"}
|
||||
copy "inno-setup\input\Companion\arm64\VDDSysTray.exe" "inno-setup\input\Companion\"
|
||||
}
|
||||
|
||||
- name: Compile Installer
|
||||
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
|
||||
with:
|
||||
path: inno-setup\Setup.iss
|
||||
options: /O+
|
||||
|
||||
- name: Upload Installer as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Installer-${{ matrix.configuration }}-${{ matrix.platform }}
|
||||
path: inno-setup\output\*.exe
|
||||
|
||||
|
||||
celebrate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Celebrate
|
||||
run: |
|
||||
echo "Bud is a god, also hi if you're looking at this!"
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
name: Virtual Display Driver Building
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
platform: [x64, ARM64]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Check Chocolatey installation
|
||||
run: choco --version
|
||||
|
||||
- name: Install Visual Studio 2022 dependencies
|
||||
run: |
|
||||
choco install visualstudio2022-workload-manageddesktop -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install visualstudio2022-workload-nativedesktop -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install visualstudio2022-workload-vctools -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
choco install windowsdriverkit11 -y
|
||||
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||
|
||||
- name: Build the driver
|
||||
run: |
|
||||
msbuild "Virtual Display Driver (HDR)/MTTVDD.sln" /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }}
|
||||
|
||||
- name: List build directory
|
||||
run: dir "Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD"
|
||||
|
||||
- name: Upload built driver
|
||||
id: upload_artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Built-Driver-${{ matrix.configuration }}-${{ matrix.platform }}
|
||||
path: |
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\MttVDD.dll
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\MttVDD.inf
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\mttvdd.cat
|
||||
Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD\vdd_settings.xml
|
||||
|
||||
- name: Generate release tag
|
||||
id: generate_tag
|
||||
run: |
|
||||
$releaseTag = (Get-Date).ToString('yy.MM.dd')
|
||||
echo "RELEASE_TAG=$releaseTag" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Show generated release tag
|
||||
run: |
|
||||
echo "Generated Release Tag: ${{ env.RELEASE_TAG }}"
|
||||
|
||||
- name: Verify Built Artifacts
|
||||
run: dir 'Virtual Display Driver (HDR)\${{ matrix.platform }}\${{ matrix.configuration }}\MttVDD'
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
@@ -1,183 +0,0 @@
|
||||
#WINDOWS
|
||||
|
||||
import platform
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
import threading
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
import mss
|
||||
import numpy as np
|
||||
import cv2
|
||||
from configparser import ConfigParser
|
||||
from screeninfo import get_monitors
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
from audio_manager import AudioManager
|
||||
from area_selector import AreaSelector
|
||||
from logging_config import setup_logging
|
||||
|
||||
logger = setup_logging()
|
||||
|
||||
class ScreenRecorderApp:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.initialize_ffmpeg()
|
||||
logger.info("THE APP WAS OPEN")
|
||||
|
||||
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||
self.root.title("Display Preview")
|
||||
root.geometry('1280x720')
|
||||
self.config = ConfigParser()
|
||||
self.config_file = 'config.ini'
|
||||
self.load_config()
|
||||
|
||||
self.audio_manager = AudioManager()
|
||||
self.audio_devices = self.audio_manager.audio_devices
|
||||
if len(self.audio_devices) == 0:
|
||||
messagebox.showerror("Error", "No audio devices.")
|
||||
return
|
||||
|
||||
self.monitors = self.get_monitors()
|
||||
if len(self.monitors) == 0:
|
||||
messagebox.showerror("Error", "No monitors found.")
|
||||
return
|
||||
|
||||
self.set_icon()
|
||||
|
||||
self.init_ui()
|
||||
|
||||
self.create_output_folder()
|
||||
self.recording_process = None
|
||||
self.running = False
|
||||
self.elapsed_time = 0
|
||||
self.record_area = None
|
||||
self.area_selector = AreaSelector(root)
|
||||
self.preview_running = False
|
||||
|
||||
# Start preview by default
|
||||
self.preview_running = True
|
||||
threading.Thread(target=self._update_preview_thread, daemon=True).start()
|
||||
|
||||
# Bind resizing event to dynamically adjust preview size
|
||||
self.root.bind("<Configure>", self.resize_preview)
|
||||
|
||||
def set_icon(self):
|
||||
if platform.system() == 'Windows':
|
||||
self.root.iconbitmap('video.ico')
|
||||
elif platform.system() == 'Linux':
|
||||
icon = tk.PhotoImage(file='video.png')
|
||||
self.root.iconphoto(True, icon)
|
||||
|
||||
def load_config(self):
|
||||
if os.path.exists(self.config_file):
|
||||
self.config.read(self.config_file)
|
||||
else:
|
||||
self.config['Settings'] = {'monitor': 0}
|
||||
with open(self.config_file, 'w') as configfile:
|
||||
self.config.write(configfile)
|
||||
|
||||
def init_ui(self):
|
||||
self.monitor_label = ttk.Label(self.root, text="Monitor:")
|
||||
self.monitor_label.grid(row=0, column=0, padx=10, pady=5, sticky="e")
|
||||
self.monitor_combo = ttk.Combobox(self.root, values=[
|
||||
f"Monitor {i+1}: ({monitor.width}x{monitor.height})"
|
||||
for i, monitor in enumerate(self.monitors)
|
||||
], width=25)
|
||||
self.monitor_combo.grid(row=0, column=1, padx=10, pady=5, sticky="w")
|
||||
self.monitor_combo.current(0)
|
||||
self.monitor_combo.config(state="readonly")
|
||||
|
||||
self.preview_frame = ttk.Frame(self.root)
|
||||
self.preview_frame.grid(row=1, column=0, columnspan=2, pady=5, padx=10, sticky="nsew")
|
||||
self.preview_label = ttk.Label(self.preview_frame)
|
||||
self.preview_label.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# Configure resizing behavior
|
||||
self.root.grid_rowconfigure(1, weight=1)
|
||||
self.root.grid_columnconfigure(1, weight=1)
|
||||
|
||||
def _update_preview_thread(self):
|
||||
with mss.mss() as sct:
|
||||
while self.preview_running:
|
||||
try:
|
||||
monitor_index = self.monitor_combo.current()
|
||||
if monitor_index < len(sct.monitors) - 1:
|
||||
monitor = sct.monitors[monitor_index + 1]
|
||||
screenshot = np.array(sct.grab(monitor))
|
||||
screenshot = cv2.cvtColor(screenshot, cv2.COLOR_RGBA2RGB)
|
||||
screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2RGB)
|
||||
|
||||
# Get current frame size
|
||||
frame_width = self.preview_frame.winfo_width()
|
||||
frame_height = self.preview_frame.winfo_height()
|
||||
|
||||
if frame_width > 0 and frame_height > 0:
|
||||
# Calculate aspect-ratio-preserving dimensions
|
||||
height, width, _ = screenshot.shape
|
||||
scale = min(frame_width / width, frame_height / height)
|
||||
new_width = int(width * scale)
|
||||
new_height = int(height * scale)
|
||||
|
||||
# Resize screenshot while preserving aspect ratio
|
||||
screenshot = cv2.resize(screenshot, (new_width, new_height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
tk_image = ImageTk.PhotoImage(image=Image.fromarray(screenshot))
|
||||
self.root.after(0, self._update_preview_label, tk_image)
|
||||
time.sleep(0.03)
|
||||
except tk.TclError:
|
||||
break
|
||||
|
||||
|
||||
def _update_preview_label(self, tk_image):
|
||||
if self.preview_running:
|
||||
self.preview_label.config(image=tk_image)
|
||||
self.preview_label.image = tk_image
|
||||
|
||||
def resize_preview(self, event):
|
||||
# Trigger a preview update on window resize
|
||||
if self.preview_running:
|
||||
self.preview_label.update_idletasks()
|
||||
|
||||
def close_preview(self):
|
||||
self.preview_running = False
|
||||
self.preview_label.config(image='')
|
||||
self.preview_label.image = None
|
||||
|
||||
def on_closing(self):
|
||||
self.close_preview()
|
||||
self.root.quit()
|
||||
self.root.destroy()
|
||||
|
||||
def create_output_folder(self):
|
||||
self.output_folder = os.path.join(os.getcwd(), "OutputFiles")
|
||||
os.makedirs(self.output_folder, exist_ok=True)
|
||||
|
||||
def get_monitors(self):
|
||||
return get_monitors()
|
||||
|
||||
def initialize_ffmpeg(self):
|
||||
ffmpeg_path = self.get_ffmpeg_path()
|
||||
if not os.path.exists(ffmpeg_path):
|
||||
logger.error("FFmpeg not found.")
|
||||
messagebox.showerror("Error", "FFmpeg not found.")
|
||||
sys.exit(1)
|
||||
logger.info("FFmpeg was found.")
|
||||
|
||||
def get_ffmpeg_path(self):
|
||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||
if platform.system() == 'Windows':
|
||||
return os.path.join(base_path, 'ffmpeg_files', 'ffmpeg.exe')
|
||||
return os.path.join(base_path, 'ffmpeg_files', 'ffmpeg')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
root = tk.Tk()
|
||||
app = ScreenRecorderApp(root)
|
||||
root.mainloop()
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred: {e}")
|
||||
messagebox.showerror("Error", f"An unexpected error occurred: {e}")
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['DisplayPreview.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name='DisplayPreview',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='DisplayPreview',
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
This script is based on a slimmed/stripped down version of LexTrack's MiniScreenRecorded.
|
||||
|
||||
https://github.com/lextrack/MiniScreenRecorder
|
||||
|
||||
|
||||
To run as Python, you'll need the following dependencies:
|
||||
|
||||
pip install pillow mss numpy opencv-python screeninfo
|
||||
|
||||
|
||||
These are automatically included with the build installer.
|
||||
|
||||
Executable built using PyInstaller.
|
||||
@@ -1,81 +0,0 @@
|
||||
import tkinter as tk
|
||||
from tkinter import font
|
||||
from PIL import ImageGrab, ImageTk
|
||||
|
||||
class AreaSelector:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.record_area = None
|
||||
self.rect = None
|
||||
self.guide_lines = []
|
||||
self.background_image = None
|
||||
|
||||
def select_area(self, callback):
|
||||
self.callback = callback
|
||||
self.root.withdraw()
|
||||
|
||||
screenshot = ImageGrab.grab()
|
||||
|
||||
self.selection_window = tk.Toplevel(self.root)
|
||||
self.selection_window.attributes('-fullscreen', True)
|
||||
self.selection_window.attributes('-alpha', 0.3)
|
||||
|
||||
self.canvas = tk.Canvas(self.selection_window, cursor="cross")
|
||||
self.canvas.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
self.background_image = ImageTk.PhotoImage(screenshot)
|
||||
self.canvas.create_image(0, 0, image=self.background_image, anchor=tk.NW)
|
||||
|
||||
self.canvas.bind('<ButtonPress-1>', self.on_button_press)
|
||||
self.canvas.bind('<B1-Motion>', self.on_mouse_drag)
|
||||
self.canvas.bind('<ButtonRelease-1>', self.on_button_release)
|
||||
self.selection_window.bind('<Escape>', self.cancel_selection)
|
||||
|
||||
self.coord_font = font.Font(size=16)
|
||||
self.coord_label = tk.Label(self.selection_window, text="", bg='black', fg='white', font=self.coord_font)
|
||||
self.coord_label.place(x=10, y=10)
|
||||
|
||||
def on_button_press(self, event):
|
||||
self.start_x = event.x
|
||||
self.start_y = event.y
|
||||
self.rect = None
|
||||
|
||||
def on_mouse_drag(self, event):
|
||||
if self.rect:
|
||||
self.canvas.delete(self.rect)
|
||||
for line in self.guide_lines:
|
||||
self.canvas.delete(line)
|
||||
|
||||
self.rect = self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y, outline='red', width=4)
|
||||
|
||||
self.guide_lines = [
|
||||
self.canvas.create_line(event.x, 0, event.x, self.canvas.winfo_height(), fill='blue', width=4, dash=(4, 4)),
|
||||
self.canvas.create_line(0, event.y, self.canvas.winfo_width(), event.y, fill='blue', width=4, dash=(4, 4))
|
||||
]
|
||||
|
||||
width = abs(event.x - self.start_x)
|
||||
height = abs(event.y - self.start_y)
|
||||
self.coord_label.config(text=f"Size: {width}x{height} - Position: ({min(self.start_x, event.x)}, {min(self.start_y, event.y)})")
|
||||
|
||||
def on_button_release(self, event):
|
||||
end_x, end_y = event.x, event.y
|
||||
if self.start_x != end_x and self.start_y != end_y:
|
||||
x1, y1 = min(self.start_x, end_x), min(self.start_y, end_y)
|
||||
x2, y2 = max(self.start_x, end_x), max(self.start_y, end_y)
|
||||
self.record_area = (x1, y1, x2, y2)
|
||||
else:
|
||||
self.record_area = None
|
||||
self.cleanup_and_close()
|
||||
|
||||
def cancel_selection(self, event):
|
||||
self.record_area = None
|
||||
self.cleanup_and_close()
|
||||
|
||||
def cleanup_and_close(self):
|
||||
if self.rect:
|
||||
self.canvas.delete(self.rect)
|
||||
for line in self.guide_lines:
|
||||
self.canvas.delete(line)
|
||||
self.selection_window.destroy()
|
||||
self.root.deiconify()
|
||||
self.callback(self.record_area)
|
||||
@@ -1,89 +0,0 @@
|
||||
#Windows
|
||||
|
||||
import locale
|
||||
import platform
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
from tkinter import messagebox
|
||||
from venv import logger
|
||||
|
||||
class AudioManager:
|
||||
def __init__(self):
|
||||
self.audio_devices = self.get_audio_devices()
|
||||
|
||||
def get_audio_devices(self):
|
||||
if platform.system() == 'Windows':
|
||||
return self._get_windows_audio_devices()
|
||||
elif platform.system() == 'Linux':
|
||||
return self._get_linux_audio_devices()
|
||||
else:
|
||||
return []
|
||||
|
||||
def _get_windows_audio_devices(self):
|
||||
ffmpeg_path = self._get_ffmpeg_path()
|
||||
if not ffmpeg_path:
|
||||
return []
|
||||
|
||||
cmd = [ffmpeg_path, "-list_devices", "true", "-f", "dshow", "-i", "dummy"]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True, encoding='utf-8', errors='replace')
|
||||
lines = result.stderr.splitlines()
|
||||
devices = []
|
||||
|
||||
for line in lines:
|
||||
if "audio" in line and len(line.split("\"")) > 1:
|
||||
device_name = line.split("\"")[1]
|
||||
normalized_name = self._normalize_audio_device_name(device_name)
|
||||
devices.append(normalized_name)
|
||||
|
||||
if not devices:
|
||||
logger.error("No active audio devices were found. Please check your audio settings.")
|
||||
messagebox.showerror("Error", "No active audio devices were found. Please check your audio settings.")
|
||||
|
||||
return devices
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running FFmpeg (Audio): {e}")
|
||||
return []
|
||||
except FileNotFoundError:
|
||||
print(f"FFmpeg (Audio) not found at {ffmpeg_path}")
|
||||
return []
|
||||
|
||||
def _normalize_audio_device_name(self, audio_device):
|
||||
system_locale = locale.getdefaultlocale()[0]
|
||||
|
||||
encodings_to_try = ['utf-8', 'latin-1', 'cp1252']
|
||||
|
||||
for encoding in encodings_to_try:
|
||||
try:
|
||||
audio_device = audio_device.encode(encoding).decode('utf-8')
|
||||
break
|
||||
except (UnicodeEncodeError, UnicodeDecodeError):
|
||||
continue
|
||||
|
||||
return audio_device
|
||||
|
||||
def _get_linux_audio_devices(self):
|
||||
cmd = ["pactl", "list", "sources"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace')
|
||||
lines = result.stdout.splitlines()
|
||||
devices = [line.split()[1] for line in lines if "Name:" in line and len(line.split()) > 1]
|
||||
return devices
|
||||
|
||||
def _get_ffmpeg_path(self):
|
||||
if getattr(sys, 'frozen', False):
|
||||
base_path = sys._MEIPASS
|
||||
else:
|
||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
ffmpeg_path = os.path.join(base_path, 'ffmpeg_files', 'ffmpeg.exe')
|
||||
else: # Linux
|
||||
ffmpeg_path = os.path.join(base_path, 'ffmpeg_files', 'ffmpeg')
|
||||
|
||||
return ffmpeg_path if os.path.exists(ffmpeg_path) else None
|
||||
|
||||
|
||||
def refresh_devices(self):
|
||||
self.audio_devices = self.get_audio_devices()
|
||||
@@ -1,10 +0,0 @@
|
||||
[Settings]
|
||||
language = en-US
|
||||
theme = light
|
||||
monitor = 3
|
||||
fps = 1
|
||||
bitrate = 0
|
||||
codec = 0
|
||||
format = 0
|
||||
audio = 0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,20 +0,0 @@
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
def setup_logging():
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
handler = RotatingFileHandler('app.log', maxBytes=5*1024*1024, backupCount=5)
|
||||
handler.setLevel(logging.DEBUG)
|
||||
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
logger.addHandler(handler)
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
return logger
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
@@ -8,7 +8,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
$device = get-pnpdevice -class Display -FriendlyName 'IddSampleDriver Device HDR' -ErrorAction SilentlyContinue
|
||||
$device = Get-PnpDevice -Class Display -ErrorAction SilentlyContinue | Where-Object { $_.FriendlyName -eq 'IddSampleDriver Device HDR' -or $_.FriendlyName -eq 'Virtual Display Driver' }
|
||||
|
||||
if ($device) {
|
||||
if ($device.Status -eq 'OK') {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Virtual Display
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,112 +1,84 @@
|
||||
# Virtual Display Driver
|
||||
Based on Microsoft Indirect Display Driver Sample. This creates a virtual display in Windows that acts and functions just like a real one. It's useful for streaming, virtual reality applications, recording, headless servers, etc. The benefit over a physical display is the ability to adjust resolutions and refresh rates beyond the physical displays capabilities. For example, this would enable the ability to stream a game from your home PC using game streaming software at 240hz at 8K while owning a 60hz 1080p monitor (unrealistic, but explains the abilities well). For servers without displays, this enabled remote desktop and screen streaming to other systems as if there were a display installed.
|
||||
▶️▶️▶️# Virtual Display Driver
|
||||
This project creates a _virtual display_ in Windows that functions just like a physical monitor. It is particularly useful for applications such as **streaming, virtual reality, screen recording,** and **headless servers—systems** that operate without a physical display attached.
|
||||
|
||||
Supports emulating resolutions from **640 x 480** to **7680 x 4320 (8K)**, and refresh rates including **60hz, 75hz, 90hz, 120hz, 144hz, 165hz, 240hz, 480hz,** and **500hz.**
|
||||
Unlike physical monitors, this virtual display can support resolutions and refresh rates that go beyond standard hardware limitations, offering greater flexibility for advanced setups. Furthermore, custom EDIDs can be used to simulate/emulate existing hardware displays.
|
||||
|
||||
This project uses the official Windows Indirect Display Driver combined with the IddCx class extension driver.
|
||||
## Download Latest Version
|
||||
|
||||
## Download Stable Version
|
||||
- [Driver Installer (Windows 10/11)](https://github.com/VirtualDisplay/Virtual-Display-Driver/releases) - Check release page for release notes.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Please make sure you download the correct version for your operating system!
|
||||
## EDID Database
|
||||
- [EDID Database by Bud3699](https://edid.mikethetech.com/)
|
||||
|
||||
- [Windows 10 and 11 (no HDR)](https://github.com/itsmikethetech/Virtual-Display-Driver/releases/tag/23.10.20.2)
|
||||
- [Windows 11 23H2+ (HDR)](https://github.com/itsmikethetech/Virtual-Display-Driver/releases/tag/23.12.2HDR)
|
||||
You can use this database to load custom edid's into the driver! Or just general edid usage :)
|
||||
|
||||
## Download Beta
|
||||
- [Universal Driver - 24.10.27 (Windows 10/11)](https://github.com/itsmikethetech/Virtual-Display-Driver/releases/tag/24.10.27) - Added more plus optimisations
|
||||
|
||||
[Edid database by bud (beta only - for custom edid) ](https://edid.mikethetech.com/)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Release Instructions
|
||||
- Step 1: Download the Installer
|
||||
- You can download the insaller directly from the [Releases](https://github.com/VirtualDisplay/Virtual-Display-Driver/releases) page.
|
||||
|
||||
1. Download the latest version from the above or the website, and extract the contents to a folder.
|
||||
2. Copy the `\IddSampleDriver\` folder and its contents to `C:\IddSampleDriver\` before installing the driver **(important!)**.
|
||||
3. Right click and run the *.bat file **as an Administrator** to add the driver certificate as a trusted root certificate.
|
||||
4. Don't install the inf. Open device manager, click on any device, then click on the "Action" menu and click "Add Legacy Hardware".
|
||||
5. Select "Add hardware from a list (Advanced)" and then select Display adapters.
|
||||
6. Click "Have Disk..." and click the "Browse..." button. Navigate to the extracted files and select the inf file.
|
||||
7. You are done! Go to display settings to customize the resolution of the additional displays. These displays show up in Sunshine, your Oculus or VR settings, and should be able to be streamed from.
|
||||
8. You can enable/disable the display adapter to toggle the monitors.
|
||||
- Step 2: Run the Installer
|
||||
- Download and run the installer.
|
||||
- Follow the on-screen instructions to complete the installation.
|
||||
|
||||
**Ps.** Make sure that `options.txt` is accessible for the system at `C:\IddSampleDriver\options.txt` or the installation will fail.
|
||||
- Step 3: Verify the Installation (Optional)
|
||||
- Check if the Virtual Display Driver is correctly installed by running the following:
|
||||
- **Device Manager:** Check "Device Manager" under "Display Adapters."
|
||||
- **Settings:** Check display settings under system settings and see if the virtual displays show.
|
||||
|
||||
---
|
||||
Manual installation can be found in the wiki
|
||||
|
||||
### Beta Release Instructions
|
||||
## 🤔 Comparison with other IDDs
|
||||
|
||||
1. Download the beta version and extract the contents to a folder.
|
||||
2. Copy the `\VirtualDisplayDriver\` folder and its contents to `C:\VirtualDisplayDriver\` before installing the driver **(important!)**.
|
||||
3. Right click and run the *.bat file **as an Administrator** to add the driver certificate as a trusted root certificate.
|
||||
4. Don't install the inf. Open device manager, click on any device, then click on the "Action" menu and click "Add Legacy Hardware".
|
||||
5. Select "Add hardware from a list (Advanced)" and then select Display adapters.
|
||||
6. Click "Have Disk..." and click the "Browse..." button. Navigate to the extracted files and select the inf file.
|
||||
7. You are done! Go to display settings to customize the resolution of the additional displays. These displays show up in Sunshine, your Oculus or VR settings, and should be able to be streamed from.
|
||||
8. You can enable/disable the display adapter to toggle the monitors.
|
||||
The table below shows a comparison with other popular Indirect Display Driver
|
||||
projects.
|
||||
|
||||

|
||||
|
||||
## Easy Uninstall
|
||||
¹ ARM64 Support in Windows 11 24H2 or later may require test signing be enabled.
|
||||
|
||||
1. Open device manager
|
||||
2. Locate Display Adapters
|
||||
3. Right click on IddSampleDriver, choose "Uninstall device"
|
||||
4. There is a new popup window, in there click Attempt to remove driver for this device.
|
||||
## HDR Support Now Available for Windows 11 23H2+
|
||||
|
||||
## Manual/Forced Uninstall
|
||||
### Installation Video
|
||||
|
||||
Next instructions are for those cases where the device is removed from the system, but driver stil remains. This happens when there is a connection to the device while trying to remove the drivers. To
|
||||
remedy this, there is a a few tricks built into windows. So here goes:
|
||||
[](https://youtu.be/Oz_cfbfUx0E)
|
||||
|
||||
1. Open up a powershell terminal and input this:
|
||||
2. ```pnputil /enum-drivers```
|
||||
3. Locate iddsampledriver.inf, there might be multiple pages of text. Make a note of the "published name", it's often unique for your system, but might look like "oem139.inf"
|
||||
4. ```pnputil /delete-driver oem139.inf```
|
||||
5. (If you still get multiple displays after uninstall, try to repeat uninstall procedure in safemode.)
|
||||
## More Videos and Resources
|
||||
- 24.12.24 (Stable): MikeTheTech: [How to install the New Virtual Display Driver](https://youtu.be/Oz_cfbfUx0E)
|
||||
- 24.12.24 (Stable): MikeTheTech: [How to manually install the New Virtual Display Driver](https://youtu.be/sM9rNJWssAI)
|
||||
- 24.12.24 (Stable): Bud3699: [How to configure the VDD using the new Companion App](https://youtu.be/p_gfjE_cwjk)
|
||||
- 24.10.27 (Beta): [MikeTheTech: How to install a virtual display](https://youtu.be/byfBWDnToYk "How to install a virtual display")
|
||||
|
||||
## HDR Support Now Available for Windows 11 22H2+
|
||||

|
||||
|
||||
### Videos
|
||||
## 🤝 Sponsors
|
||||
|
||||
[](https://youtu.be/nNWpbRUPkn4 "How to install a virtual display")
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://github.com/user-attachments/assets/ca93d971-67dc-41dd-b945-ab4f372ea72a" /></td>
|
||||
<td>Free code signing on Windows provided by <a href="https://signpath.io">SignPath.io</a>, certificate by <a href="https://signpath.org">SignPath Foundation</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
[Previous Video: How to install a virtual display](https://youtu.be/byfBWDnToYk "How to install a virtual display")
|
||||
## Developers
|
||||
|
||||
### Screenshots:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## License
|
||||
|
||||
MIT and CC0 or Public Domain (for changes I made, please consult Microsoft for their license), choose the least restrictive option.
|
||||
|
||||
## Disclaimer:
|
||||
|
||||
This software is provided "AS IS" with NO IMPLICIT OR EXPLICIT warranty. It's worth noting that while this software functioned without issues on my system, there is no guarantee that it will not impact your computer. It operates in User Mode, which reduces the likelihood of causing system instability, such as the Blue Screen of Death. However, exercise caution when using this software.
|
||||
- Shoutout to **[MikeTheTech](https://github.com/itsmikethetech)** Project Boss man, owner and programmer!
|
||||
- Shoutout to **[Bud](https://github.com/bud3699)** For a ton of features, companion & installer work
|
||||
- Shoutout to **[zjoasan](https://github.com/zjoasan)** For scripts and part of installer
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Shoutout to **[Bud](https://github.com/bud3699)** and **[zjoasan](https://github.com/zjoasan)** for jumping on the team and helping with not just support, but lots of great new features!
|
||||
|
||||
Shoutout to **[Roshkins](https://github.com/roshkins/IddSampleDriver)** for the original repo.
|
||||
|
||||
Shoutout to **[Baloukj](https://github.com/baloukj/IddSampleDriver)** for the 8-bit / 10-bit support. (Also, first to push the new Microsoft Driver public!)
|
||||
|
||||
Shoutout to **[Anakngtokwa](https://github.com/Anakngtokwa)** for assisting with finding driver sources.
|
||||
|
||||
**[Microsoft](https://github.com/microsoft/Windows-driver-samples/tree/master/video/IndirectDisplay)** Indirect Display Driver/Sample (Driver code)
|
||||
|
||||
Thanks to **[AKATrevorJay](https://github.com/akatrevorjay/edid-generator)** for the hi-res EDID.
|
||||
|
||||
Shoutout to **[LexTrack](https://github.com/lextrack/)** for the MiniScreenRecorder script.
|
||||
- Shoutout to **[Roshkins](https://github.com/roshkins/IddSampleDriver)** for the original repo.
|
||||
- Shoutout to **[Baloukj](https://github.com/baloukj/IddSampleDriver)** for the 8-bit / 10-bit support. (Also, first to push the new Microsoft Driver public!)
|
||||
- Shoutout to **[Anakngtokwa](https://github.com/Anakngtokwa)** for assisting with finding driver sources.
|
||||
- **[Microsoft](https://github.com/microsoft/Windows-driver-samples/tree/master/video/IndirectDisplay)** Indirect Display Driver/Sample (Driver code)
|
||||
- Thanks to **[AKATrevorJay](https://github.com/akatrevorjay/edid-generator)** for the hi-res EDID.
|
||||
- Shoutout to **[LexTrack](https://github.com/lextrack/)** for the MiniScreenRecorder script.
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#itsmikethetech/Virtual-Display-Driver&Date)
|
||||
[](https://star-history.com/#VirtualDisplay/Virtual-Display-Driver&Date)
|
||||
|
||||
## Disclaimer:
|
||||
|
||||
This software is provided "AS IS" with NO IMPLICIT OR EXPLICIT warranty. It's worth noting that while this software functioned without issues on our systems, there is no guarantee that it will not impact your computer. It operates in User Mode(Session0), which reduces the likelihood of causing system instability, such as the Blue Screen of Death. However, exercise caution when using this software.
|
||||
@@ -38,6 +38,7 @@ Environment:
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
||||
|
||||
@@ -332,6 +333,9 @@ void vddlog(const char* type, const char* message) {
|
||||
case 't':
|
||||
logType = "TESTING";
|
||||
break;
|
||||
case 'c':
|
||||
logType = "COMPANION";
|
||||
break;
|
||||
default:
|
||||
logType = "UNKNOWN";
|
||||
break;
|
||||
@@ -783,6 +787,16 @@ bool UpdateXmlDisplayCountSetting(int displayCount) {
|
||||
}
|
||||
|
||||
|
||||
LUID getSetAdapterLuid() {
|
||||
AdapterOption& adapterOption = Options.Adapter;
|
||||
|
||||
if (!adapterOption.hasTargetAdapter) {
|
||||
vddlog("e","No Gpu Found/Selected");
|
||||
}
|
||||
|
||||
return adapterOption.adapterLuid;
|
||||
}
|
||||
|
||||
|
||||
void GetGpuInfo()
|
||||
{
|
||||
@@ -793,20 +807,55 @@ void GetGpuInfo()
|
||||
return;
|
||||
}
|
||||
|
||||
string utf8_desc;
|
||||
try {
|
||||
utf8_desc = WStringToString(adapterOption.target_name);
|
||||
string utf8_desc = WStringToString(adapterOption.target_name);
|
||||
LUID luid = getSetAdapterLuid();
|
||||
string logtext = "ASSIGNED GPU: " + utf8_desc +
|
||||
" (LUID: " + std::to_string(luid.LowPart) + "-" + std::to_string(luid.HighPart) + ")";
|
||||
vddlog("i", logtext.c_str());
|
||||
}
|
||||
catch (const exception& e) {
|
||||
vddlog("e", ("Conversion error: " + string(e.what())).c_str());
|
||||
vddlog("e", ("Error: " + string(e.what())).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void logAvailableGPUs() {
|
||||
vector<GPUInfo> gpus;
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
if (!SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
string logtext = "ASSIGNED GPU: " + utf8_desc;
|
||||
vddlog("i", logtext.c_str());
|
||||
for (UINT i = 0;; i++) {
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
if (!SUCCEEDED(factory->EnumAdapters(i, &adapter))) {
|
||||
break;
|
||||
}
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
if (!SUCCEEDED(adapter->GetDesc(&desc))) {
|
||||
continue;
|
||||
}
|
||||
GPUInfo info{ desc.Description, adapter, desc };
|
||||
gpus.push_back(info);
|
||||
}
|
||||
for (const auto& gpu : gpus) {
|
||||
wstring logMessage = L"GPU Name: ";
|
||||
logMessage += gpu.desc.Description;
|
||||
wstring memorySize = L" Memory: ";
|
||||
memorySize += std::to_wstring(gpu.desc.DedicatedVideoMemory / (1024 * 1024)) + L" MB";
|
||||
wstring logText = logMessage + memorySize;
|
||||
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, logText.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (bufferSize > 0) {
|
||||
std::string logTextA(bufferSize - 1, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, 0, logText.c_str(), -1, &logTextA[0], bufferSize, nullptr, nullptr);
|
||||
vddlog("c", logTextA.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ReloadDriver(HANDLE hPipe) {
|
||||
auto* pContext = WdfObjectGet_IndirectDeviceContextWrapper(hPipe);
|
||||
if (pContext && pContext->pContext) {
|
||||
@@ -830,7 +879,7 @@ void HandleClient(HANDLE hPipe) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, bufferwstr.c_str(), -1, &bufferstr[0], bufferSize, nullptr, nullptr);
|
||||
vddlog("p", bufferstr.c_str());
|
||||
if (wcsncmp(buffer, L"RELOAD_DRIVER", 13) == 0) {
|
||||
vddlog("i", "Reloading the driver");
|
||||
vddlog("c", "Reloading the driver");
|
||||
ReloadDriver(hPipe);
|
||||
|
||||
}
|
||||
@@ -839,13 +888,13 @@ void HandleClient(HANDLE hPipe) {
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"debuglogging");
|
||||
debugLogs = true;
|
||||
vddlog("i", "Pipe debugging enabled");
|
||||
vddlog("c", "Pipe debugging enabled");
|
||||
vddlog("d", "Debug Logs Enabled");
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"debuglogging");
|
||||
debugLogs = false;
|
||||
vddlog("i", "Debugging disabled");
|
||||
vddlog("c", "Debugging disabled");
|
||||
}
|
||||
}
|
||||
else if (wcsncmp(buffer, L"LOGGING", 7) == 0) {
|
||||
@@ -853,24 +902,24 @@ void HandleClient(HANDLE hPipe) {
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"logging");
|
||||
logsEnabled = true;
|
||||
vddlog("i", "Logging Enabled");
|
||||
vddlog("c", "Logging Enabled");
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"logging");
|
||||
logsEnabled = false;
|
||||
vddlog("i", "Logging disabled"); // We can keep this here just to make it delete the logs on disable
|
||||
vddlog("c", "Logging disabled"); // We can keep this here just to make it delete the logs on disable
|
||||
}
|
||||
}
|
||||
else if (wcsncmp(buffer, L"HDRPLUS", 7) == 0) {
|
||||
wchar_t* param = buffer + 8;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"HDRPlus");
|
||||
vddlog("i", "HDR+ Enabled");
|
||||
vddlog("c", "HDR+ Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"HDRPlus");
|
||||
vddlog("i", "HDR+ Disabled");
|
||||
vddlog("c", "HDR+ Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
@@ -878,12 +927,12 @@ void HandleClient(HANDLE hPipe) {
|
||||
wchar_t* param = buffer + 6;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"SDR10bit");
|
||||
vddlog("i", "SDR 10 Bit Enabled");
|
||||
vddlog("c", "SDR 10 Bit Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"SDR10bit");
|
||||
vddlog("i", "SDR 10 Bit Disabled");
|
||||
vddlog("c", "SDR 10 Bit Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
@@ -891,12 +940,12 @@ void HandleClient(HANDLE hPipe) {
|
||||
wchar_t* param = buffer + 11;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"CustomEdid");
|
||||
vddlog("i", "Custom Edid Enabled");
|
||||
vddlog("c", "Custom Edid Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"CustomEdid");
|
||||
vddlog("i", "Custom Edid Disabled");
|
||||
vddlog("c", "Custom Edid Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
@@ -904,12 +953,12 @@ void HandleClient(HANDLE hPipe) {
|
||||
wchar_t* param = buffer + 13;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"PreventSpoof");
|
||||
vddlog("i", "Prevent Spoof Enabled");
|
||||
vddlog("c", "Prevent Spoof Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"PreventSpoof");
|
||||
vddlog("i", "Prevent Spoof Disabled");
|
||||
vddlog("c", "Prevent Spoof Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
@@ -917,12 +966,12 @@ void HandleClient(HANDLE hPipe) {
|
||||
wchar_t* param = buffer + 12;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"EdidCeaOverride");
|
||||
vddlog("i", "Cea override Enabled");
|
||||
vddlog("c", "Cea override Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"EdidCeaOverride");
|
||||
vddlog("i", "Cea override Disabled");
|
||||
vddlog("c", "Cea override Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
@@ -930,29 +979,35 @@ void HandleClient(HANDLE hPipe) {
|
||||
wchar_t* param = buffer + 15;
|
||||
if (wcsncmp(param, L"true", 4) == 0) {
|
||||
UpdateXmlToggleSetting(true, L"HardwareCursor");
|
||||
vddlog("i", "Hardware Cursor Enabled");
|
||||
vddlog("c", "Hardware Cursor Enabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
else if (wcsncmp(param, L"false", 5) == 0) {
|
||||
UpdateXmlToggleSetting(false, L"HardwareCursor");
|
||||
vddlog("i", "Hardware Cursor Disabled");
|
||||
vddlog("c", "Hardware Cursor Disabled");
|
||||
ReloadDriver(hPipe);
|
||||
}
|
||||
}
|
||||
else if (wcsncmp(buffer, L"D3DDEVICEGPU", 12) == 0) {
|
||||
vddlog("i", "Retrieving D3D GPU (This information may be inaccurate without reloading the driver first)");
|
||||
vddlog("c", "Retrieving D3D GPU (This information may be inaccurate without reloading the driver first)");
|
||||
InitializeD3DDeviceAndLogGPU();
|
||||
vddlog("i", "Rerieved D3D GPU");
|
||||
vddlog("c", "Retrieved D3D GPU");
|
||||
}
|
||||
else if (wcsncmp(buffer, L"IDDCXVERSION", 12) == 0) {
|
||||
vddlog("i", "Logging iddcx version");
|
||||
vddlog("c", "Logging iddcx version");
|
||||
LogIddCxVersion();
|
||||
}
|
||||
else if (wcsncmp(buffer, L"GETASSIGNEDGPU", 14) == 0) {
|
||||
vddlog("i", "Retrieving Assigned GPU");
|
||||
vddlog("c", "Retrieving Assigned GPU");
|
||||
GetGpuInfo();
|
||||
vddlog("i", "Rerieved Assigned GPU");
|
||||
}
|
||||
vddlog("c", "Retrieved Assigned GPU");
|
||||
}
|
||||
else if (wcsncmp(buffer, L"GETALLGPUS", 10) == 0) {
|
||||
vddlog("c", "Logging all GPUs");
|
||||
vddlog("i", "Any GPUs which show twice but you only have one, will most likely be the GPU the driver is attached to");
|
||||
logAvailableGPUs();
|
||||
vddlog("c", "Logged all GPUs");
|
||||
}
|
||||
else if (wcsncmp(buffer, L"SETGPU", 6) == 0) {
|
||||
std::wstring gpuName = buffer + 7;
|
||||
gpuName = gpuName.substr(1, gpuName.size() - 2);
|
||||
@@ -961,9 +1016,9 @@ void HandleClient(HANDLE hPipe) {
|
||||
std::string gpuNameNarrow(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, gpuName.c_str(), static_cast<int>(gpuName.length()), &gpuNameNarrow[0], size_needed, nullptr, nullptr);
|
||||
|
||||
vddlog("i", ("Setting GPU to: " + gpuNameNarrow).c_str());
|
||||
vddlog("c", ("Setting GPU to: " + gpuNameNarrow).c_str());
|
||||
if (UpdateXmlGpuSetting(gpuName.c_str())) {
|
||||
vddlog("i", "Gpu Changed, Restarting Driver");
|
||||
vddlog("c", "Gpu Changed, Restarting Driver");
|
||||
}
|
||||
else {
|
||||
vddlog("e", "Failed to update GPU setting in XML. Restarting anyway");
|
||||
@@ -977,10 +1032,10 @@ void HandleClient(HANDLE hPipe) {
|
||||
swscanf_s(buffer + 15, L"%d", &newDisplayCount);
|
||||
|
||||
std::wstring displayLog = L"Setting display count to " + std::to_wstring(newDisplayCount);
|
||||
vddlog("i", WStringToString(displayLog).c_str());
|
||||
vddlog("c", WStringToString(displayLog).c_str());
|
||||
|
||||
if (UpdateXmlDisplayCountSetting(newDisplayCount)){
|
||||
vddlog("i", "Display Count Changed, Restarting Driver");
|
||||
vddlog("c", "Display Count Changed, Restarting Driver");
|
||||
}
|
||||
else {
|
||||
vddlog("e", "Failed to update display count setting in XML. Restarting anyway");
|
||||
@@ -1241,6 +1296,8 @@ void loadSettings() {
|
||||
vector<tuple<int, int, int, int>> res;
|
||||
wstring gpuFriendlyName;
|
||||
UINT monitorcount = 1;
|
||||
set<tuple<int, int>> resolutions;
|
||||
vector<int> globalRefreshRates;
|
||||
|
||||
while (S_OK == (hr = pReader->Read(&nodeType))) {
|
||||
switch (nodeType) {
|
||||
@@ -1277,6 +1334,7 @@ void loadSettings() {
|
||||
if (height.empty()) {
|
||||
height = L"600";
|
||||
}
|
||||
resolutions.insert(make_tuple(stoi(width), stoi(height)));
|
||||
}
|
||||
else if (currentElement == L"refresh_rate") {
|
||||
refreshRate = wstring(pwszValue, cwchValue);
|
||||
@@ -1291,10 +1349,57 @@ void loadSettings() {
|
||||
ss << "Added: " << stoi(width) << "x" << stoi(height) << " @ " << vsync_num << "/" << vsync_den << "Hz";
|
||||
vddlog("d", ss.str().c_str());
|
||||
}
|
||||
else if (currentElement == L"g_refresh_rate") {
|
||||
globalRefreshRates.push_back(stoi(wstring(pwszValue, cwchValue)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for res testing, stores each resolution then iterates through each global adding a res for each one
|
||||
*
|
||||
|
||||
for (const auto& resTuple : resolutions) {
|
||||
stringstream ss;
|
||||
ss << get<0>(resTuple) << "x" << get<1>(resTuple);
|
||||
vddlog("t", ss.str().c_str());
|
||||
}
|
||||
|
||||
for (const auto& globalRate : globalRefreshRates) {
|
||||
stringstream ss;
|
||||
ss << globalRate << " Hz";
|
||||
vddlog("t", ss.str().c_str());
|
||||
}
|
||||
*/
|
||||
|
||||
for (int globalRate : globalRefreshRates) {
|
||||
for (const auto& resTuple : resolutions) {
|
||||
int global_width = get<0>(resTuple);
|
||||
int global_height = get<1>(resTuple);
|
||||
|
||||
int vsync_num, vsync_den;
|
||||
float_to_vsync(static_cast<float>(globalRate), vsync_num, vsync_den);
|
||||
res.push_back(make_tuple(global_width, global_height, vsync_num, vsync_den));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* logging all resolutions after added global
|
||||
*
|
||||
for (const auto& tup : res) {
|
||||
stringstream ss;
|
||||
ss << "("
|
||||
<< get<0>(tup) << ", "
|
||||
<< get<1>(tup) << ", "
|
||||
<< get<2>(tup) << ", "
|
||||
<< get<3>(tup) << ")";
|
||||
vddlog("t", ss.str().c_str());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
numVirtualDisplays = monitorcount;
|
||||
gpuname = gpuFriendlyName;
|
||||
monitorModes = res;
|
||||
@@ -1385,10 +1490,10 @@ void loadSettings() {
|
||||
int vsync_num, vsync_den;
|
||||
float_to_vsync(refreshRate, vsync_num, vsync_den);
|
||||
|
||||
stringstream ss;
|
||||
stringstream ss;
|
||||
res.push_back(make_tuple(width, height, vsync_num, vsync_den));
|
||||
|
||||
stringstream ss;
|
||||
|
||||
ss << "Resolution: " << width << "x" << height << " @ " << vsync_num << "/" << vsync_den << "Hz";
|
||||
vddlog("d", ss.str().c_str());
|
||||
}
|
||||
|
||||
@@ -6,56 +6,40 @@
|
||||
<gpu>
|
||||
<friendlyname>default</friendlyname>
|
||||
</gpu>
|
||||
<global>
|
||||
<!--These are global refreshrates, any you add in here, will be replicated to all resolutions-->
|
||||
<g_refresh_rate>60</g_refresh_rate>
|
||||
<g_refresh_rate>90</g_refresh_rate>
|
||||
<g_refresh_rate>120</g_refresh_rate>
|
||||
<g_refresh_rate>144</g_refresh_rate>
|
||||
<g_refresh_rate>165</g_refresh_rate>
|
||||
<g_refresh_rate>244</g_refresh_rate>
|
||||
</global>
|
||||
<resolutions>
|
||||
<resolution>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
<refresh_rate>30</refresh_rate>
|
||||
<refresh_rate>60</refresh_rate>
|
||||
<refresh_rate>90</refresh_rate>
|
||||
<refresh_rate>120</refresh_rate>
|
||||
<refresh_rate>144</refresh_rate>
|
||||
<refresh_rate>165</refresh_rate>
|
||||
</resolution>
|
||||
<resolution>
|
||||
<width>1366</width>
|
||||
<height>768</height>
|
||||
<refresh_rate>30</refresh_rate>
|
||||
<refresh_rate>60</refresh_rate>
|
||||
<refresh_rate>90</refresh_rate>
|
||||
<refresh_rate>120</refresh_rate>
|
||||
<refresh_rate>144</refresh_rate>
|
||||
<refresh_rate>165</refresh_rate>
|
||||
</resolution>
|
||||
<resolution>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<refresh_rate>30</refresh_rate>
|
||||
<refresh_rate>60</refresh_rate>
|
||||
<refresh_rate>90</refresh_rate>
|
||||
<refresh_rate>120</refresh_rate>
|
||||
<refresh_rate>144</refresh_rate>
|
||||
<refresh_rate>165</refresh_rate>
|
||||
</resolution>
|
||||
<resolution>
|
||||
<width>2560</width>
|
||||
<height>1440</height>
|
||||
<refresh_rate>30</refresh_rate>
|
||||
<refresh_rate>60</refresh_rate>
|
||||
<refresh_rate>90</refresh_rate>
|
||||
<refresh_rate>120</refresh_rate>
|
||||
<refresh_rate>144</refresh_rate>
|
||||
<refresh_rate>165</refresh_rate>
|
||||
</resolution>
|
||||
<resolution>
|
||||
<width>3840</width>
|
||||
<height>2160</height>
|
||||
<refresh_rate>30</refresh_rate>
|
||||
<refresh_rate>60</refresh_rate>
|
||||
<refresh_rate>90</refresh_rate>
|
||||
<refresh_rate>120</refresh_rate>
|
||||
<refresh_rate>144</refresh_rate>
|
||||
<refresh_rate>165</refresh_rate>
|
||||
</resolution>
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user