mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-30 04:50:11 +08:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ab13fa582d | ||
|  | b9e8192eee | ||
|  | 5590aaeb1e | ||
|  | adfe14809f | ||
|  | a21dbc8d69 | ||
|  | b9c70f54d3 | ||
|  | 9cd617d078 | 
							
								
								
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | *.h   linguist-language=C++ | ||||||
|  | *.cpp linguist-language=C++ | ||||||
|  | *.lua linguist-language=Xmake | ||||||
							
								
								
									
										2
									
								
								.github/workflows/build.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -140,7 +140,7 @@ jobs: | |||||||
|       matrix: |       matrix: | ||||||
|         include: |         include: | ||||||
|           - arch: x64 |           - arch: x64 | ||||||
|             runner: macos-13 |             runner: macos-15-intel | ||||||
|             cache-key: intel |             cache-key: intel | ||||||
|             out-dir: ./build/macosx/x86_64/release/crossdesk |             out-dir: ./build/macosx/x86_64/release/crossdesk | ||||||
|             package_script: ./scripts/macosx/pkg_x64.sh |             package_script: ./scripts/macosx/pkg_x64.sh | ||||||
|   | |||||||
							
								
								
									
										163
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,8 +1,5 @@ | |||||||
| # CrossDesk | # CrossDesk | ||||||
|  |  | ||||||
| #### 跨界连接,高效如一 |  | ||||||
|  |  | ||||||
| ---- |  | ||||||
| [English](README_EN.md) / [中文](README.md) | [English](README_EN.md) / [中文](README.md) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -72,7 +69,7 @@ xmake r crossdesk | |||||||
| #### 注意 | #### 注意 | ||||||
| 运行时如果客户端状态栏显示 **未连接服务器**,请先在 [CrossDesk 官方网站](https://www.crossdesk.cn/) 安装客户端,以便在环境中安装所需的证书文件。 | 运行时如果客户端状态栏显示 **未连接服务器**,请先在 [CrossDesk 官方网站](https://www.crossdesk.cn/) 安装客户端,以便在环境中安装所需的证书文件。 | ||||||
|  |  | ||||||
| <img width="129" height="60" alt="image" src="https://github.com/user-attachments/assets/1812f7d6-516b-4b4f-8a3d-98bee505cc5a" /> | <img width="256" height="120" alt="image" src="https://github.com/user-attachments/assets/1812f7d6-516b-4b4f-8a3d-98bee505cc5a" /> | ||||||
|  |  | ||||||
| ## 关于 Xmake | ## 关于 Xmake | ||||||
|  |  | ||||||
| @@ -110,3 +107,161 @@ xmake b -vy crossdesk | |||||||
| xmake r -d crossdesk | xmake r -d crossdesk | ||||||
| ``` | ``` | ||||||
| 更多使用方法可参考 [Xmake官方文档](https://xmake.io/guide/quick-start.html) 。 | 更多使用方法可参考 [Xmake官方文档](https://xmake.io/guide/quick-start.html) 。 | ||||||
|  |  | ||||||
|  | ## 自托管服务器 | ||||||
|  | 推荐使用Docker部署CrossDesk Server。 | ||||||
|  | ``` | ||||||
|  | sudo docker run -d \ | ||||||
|  |   --name crossdesk_server \ | ||||||
|  |   --network host \ | ||||||
|  |   -e EXTERNAL_IP=xxx.xxx.xxx.xxx \ | ||||||
|  |   -e INTERNAL_IP=xxx.xxx.xxx.xxx \ | ||||||
|  |   -e CROSSDESK_SERVER_PORT=9099 \ | ||||||
|  |   -v /path/to/your/certs:/crossdesk-server/certs \ | ||||||
|  |   -v /path/to/your/db:/crossdesk-server/db \ | ||||||
|  |   -v /path/to/your/logs:/crossdesk-server/logs \ | ||||||
|  |   crossdesk/crossdesk-server:latest | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 上述命令中,用户需注意的参数如下: | ||||||
|  |  | ||||||
|  | - EXTERNAL_IP:服务器公网 IP , 对应 CrossDesk 客户端**自托管服务器配置**中填写的**服务器地址** | ||||||
|  |  | ||||||
|  | - INTERNAL_IP:服务器内网 IP | ||||||
|  |  | ||||||
|  | - CROSSDESK_SERVER_PORT:自托管服务使用的端口,对应 CrossDesk 客户端**自托管服务器配置**中填写的**服务器端口** | ||||||
|  |  | ||||||
|  | - /path/to/your/certs:证书文件目录 | ||||||
|  |  | ||||||
|  | - /path/to/your/db:CrossDesk Server 设备管理数据库 | ||||||
|  |  | ||||||
|  | - /path/to/your/logs:日志目录 | ||||||
|  |  | ||||||
|  | **注意**: | ||||||
|  | - **/path/to/your/ 是示例路径,请替换为你自己的实际路径。挂载的目录必须事先创建好,否则容器会报错。** | ||||||
|  | - **服务器需开放端口:3478/udp,3478/tcp,30000-60000/udp,CROSSDESK_SERVER_PORT/tcp,443/tcp。** | ||||||
|  |  | ||||||
|  | ## 证书文件 | ||||||
|  | 客户端需加载根证书文件,服务端需加载服务器私钥和服务器证书文件。 | ||||||
|  |  | ||||||
|  | 如果已有SSL证书的用户,可以忽略下面的证书生成步骤。 | ||||||
|  |  | ||||||
|  | 对于无证书的用户,可使用下面的脚本自行生成证书文件: | ||||||
|  | ``` | ||||||
|  | # 创建证书生成脚本 | ||||||
|  | vim generate_certs.sh | ||||||
|  | ``` | ||||||
|  | 拷贝到脚本中 | ||||||
|  | ``` | ||||||
|  | #!/bin/bash | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | # 检查参数 | ||||||
|  | if [ "$#" -ne 1 ]; then | ||||||
|  |     echo "Usage: $0 <SERVER_IP>" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | SERVER_IP="$1" | ||||||
|  |  | ||||||
|  | # 文件名 | ||||||
|  | ROOT_KEY="crossdesk.cn_root.key" | ||||||
|  | ROOT_CERT="crossdesk.cn_root.crt" | ||||||
|  | SERVER_KEY="crossdesk.cn.key" | ||||||
|  | SERVER_CSR="crossdesk.cn.csr" | ||||||
|  | SERVER_CERT="crossdesk.cn_bundle.crt" | ||||||
|  | FULLCHAIN_CERT="crossdesk.cn_fullchain.crt" | ||||||
|  |  | ||||||
|  | # 证书主题 | ||||||
|  | SUBJ="/C=CN/ST=Zhejiang/L=Hangzhou/O=CrossDesk/OU=CrossDesk/CN=$SERVER_IP" | ||||||
|  |  | ||||||
|  | # 1. 生成根证书 | ||||||
|  | echo "Generating root private key..." | ||||||
|  | openssl genrsa -out "$ROOT_KEY" 4096 | ||||||
|  |  | ||||||
|  | echo "Generating self-signed root certificate..." | ||||||
|  | openssl req -x509 -new -nodes -key "$ROOT_KEY" -sha256 -days 3650 -out "$ROOT_CERT" -subj "$SUBJ" | ||||||
|  |  | ||||||
|  | # 2. 生成服务器私钥 | ||||||
|  | echo "Generating server private key..." | ||||||
|  | openssl genrsa -out "$SERVER_KEY" 2048 | ||||||
|  |  | ||||||
|  | # 3. 生成服务器 CSR | ||||||
|  | echo "Generating server CSR..." | ||||||
|  | openssl req -new -key "$SERVER_KEY" -out "$SERVER_CSR" -subj "$SUBJ" | ||||||
|  |  | ||||||
|  | # 4. 生成临时 OpenSSL 配置文件,加入 SAN | ||||||
|  | SAN_CONF="san.cnf" | ||||||
|  | cat > $SAN_CONF <<EOL | ||||||
|  | [ req ] | ||||||
|  | default_bits = 2048 | ||||||
|  | distinguished_name = req_distinguished_name | ||||||
|  | req_extensions = req_ext | ||||||
|  | prompt = no | ||||||
|  |  | ||||||
|  | [ req_distinguished_name ] | ||||||
|  | C = CN | ||||||
|  | ST = Zhejiang | ||||||
|  | L = Hangzhou | ||||||
|  | O = CrossDesk | ||||||
|  | OU = CrossDesk | ||||||
|  | CN = $SERVER_IP | ||||||
|  |  | ||||||
|  | [ req_ext ] | ||||||
|  | subjectAltName = IP:$SERVER_IP | ||||||
|  | EOL | ||||||
|  |  | ||||||
|  | # 5. 用根证书签发服务器证书(包含 SAN) | ||||||
|  | echo "Signing server certificate with root certificate..." | ||||||
|  | openssl x509 -req -in "$SERVER_CSR" -CA "$ROOT_CERT" -CAkey "$ROOT_KEY" -CAcreateserial \ | ||||||
|  |   -out "$SERVER_CERT" -days 3650 -sha256 -extfile "$SAN_CONF" -extensions req_ext | ||||||
|  |  | ||||||
|  | # 6. 生成完整链证书 | ||||||
|  | cat "$SERVER_CERT" "$ROOT_CERT" > "$FULLCHAIN_CERT" | ||||||
|  |  | ||||||
|  | # 7. 清理中间文件 | ||||||
|  | rm -f "$ROOT_CERT.srl" "$SAN_CONF" "$ROOT_KEY" "$SERVER_CSR" "FULLCHAIN_CERT" | ||||||
|  |  | ||||||
|  | echo "Generation complete. Deployment files:" | ||||||
|  | echo "  Client root certificate: $ROOT_CERT" | ||||||
|  | echo "  Server private key: $SERVER_KEY" | ||||||
|  | echo "  Server certificate: $SERVER_CERT" | ||||||
|  | ``` | ||||||
|  | 执行 | ||||||
|  | ``` | ||||||
|  | chmod +x generate_certs.sh | ||||||
|  | ./generate_certs.sh 服务器外网IP | ||||||
|  |  | ||||||
|  | # 例如 ./generate_certs.sh 111.111.111.111 | ||||||
|  | ``` | ||||||
|  | 输出如下: | ||||||
|  | ``` | ||||||
|  | Generating root private key... | ||||||
|  | Generating self-signed root certificate... | ||||||
|  | Generating server private key... | ||||||
|  | Generating server CSR... | ||||||
|  | Signing server certificate with root certificate... | ||||||
|  | Certificate request self-signature ok | ||||||
|  | subject=C = CN, ST = Zhejiang, L = Hangzhou, O = CrossDesk, OU = CrossDesk, CN = xxx.xxx.xxx.xxx | ||||||
|  | cleaning up intermediate files... | ||||||
|  | Generation complete. Deployment files:: | ||||||
|  |   Client root certificate:: crossdesk.cn_root.crt | ||||||
|  |   Server private key: crossdesk.cn.key | ||||||
|  |   Server certificate: crossdesk.cn_bundle.crt | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 服务端 | ||||||
|  | 将 **crossdesk.cn.key** 和 **crossdesk.cn_bundle.crt** 放置到 **/path/to/your/certs** 目录下。 | ||||||
|  |  | ||||||
|  | #### 客户端 | ||||||
|  | 1. 点击右上角设置进入设置页面。<br> | ||||||
|  | <img width="600" height="210" alt="image" src="https://github.com/user-attachments/assets/6431131d-b32a-4726-8783-6788f47baa3b" /><br><br> | ||||||
|  |  | ||||||
|  | 3. 点击点击**自托管服务器配置**。<br><br> | ||||||
|  | <img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/24c761a3-1985-4d7e-84be-787383c2afb8" /><br><br> | ||||||
|  |  | ||||||
|  | 5. 在**证书文件路径**选择框中找到 **crossdesk.cn_root.crt** 的存放路径,选中 **crossdesk.cn_root.crt**,点击确认。<br><br> | ||||||
|  | <img width="600" height="220" alt="image" src="https://github.com/user-attachments/assets/4af7cd3a-c72e-44fb-b032-30e050019c2a" /><br><br> | ||||||
|  |  | ||||||
|  | 7. 勾选使用**自托管服务器配置**,点击确认配置生效。<br><br> | ||||||
|  | <img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/1e455dc3-4087-4f37-a544-1ff9f8789383" /><br><br> | ||||||
|   | |||||||
							
								
								
									
										169
									
								
								README_EN.md
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								README_EN.md
									
									
									
									
									
								
							| @@ -1,8 +1,5 @@ | |||||||
| # CrossDesk | # CrossDesk | ||||||
|  |  | ||||||
| #### Bridging work, uniting efficiency |  | ||||||
|  |  | ||||||
| ---- |  | ||||||
| [中文](README.md) / [English](README_EN.md) | [中文](README.md) / [English](README_EN.md) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -17,15 +14,15 @@ CrossDesk is an experimental application of [MiniRTC](https://github.com/kunkund | |||||||
|  |  | ||||||
| Enter the remote desktop ID in the menu bar’s “Remote ID” field and click “→” to initiate a remote connection. | Enter the remote desktop ID in the menu bar’s “Remote ID” field and click “→” to initiate a remote connection. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| If the remote desktop requires a connection password, you must enter the correct password on your side to successfully establish the connection. | If the remote desktop requires a connection password, you must enter the correct password on your side to successfully establish the connection. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Before connecting, you can customize configuration options in the settings, such as language and video encoding format. | Before connecting, you can customize configuration options in the settings, such as language and video encoding format. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## How to build | ## How to build | ||||||
|  |  | ||||||
| @@ -73,7 +70,7 @@ xmake r crossdesk | |||||||
| #### Notice | #### Notice | ||||||
| If the client status bar shows **Disconnected** during runtime, please first install the client from the [CrossDesk official website](https://www.crossdesk.cn/) to ensure the required certificate files are available in the environment. | If the client status bar shows **Disconnected** during runtime, please first install the client from the [CrossDesk official website](https://www.crossdesk.cn/) to ensure the required certificate files are available in the environment. | ||||||
|  |  | ||||||
| <img width="108" height="57" alt="image" src="https://github.com/user-attachments/assets/26e8b9f3-b326-410e-9466-dd073eaf675a" /> | <img width="256" height="120" alt="image" src="https://github.com/user-attachments/assets/1812f7d6-516b-4b4f-8a3d-98bee505cc5a" /> | ||||||
|  |  | ||||||
| ## About Xmake | ## About Xmake | ||||||
| #### Installing Xmake | #### Installing Xmake | ||||||
| @@ -114,3 +111,161 @@ xmake r -d crossdesk | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| For more information, please refer to the [official Xmake documentation](https://xmake.io/guide/quick-start.html) . | For more information, please refer to the [official Xmake documentation](https://xmake.io/guide/quick-start.html) . | ||||||
|  |  | ||||||
|  | ## Self-Hosted Server | ||||||
|  | It is recommended to deploy CrossDesk Server using Docker. | ||||||
|  | ``` | ||||||
|  | sudo docker run -d \ | ||||||
|  |   --name crossdesk_server \ | ||||||
|  |   --network host \ | ||||||
|  |   -e EXTERNAL_IP=150.158.81.30 \ | ||||||
|  |   -e INTERNAL_IP=10.0.4.3 \ | ||||||
|  |   -e CROSSDESK_SERVER_PORT=9099 \ | ||||||
|  |   -v /path/to/your/certs:/crossdesk-server/certs \ | ||||||
|  |   -v /path/to/your/db:/crossdesk-server/db \ | ||||||
|  |   -v /path/to/your/logs:/crossdesk-server/logs \ | ||||||
|  |   crossdesk/crossdesk-server:latest | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The parameters you need to pay attention to are as follows: | ||||||
|  |  | ||||||
|  | - **EXTERNAL_IP**: The server's public IP, corresponding to the **Server Address** in the CrossDesk client **Self-Hosted Server Configuration**. | ||||||
|  |  | ||||||
|  | - **INTERNAL_IP**: The server's internal IP. | ||||||
|  |  | ||||||
|  | - **CROSSDESK_SERVER_PORT**: The port used by the self-hosted server, corresponding to the **Server Port** in the CrossDesk client **Self-Hosted Server Configuration**. | ||||||
|  |  | ||||||
|  | - **/path/to/your/certs**: Directory for certificate files. | ||||||
|  |  | ||||||
|  | - **/path/to/your/db**: CrossDesk Server device management database. | ||||||
|  |  | ||||||
|  | - **/path/to/your/logs**: Log directory. | ||||||
|  |  | ||||||
|  | **Note**:   | ||||||
|  | - **/path/to/your/ is an example path; please replace it with your actual path. The mounted directories must be created in advance, otherwise the container will fail.** | ||||||
|  | - **The server must open the following ports: 3478/udp, 3478/tcp, 30000-60000/udp, CROSSDESK_SERVER_PORT/tcp, 443/tcp.** | ||||||
|  |  | ||||||
|  | ## Certificate Files | ||||||
|  | The client needs to load the root certificate, and the server needs to load the server private key and server certificate. | ||||||
|  |  | ||||||
|  | If you already have an SSL certificate, you can skip the following certificate generation steps. | ||||||
|  |  | ||||||
|  | For users without a certificate, you can use the script below to generate the certificate files: | ||||||
|  | ``` | ||||||
|  | # Create certificate generation script | ||||||
|  | vim generate_certs.sh | ||||||
|  | ``` | ||||||
|  | Copy the following into the script: | ||||||
|  | ``` | ||||||
|  | #!/bin/bash | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | # Check arguments | ||||||
|  | if [ "$#" -ne 1 ]; then | ||||||
|  |     echo "Usage: $0 <SERVER_IP>" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | SERVER_IP="$1" | ||||||
|  |  | ||||||
|  | # Filenames | ||||||
|  | ROOT_KEY="crossdesk.cn_root.key" | ||||||
|  | ROOT_CERT="crossdesk.cn_root.crt" | ||||||
|  | SERVER_KEY="crossdesk.cn.key" | ||||||
|  | SERVER_CSR="crossdesk.cn.csr" | ||||||
|  | SERVER_CERT="crossdesk.cn_bundle.crt" | ||||||
|  | FULLCHAIN_CERT="crossdesk.cn_fullchain.crt" | ||||||
|  |  | ||||||
|  | # Certificate subject | ||||||
|  | SUBJ="/C=CN/ST=Zhejiang/L=Hangzhou/O=CrossDesk/OU=CrossDesk/CN=$SERVER_IP" | ||||||
|  |  | ||||||
|  | # 1. Generate root certificate | ||||||
|  | echo "Generating root private key..." | ||||||
|  | openssl genrsa -out "$ROOT_KEY" 4096 | ||||||
|  |  | ||||||
|  | echo "Generating self-signed root certificate..." | ||||||
|  | openssl req -x509 -new -nodes -key "$ROOT_KEY" -sha256 -days 3650 -out "$ROOT_CERT" -subj "$SUBJ" | ||||||
|  |  | ||||||
|  | # 2. Generate server private key | ||||||
|  | echo "Generating server private key..." | ||||||
|  | openssl genrsa -out "$SERVER_KEY" 2048 | ||||||
|  |  | ||||||
|  | # 3. Generate server CSR | ||||||
|  | echo "Generating server CSR..." | ||||||
|  | openssl req -new -key "$SERVER_KEY" -out "$SERVER_CSR" -subj "$SUBJ" | ||||||
|  |  | ||||||
|  | # 4. Create temporary OpenSSL config file with SAN | ||||||
|  | SAN_CONF="san.cnf" | ||||||
|  | cat > $SAN_CONF <<EOL | ||||||
|  | [ req ] | ||||||
|  | default_bits = 2048 | ||||||
|  | distinguished_name = req_distinguished_name | ||||||
|  | req_extensions = req_ext | ||||||
|  | prompt = no | ||||||
|  |  | ||||||
|  | [ req_distinguished_name ] | ||||||
|  | C = CN | ||||||
|  | ST = Zhejiang | ||||||
|  | L = Hangzhou | ||||||
|  | O = CrossDesk | ||||||
|  | OU = CrossDesk | ||||||
|  | CN = $SERVER_IP | ||||||
|  |  | ||||||
|  | [ req_ext ] | ||||||
|  | subjectAltName = IP:$SERVER_IP | ||||||
|  | EOL | ||||||
|  |  | ||||||
|  | # 5. Sign server certificate with root certificate (including SAN) | ||||||
|  | echo "Signing server certificate with root certificate..." | ||||||
|  | openssl x509 -req -in "$SERVER_CSR" -CA "$ROOT_CERT" -CAkey "$ROOT_KEY" -CAcreateserial \ | ||||||
|  |   -out "$SERVER_CERT" -days 3650 -sha256 -extfile "$SAN_CONF" -extensions req_ext | ||||||
|  |  | ||||||
|  | # 6. Generate full chain certificate | ||||||
|  | cat "$SERVER_CERT" "$ROOT_CERT" > "$FULLCHAIN_CERT" | ||||||
|  |  | ||||||
|  | # 7. Clean up intermediate files | ||||||
|  | rm -f "$ROOT_CERT.srl" "$SAN_CONF" "$ROOT_KEY" "$SERVER_CSR" "FULLCHAIN_CERT" | ||||||
|  |  | ||||||
|  | echo "Generation complete. Deployment files:" | ||||||
|  | echo "  Client root certificate: $ROOT_CERT" | ||||||
|  | echo "  Server private key: $SERVER_KEY" | ||||||
|  | echo "  Server certificate: $SERVER_CERT" | ||||||
|  | ``` | ||||||
|  | Execute: | ||||||
|  | ``` | ||||||
|  | chmod +x generate_certs.sh | ||||||
|  | ./generate_certs.sh EXTERNAL_IP | ||||||
|  |  | ||||||
|  | # example ./generate_certs.sh 111.111.111.111 | ||||||
|  | ``` | ||||||
|  | Expected output: | ||||||
|  | ``` | ||||||
|  | Generating root private key... | ||||||
|  | Generating self-signed root certificate... | ||||||
|  | Generating server private key... | ||||||
|  | Generating server CSR... | ||||||
|  | Signing server certificate with root certificate... | ||||||
|  | Certificate request self-signature ok | ||||||
|  | subject=C = CN, ST = Zhejiang, L = Hangzhou, O = CrossDesk, OU = CrossDesk, CN = xxx.xxx.xxx.xxx | ||||||
|  | cleaning up intermediate files... | ||||||
|  | Generation complete. Deployment files:: | ||||||
|  |   Client root certificate:: crossdesk.cn_root.crt | ||||||
|  |   Server private key: crossdesk.cn.key | ||||||
|  |   Server certificate: crossdesk.cn_bundle.crt | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### Server Side | ||||||
|  | Place **crossdesk.cn.key** and **crossdesk.cn_bundle.crt** into the **/path/to/your/certs** directory. | ||||||
|  |  | ||||||
|  | #### Client Side | ||||||
|  | 1. Click the settings icon in the top-right corner to enter the settings page.<br> | ||||||
|  | <img width="600" height="210" alt="image" src="https://github.com/user-attachments/assets/6431131d-b32a-4726-8783-6788f47baa3b" /><br><br> | ||||||
|  |  | ||||||
|  | 2. Click **Self-Hosted Server Configuration**.<br><br> | ||||||
|  | <img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/24c761a3-1985-4d7e-84be-787383c2afb8" /><br><br> | ||||||
|  |  | ||||||
|  | 3. In the **Certificate File Path** selection, locate and select the **crossdesk.cn_root.crt** file.<br><br> | ||||||
|  | <img width="600" height="220" alt="image" src="https://github.com/user-attachments/assets/4af7cd3a-c72e-44fb-b032-30e050019c2a" /><br><br> | ||||||
|  |  | ||||||
|  | 4. Check the option to use **Self-Hosted Server Configuration**.<br><br> | ||||||
|  | <img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/1e455dc3-4087-4f37-a544-1ff9f8789383" /><br><br> | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3644
									
								
								src/config_center/SimpleIni.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3644
									
								
								src/config_center/SimpleIni.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,64 +1,229 @@ | |||||||
| #include "config_center.h" | #include "config_center.h" | ||||||
|  |  | ||||||
| #include "rd_log.h" | ConfigCenter::ConfigCenter(const std::string& config_path, | ||||||
|  |                            const std::string& cert_file_path) | ||||||
| ConfigCenter::ConfigCenter() {} |     : config_path_(config_path), | ||||||
|  |       cert_file_path_(cert_file_path), | ||||||
|  |       cert_file_path_default_(cert_file_path) { | ||||||
|  |   ini_.SetUnicode(true); | ||||||
|  |   Load(); | ||||||
|  | } | ||||||
|  |  | ||||||
| ConfigCenter::~ConfigCenter() {} | ConfigCenter::~ConfigCenter() {} | ||||||
|  |  | ||||||
|  | int ConfigCenter::Load() { | ||||||
|  |   SI_Error rc = ini_.LoadFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     Save(); | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   language_ = static_cast<LANGUAGE>( | ||||||
|  |       ini_.GetLongValue(section_, "language", static_cast<long>(language_))); | ||||||
|  |  | ||||||
|  |   video_quality_ = static_cast<VIDEO_QUALITY>(ini_.GetLongValue( | ||||||
|  |       section_, "video_quality", static_cast<long>(video_quality_))); | ||||||
|  |  | ||||||
|  |   video_frame_rate_ = static_cast<VIDEO_FRAME_RATE>(ini_.GetLongValue( | ||||||
|  |       section_, "video_frame_rate", static_cast<long>(video_frame_rate_))); | ||||||
|  |  | ||||||
|  |   video_encode_format_ = static_cast<VIDEO_ENCODE_FORMAT>( | ||||||
|  |       ini_.GetLongValue(section_, "video_encode_format", | ||||||
|  |                         static_cast<long>(video_encode_format_))); | ||||||
|  |  | ||||||
|  |   hardware_video_codec_ = ini_.GetBoolValue(section_, "hardware_video_codec", | ||||||
|  |                                             hardware_video_codec_); | ||||||
|  |  | ||||||
|  |   enable_turn_ = ini_.GetBoolValue(section_, "enable_turn", enable_turn_); | ||||||
|  |   enable_srtp_ = ini_.GetBoolValue(section_, "enable_srtp", enable_srtp_); | ||||||
|  |   server_host_ = ini_.GetValue(section_, "server_host", server_host_.c_str()); | ||||||
|  |   server_port_ = static_cast<int>( | ||||||
|  |       ini_.GetLongValue(section_, "server_port", server_port_)); | ||||||
|  |   cert_file_path_ = | ||||||
|  |       ini_.GetValue(section_, "cert_file_path", cert_file_path_.c_str()); | ||||||
|  |   enable_self_hosted_ = | ||||||
|  |       ini_.GetBoolValue(section_, "enable_self_hosted", enable_self_hosted_); | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ConfigCenter::Save() { | ||||||
|  |   ini_.SetLongValue(section_, "language", static_cast<long>(language_)); | ||||||
|  |   ini_.SetLongValue(section_, "video_quality", | ||||||
|  |                     static_cast<long>(video_quality_)); | ||||||
|  |   ini_.SetLongValue(section_, "video_frame_rate", | ||||||
|  |                     static_cast<long>(video_frame_rate_)); | ||||||
|  |   ini_.SetLongValue(section_, "video_encode_format", | ||||||
|  |                     static_cast<long>(video_encode_format_)); | ||||||
|  |   ini_.SetBoolValue(section_, "hardware_video_codec", hardware_video_codec_); | ||||||
|  |   ini_.SetBoolValue(section_, "enable_turn", enable_turn_); | ||||||
|  |   ini_.SetBoolValue(section_, "enable_srtp", enable_srtp_); | ||||||
|  |   ini_.SetValue(section_, "server_host", server_host_.c_str()); | ||||||
|  |   ini_.SetLongValue(section_, "server_port", static_cast<long>(server_port_)); | ||||||
|  |   ini_.SetValue(section_, "cert_file_path", cert_file_path_.c_str()); | ||||||
|  |   ini_.SetBoolValue(section_, "enable_self_hosted", enable_self_hosted_); | ||||||
|  |  | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // setters | ||||||
|  |  | ||||||
| int ConfigCenter::SetLanguage(LANGUAGE language) { | int ConfigCenter::SetLanguage(LANGUAGE language) { | ||||||
|   language_ = language; |   language_ = language; | ||||||
|  |   ini_.SetLongValue(section_, "language", static_cast<long>(language_)); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetVideoQuality(VIDEO_QUALITY video_quality) { | int ConfigCenter::SetVideoQuality(VIDEO_QUALITY video_quality) { | ||||||
|   video_quality_ = video_quality; |   video_quality_ = video_quality; | ||||||
|  |   ini_.SetLongValue(section_, "video_quality", | ||||||
|  |                     static_cast<long>(video_quality_)); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetVideoFrameRate(VIDEO_FRAME_RATE video_frame_rate) { | int ConfigCenter::SetVideoFrameRate(VIDEO_FRAME_RATE video_frame_rate) { | ||||||
|   video_frame_rate_ = video_frame_rate; |   video_frame_rate_ = video_frame_rate; | ||||||
|  |   ini_.SetLongValue(section_, "video_frame_rate", | ||||||
|  |                     static_cast<long>(video_frame_rate_)); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetVideoEncodeFormat( | int ConfigCenter::SetVideoEncodeFormat( | ||||||
|     VIDEO_ENCODE_FORMAT video_encode_format) { |     VIDEO_ENCODE_FORMAT video_encode_format) { | ||||||
|   video_encode_format_ = video_encode_format; |   video_encode_format_ = video_encode_format; | ||||||
|  |   ini_.SetLongValue(section_, "video_encode_format", | ||||||
|  |                     static_cast<long>(video_encode_format_)); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetHardwareVideoCodec(bool hardware_video_codec) { | int ConfigCenter::SetHardwareVideoCodec(bool hardware_video_codec) { | ||||||
|   hardware_video_codec_ = hardware_video_codec; |   hardware_video_codec_ = hardware_video_codec; | ||||||
|  |   ini_.SetBoolValue(section_, "hardware_video_codec", hardware_video_codec_); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetTurn(bool enable_turn) { | int ConfigCenter::SetTurn(bool enable_turn) { | ||||||
|   enable_turn_ = enable_turn; |   enable_turn_ = enable_turn; | ||||||
|  |   ini_.SetBoolValue(section_, "enable_turn", enable_turn_); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::SetSrtp(bool enable_srtp) { | int ConfigCenter::SetSrtp(bool enable_srtp) { | ||||||
|   enable_srtp_ = enable_srtp; |   enable_srtp_ = enable_srtp; | ||||||
|  |   ini_.SetBoolValue(section_, "enable_srtp", enable_srtp_); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| ConfigCenter::LANGUAGE ConfigCenter::GetLanguage() { return language_; } | int ConfigCenter::SetServerHost(const std::string& server_host) { | ||||||
|  |   server_host_ = server_host; | ||||||
|  |   ini_.SetValue(section_, "server_host", server_host_.c_str()); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| ConfigCenter::VIDEO_QUALITY ConfigCenter::GetVideoQuality() { | int ConfigCenter::SetServerPort(int server_port) { | ||||||
|  |   server_port_ = server_port; | ||||||
|  |   ini_.SetLongValue(section_, "server_port", static_cast<long>(server_port_)); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ConfigCenter::SetCertFilePath(const std::string& cert_file_path) { | ||||||
|  |   cert_file_path_ = cert_file_path; | ||||||
|  |   ini_.SetValue(section_, "cert_file_path", cert_file_path_.c_str()); | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ConfigCenter::SetSelfHosted(bool enable_self_hosted) { | ||||||
|  |   enable_self_hosted_ = enable_self_hosted; | ||||||
|  |   SI_Error rc = ini_.SaveFile(config_path_.c_str()); | ||||||
|  |   if (rc < 0) { | ||||||
|  |     return -1; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // getters | ||||||
|  |  | ||||||
|  | ConfigCenter::LANGUAGE ConfigCenter::GetLanguage() const { return language_; } | ||||||
|  |  | ||||||
|  | ConfigCenter::VIDEO_QUALITY ConfigCenter::GetVideoQuality() const { | ||||||
|   return video_quality_; |   return video_quality_; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ConfigCenter::GetVideoFrameRate() { | ConfigCenter::VIDEO_FRAME_RATE ConfigCenter::GetVideoFrameRate() const { | ||||||
|   int fps = video_frame_rate_ == VIDEO_FRAME_RATE::FPS_30 ? 30 : 60; |   return video_frame_rate_; | ||||||
|   return fps; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ConfigCenter::VIDEO_ENCODE_FORMAT ConfigCenter::GetVideoEncodeFormat() { | ConfigCenter::VIDEO_ENCODE_FORMAT ConfigCenter::GetVideoEncodeFormat() const { | ||||||
|   return video_encode_format_; |   return video_encode_format_; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool ConfigCenter::IsHardwareVideoCodec() { return hardware_video_codec_; } | bool ConfigCenter::IsHardwareVideoCodec() const { | ||||||
|  |   return hardware_video_codec_; | ||||||
|  | } | ||||||
|  |  | ||||||
| bool ConfigCenter::IsEnableTurn() { return enable_turn_; } | bool ConfigCenter::IsEnableTurn() const { return enable_turn_; } | ||||||
|  |  | ||||||
| bool ConfigCenter::IsEnableSrtp() { return enable_srtp_; } | bool ConfigCenter::IsEnableSrtp() const { return enable_srtp_; } | ||||||
|  |  | ||||||
|  | std::string ConfigCenter::GetServerHost() const { return server_host_; } | ||||||
|  |  | ||||||
|  | int ConfigCenter::GetServerPort() const { return server_port_; } | ||||||
|  |  | ||||||
|  | std::string ConfigCenter::GetCertFilePath() const { return cert_file_path_; } | ||||||
|  |  | ||||||
|  | std::string ConfigCenter::GetDefaultServerHost() const { | ||||||
|  |   return server_host_default_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ConfigCenter::GetDefaultServerPort() const { return server_port_default_; } | ||||||
|  |  | ||||||
|  | std::string ConfigCenter::GetDefaultCertFilePath() const { | ||||||
|  |   return cert_file_path_default_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ConfigCenter::IsSelfHosted() const { return enable_self_hosted_; } | ||||||
| @@ -7,18 +7,24 @@ | |||||||
| #ifndef _CONFIG_CENTER_H_ | #ifndef _CONFIG_CENTER_H_ | ||||||
| #define _CONFIG_CENTER_H_ | #define _CONFIG_CENTER_H_ | ||||||
|  |  | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
|  | #include "SimpleIni.h" | ||||||
|  |  | ||||||
| class ConfigCenter { | class ConfigCenter { | ||||||
|  public: |  public: | ||||||
|   enum class LANGUAGE { CHINESE = 0, ENGLISH = 1 }; |   enum class LANGUAGE { CHINESE = 0, ENGLISH = 1 }; | ||||||
|   enum class VIDEO_QUALITY { LOW = 0, MEDIUM = 1, HIGH = 2 }; |   enum class VIDEO_QUALITY { LOW = 0, MEDIUM = 1, HIGH = 2 }; | ||||||
|   enum class VIDEO_FRAME_RATE { FPS_30 = 0, FPS_60 = 1 }; |   enum class VIDEO_FRAME_RATE { FPS_30 = 0, FPS_60 = 1 }; | ||||||
|   enum class VIDEO_ENCODE_FORMAT { AV1 = 0, H264 = 1 }; |   enum class VIDEO_ENCODE_FORMAT { H264 = 0, AV1 = 1 }; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   ConfigCenter(); |   explicit ConfigCenter( | ||||||
|  |       const std::string& config_path = "config.ini", | ||||||
|  |       const std::string& cert_file_path = "crossdesk.cn_root.crt"); | ||||||
|   ~ConfigCenter(); |   ~ConfigCenter(); | ||||||
|  |  | ||||||
|  public: |   // write config | ||||||
|   int SetLanguage(LANGUAGE language); |   int SetLanguage(LANGUAGE language); | ||||||
|   int SetVideoQuality(VIDEO_QUALITY video_quality); |   int SetVideoQuality(VIDEO_QUALITY video_quality); | ||||||
|   int SetVideoFrameRate(VIDEO_FRAME_RATE video_frame_rate); |   int SetVideoFrameRate(VIDEO_FRAME_RATE video_frame_rate); | ||||||
| @@ -26,25 +32,50 @@ class ConfigCenter { | |||||||
|   int SetHardwareVideoCodec(bool hardware_video_codec); |   int SetHardwareVideoCodec(bool hardware_video_codec); | ||||||
|   int SetTurn(bool enable_turn); |   int SetTurn(bool enable_turn); | ||||||
|   int SetSrtp(bool enable_srtp); |   int SetSrtp(bool enable_srtp); | ||||||
|  |   int SetServerHost(const std::string& server_host); | ||||||
|  |   int SetServerPort(int server_port); | ||||||
|  |   int SetCertFilePath(const std::string& cert_file_path); | ||||||
|  |   int SetSelfHosted(bool enable_self_hosted); | ||||||
|  |  | ||||||
|  public: |   // read config | ||||||
|   LANGUAGE GetLanguage(); |  | ||||||
|   VIDEO_QUALITY GetVideoQuality(); |   LANGUAGE GetLanguage() const; | ||||||
|   int GetVideoFrameRate(); |   VIDEO_QUALITY GetVideoQuality() const; | ||||||
|   VIDEO_ENCODE_FORMAT GetVideoEncodeFormat(); |   VIDEO_FRAME_RATE GetVideoFrameRate() const; | ||||||
|   bool IsHardwareVideoCodec(); |   VIDEO_ENCODE_FORMAT GetVideoEncodeFormat() const; | ||||||
|   bool IsEnableTurn(); |   bool IsHardwareVideoCodec() const; | ||||||
|   bool IsEnableSrtp(); |   bool IsEnableTurn() const; | ||||||
|  |   bool IsEnableSrtp() const; | ||||||
|  |   std::string GetServerHost() const; | ||||||
|  |   int GetServerPort() const; | ||||||
|  |   std::string GetCertFilePath() const; | ||||||
|  |   std::string GetDefaultServerHost() const; | ||||||
|  |   int GetDefaultServerPort() const; | ||||||
|  |   std::string GetDefaultCertFilePath() const; | ||||||
|  |   bool IsSelfHosted() const; | ||||||
|  |  | ||||||
|  |   int Load(); | ||||||
|  |   int Save(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // Default value should be same with parameters in localization.h |   std::string config_path_; | ||||||
|  |   std::string cert_file_path_; | ||||||
|  |   CSimpleIniA ini_; | ||||||
|  |   const char* section_ = "Settings"; | ||||||
|  |  | ||||||
|   LANGUAGE language_ = LANGUAGE::CHINESE; |   LANGUAGE language_ = LANGUAGE::CHINESE; | ||||||
|   VIDEO_QUALITY video_quality_ = VIDEO_QUALITY::MEDIUM; |   VIDEO_QUALITY video_quality_ = VIDEO_QUALITY::MEDIUM; | ||||||
|   VIDEO_FRAME_RATE video_frame_rate_ = VIDEO_FRAME_RATE::FPS_30; |   VIDEO_FRAME_RATE video_frame_rate_ = VIDEO_FRAME_RATE::FPS_30; | ||||||
|   VIDEO_ENCODE_FORMAT video_encode_format_ = VIDEO_ENCODE_FORMAT::AV1; |   VIDEO_ENCODE_FORMAT video_encode_format_ = VIDEO_ENCODE_FORMAT::H264; | ||||||
|   bool hardware_video_codec_ = false; |   bool hardware_video_codec_ = false; | ||||||
|   bool enable_turn_ = false; |   bool enable_turn_ = false; | ||||||
|   bool enable_srtp_ = false; |   bool enable_srtp_ = false; | ||||||
|  |   std::string server_host_ = "api.crossdesk.cn"; | ||||||
|  |   int server_port_ = 9099; | ||||||
|  |   std::string server_host_default_ = "api.crossdesk.cn"; | ||||||
|  |   int server_port_default_ = 9099; | ||||||
|  |   std::string cert_file_path_default_ = ""; | ||||||
|  |   bool enable_self_hosted_ = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
							
								
								
									
										2710
									
								
								src/gui/assets/fonts/OPPOSans_Regular.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2710
									
								
								src/gui/assets/fonts/OPPOSans_Regular.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										56
									
								
								src/gui/assets/layouts/layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/gui/assets/layouts/layout.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: DI JUNKUN | ||||||
|  |  * @Date: 2024-06-14 | ||||||
|  |  * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef _LAYOUT_STYLE_H_ | ||||||
|  | #define _LAYOUT_STYLE_H_ | ||||||
|  |  | ||||||
|  | #define MENU_WINDOW_WIDTH_CN 300 | ||||||
|  | #define MENU_WINDOW_HEIGHT_CN 280 | ||||||
|  | #define LOCAL_WINDOW_WIDTH_CN 300 | ||||||
|  | #define LOCAL_WINDOW_HEIGHT_CN 280 | ||||||
|  | #define REMOTE_WINDOW_WIDTH_CN 300 | ||||||
|  | #define REMOTE_WINDOW_HEIGHT_CN 280 | ||||||
|  | #define MENU_WINDOW_WIDTH_EN 190 | ||||||
|  | #define MENU_WINDOW_HEIGHT_EN 245 | ||||||
|  | #define IPUT_WINDOW_WIDTH 160 | ||||||
|  | #define INPUT_WINDOW_PADDING_CN 66 | ||||||
|  | #define INPUT_WINDOW_PADDING_EN 96 | ||||||
|  | #define SETTINGS_WINDOW_WIDTH_CN 202 | ||||||
|  | #define SETTINGS_WINDOW_WIDTH_EN 248 | ||||||
|  | #define SETTINGS_WINDOW_HEIGHT_CN 315 | ||||||
|  | #define SETTINGS_WINDOW_HEIGHT_EN 315 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN 228 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN 275 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN 165 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN 165 | ||||||
|  | #define LANGUAGE_SELECT_WINDOW_PADDING_CN 120 | ||||||
|  | #define LANGUAGE_SELECT_WINDOW_PADDING_EN 167 | ||||||
|  | #define VIDEO_QUALITY_SELECT_WINDOW_PADDING_CN 120 | ||||||
|  | #define VIDEO_QUALITY_SELECT_WINDOW_PADDING_EN 167 | ||||||
|  | #define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_CN 120 | ||||||
|  | #define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_EN 167 | ||||||
|  | #define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_CN 120 | ||||||
|  | #define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_EN 167 | ||||||
|  | #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_CN 171 | ||||||
|  | #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218 | ||||||
|  | #define ENABLE_TURN_CHECKBOX_PADDING_CN 171 | ||||||
|  | #define ENABLE_TURN_CHECKBOX_PADDING_EN 218 | ||||||
|  | #define ENABLE_SRTP_CHECKBOX_PADDING_CN 171 | ||||||
|  | #define ENABLE_SRTP_CHECKBOX_PADDING_EN 218 | ||||||
|  | #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171 | ||||||
|  | #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218 | ||||||
|  | #define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_CN 90 | ||||||
|  | #define SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_EN 137 | ||||||
|  | #define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN 90 | ||||||
|  | #define SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN 137 | ||||||
|  | #define SETTINGS_SELECT_WINDOW_WIDTH 73 | ||||||
|  | #define SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH 130 | ||||||
|  | #define SETTINGS_OK_BUTTON_PADDING_CN 65 | ||||||
|  | #define SETTINGS_OK_BUTTON_PADDING_EN 83 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_CN 78 | ||||||
|  | #define SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_EN 91 | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -91,10 +91,22 @@ static std::vector<std::string> enable_hardware_video_codec = { | |||||||
|     "Enable Hardware Video Codec:"}; |     "Enable Hardware Video Codec:"}; | ||||||
| static std::vector<std::string> enable_turn = { | static std::vector<std::string> enable_turn = { | ||||||
|     reinterpret_cast<const char*>(u8"启用中继服务:"), "Enable TURN Service:"}; |     reinterpret_cast<const char*>(u8"启用中继服务:"), "Enable TURN Service:"}; | ||||||
| 
 |  | ||||||
| static std::vector<std::string> enable_srtp = { | static std::vector<std::string> enable_srtp = { | ||||||
|     reinterpret_cast<const char*>(u8"启用SRTP:"), "Enable SRTP:"}; |     reinterpret_cast<const char*>(u8"启用SRTP:"), "Enable SRTP:"}; | ||||||
| 
 | static std::vector<std::string> self_hosted_server_config = { | ||||||
|  |     reinterpret_cast<const char*>(u8"自托管服务器配置"), | ||||||
|  |     "Self-Hosted Server Config"}; | ||||||
|  | static std::vector<std::string> self_hosted_server_settings = { | ||||||
|  |     reinterpret_cast<const char*>(u8"自托管服务器设置"), | ||||||
|  |     "Self-Hosted Server Settings"}; | ||||||
|  | static std::vector<std::string> self_hosted_server_address = { | ||||||
|  |     reinterpret_cast<const char*>(u8"服务器地址:"), "Server Address:"}; | ||||||
|  | static std::vector<std::string> self_hosted_server_port = { | ||||||
|  |     reinterpret_cast<const char*>(u8"服务器端口:"), "Server Port:"}; | ||||||
|  | static std::vector<std::string> self_hosted_server_certificate_path = { | ||||||
|  |     reinterpret_cast<const char*>(u8"证书文件路径:"), "Certificate File Path:"}; | ||||||
|  | static std::vector<std::string> select_a_file = { | ||||||
|  |     reinterpret_cast<const char*>(u8"请选择文件"), "Please select a file"}; | ||||||
| static std::vector<std::string> ok = {reinterpret_cast<const char*>(u8"确认"), | static std::vector<std::string> ok = {reinterpret_cast<const char*>(u8"确认"), | ||||||
|                                       "OK"}; |                                       "OK"}; | ||||||
| static std::vector<std::string> cancel = { | static std::vector<std::string> cancel = { | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| #include <random> | #include <random> | ||||||
| 
 | 
 | ||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -11,7 +11,7 @@ | |||||||
| #include "device_controller_factory.h" | #include "device_controller_factory.h" | ||||||
| #include "fa_regular_400.h" | #include "fa_regular_400.h" | ||||||
| #include "fa_solid_900.h" | #include "fa_solid_900.h" | ||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "platform.h" | #include "platform.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| @@ -171,7 +171,8 @@ Render::~Render() {} | |||||||
| 
 | 
 | ||||||
| int Render::SaveSettingsIntoCacheFile() { | int Render::SaveSettingsIntoCacheFile() { | ||||||
|   cd_cache_mutex_.lock(); |   cd_cache_mutex_.lock(); | ||||||
|   std::ofstream cd_cache_file(cache_path_ + "/cache.cd", std::ios::binary); |   std::ofstream cd_cache_file(cache_path_ + "/secure_cache.enc", | ||||||
|  |                               std::ios::binary); | ||||||
|   if (!cd_cache_file) { |   if (!cd_cache_file) { | ||||||
|     cd_cache_mutex_.unlock(); |     cd_cache_mutex_.unlock(); | ||||||
|     return -1; |     return -1; | ||||||
| @@ -181,18 +182,6 @@ int Render::SaveSettingsIntoCacheFile() { | |||||||
|          sizeof(cd_cache_.client_id_with_password)); |          sizeof(cd_cache_.client_id_with_password)); | ||||||
|   memcpy(cd_cache_.client_id_with_password, client_id_with_password_, |   memcpy(cd_cache_.client_id_with_password, client_id_with_password_, | ||||||
|          sizeof(client_id_with_password_)); |          sizeof(client_id_with_password_)); | ||||||
|   memcpy(&cd_cache_.language, &language_button_value_, |  | ||||||
|          sizeof(language_button_value_)); |  | ||||||
|   memcpy(&cd_cache_.video_quality, &video_quality_button_value_, |  | ||||||
|          sizeof(video_quality_button_value_)); |  | ||||||
|   memcpy(&cd_cache_.video_frame_rate, &video_frame_rate_button_value_, |  | ||||||
|          sizeof(video_frame_rate_button_value_)); |  | ||||||
|   memcpy(&cd_cache_.video_encode_format, &video_encode_format_button_value_, |  | ||||||
|          sizeof(video_encode_format_button_value_)); |  | ||||||
|   memcpy(&cd_cache_.enable_hardware_video_codec, &enable_hardware_video_codec_, |  | ||||||
|          sizeof(enable_hardware_video_codec_)); |  | ||||||
|   memcpy(&cd_cache_.enable_turn, &enable_turn_, sizeof(enable_turn_)); |  | ||||||
|   memcpy(&cd_cache_.enable_srtp, &enable_srtp_, sizeof(enable_srtp_)); |  | ||||||
|   memcpy(&cd_cache_.key, &aes128_key_, sizeof(aes128_key_)); |   memcpy(&cd_cache_.key, &aes128_key_, sizeof(aes128_key_)); | ||||||
|   memcpy(&cd_cache_.iv, &aes128_iv_, sizeof(aes128_iv_)); |   memcpy(&cd_cache_.iv, &aes128_iv_, sizeof(aes128_iv_)); | ||||||
| 
 | 
 | ||||||
| @@ -200,49 +189,19 @@ int Render::SaveSettingsIntoCacheFile() { | |||||||
|   cd_cache_file.close(); |   cd_cache_file.close(); | ||||||
|   cd_cache_mutex_.unlock(); |   cd_cache_mutex_.unlock(); | ||||||
| 
 | 
 | ||||||
|   config_center_.SetLanguage((ConfigCenter::LANGUAGE)language_button_value_); |  | ||||||
|   config_center_.SetVideoQuality( |  | ||||||
|       (ConfigCenter::VIDEO_QUALITY)video_quality_button_value_); |  | ||||||
|   config_center_.SetVideoFrameRate( |  | ||||||
|       (ConfigCenter::VIDEO_FRAME_RATE)video_frame_rate_button_value_); |  | ||||||
|   config_center_.SetVideoEncodeFormat( |  | ||||||
|       (ConfigCenter::VIDEO_ENCODE_FORMAT)video_encode_format_button_value_); |  | ||||||
|   config_center_.SetHardwareVideoCodec(enable_hardware_video_codec_); |  | ||||||
|   config_center_.SetTurn(enable_turn_); |  | ||||||
|   config_center_.SetSrtp(enable_srtp_); |  | ||||||
| 
 |  | ||||||
|   LOG_INFO("Save settings into cache file success"); |  | ||||||
| 
 |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Render::LoadSettingsFromCacheFile() { | int Render::LoadSettingsFromCacheFile() { | ||||||
|   cd_cache_mutex_.lock(); |   cd_cache_mutex_.lock(); | ||||||
|   std::ifstream cd_cache_file(cache_path_ + "/cache.cd", std::ios::binary); |   std::ifstream cd_cache_file(cache_path_ + "/secure_cache.enc", | ||||||
|  |                               std::ios::binary); | ||||||
|   if (!cd_cache_file) { |   if (!cd_cache_file) { | ||||||
|     cd_cache_mutex_.unlock(); |     cd_cache_mutex_.unlock(); | ||||||
| 
 | 
 | ||||||
|     LOG_INFO("Init cache file by using default settings"); |  | ||||||
|     memset(password_saved_, 0, sizeof(password_saved_)); |     memset(password_saved_, 0, sizeof(password_saved_)); | ||||||
|     memset(aes128_key_, 0, sizeof(aes128_key_)); |     memset(aes128_key_, 0, sizeof(aes128_key_)); | ||||||
|     memset(aes128_iv_, 0, sizeof(aes128_iv_)); |     memset(aes128_iv_, 0, sizeof(aes128_iv_)); | ||||||
|     language_button_value_ = 0; |  | ||||||
|     video_quality_button_value_ = 0; |  | ||||||
|     video_encode_format_button_value_ = 1; |  | ||||||
|     enable_hardware_video_codec_ = false; |  | ||||||
|     enable_turn_ = false; |  | ||||||
|     enable_srtp_ = false; |  | ||||||
| 
 |  | ||||||
|     config_center_.SetLanguage((ConfigCenter::LANGUAGE)language_button_value_); |  | ||||||
|     config_center_.SetVideoQuality( |  | ||||||
|         (ConfigCenter::VIDEO_QUALITY)video_quality_button_value_); |  | ||||||
|     config_center_.SetVideoFrameRate( |  | ||||||
|         (ConfigCenter::VIDEO_FRAME_RATE)video_frame_rate_button_value_); |  | ||||||
|     config_center_.SetVideoEncodeFormat( |  | ||||||
|         (ConfigCenter::VIDEO_ENCODE_FORMAT)video_encode_format_button_value_); |  | ||||||
|     config_center_.SetHardwareVideoCodec(enable_hardware_video_codec_); |  | ||||||
|     config_center_.SetTurn(enable_turn_); |  | ||||||
|     config_center_.SetSrtp(enable_srtp_); |  | ||||||
| 
 | 
 | ||||||
|     thumbnail_.reset(); |     thumbnail_.reset(); | ||||||
|     thumbnail_ = std::make_unique<Thumbnail>(cache_path_ + "/thumbnails/"); |     thumbnail_ = std::make_unique<Thumbnail>(cache_path_ + "/thumbnails/"); | ||||||
| @@ -289,13 +248,14 @@ int Render::LoadSettingsFromCacheFile() { | |||||||
|   thumbnail_ = std::make_unique<Thumbnail>(cache_path_ + "/thumbnails/", |   thumbnail_ = std::make_unique<Thumbnail>(cache_path_ + "/thumbnails/", | ||||||
|                                            aes128_key_, aes128_iv_); |                                            aes128_key_, aes128_iv_); | ||||||
| 
 | 
 | ||||||
|   language_button_value_ = cd_cache_.language; |   language_button_value_ = (int)config_center_->GetLanguage(); | ||||||
|   video_quality_button_value_ = cd_cache_.video_quality; |   video_quality_button_value_ = (int)config_center_->GetVideoQuality(); | ||||||
|   video_frame_rate_button_value_ = cd_cache_.video_frame_rate; |   video_frame_rate_button_value_ = (int)config_center_->GetVideoFrameRate(); | ||||||
|   video_encode_format_button_value_ = cd_cache_.video_encode_format; |   video_encode_format_button_value_ = | ||||||
|   enable_hardware_video_codec_ = cd_cache_.enable_hardware_video_codec; |       (int)config_center_->GetVideoEncodeFormat(); | ||||||
|   enable_turn_ = cd_cache_.enable_turn; |   enable_hardware_video_codec_ = config_center_->IsHardwareVideoCodec(); | ||||||
|   enable_srtp_ = cd_cache_.enable_srtp; |   enable_turn_ = config_center_->IsEnableTurn(); | ||||||
|  |   enable_srtp_ = config_center_->IsEnableSrtp(); | ||||||
| 
 | 
 | ||||||
|   language_button_value_last_ = language_button_value_; |   language_button_value_last_ = language_button_value_; | ||||||
|   video_quality_button_value_last_ = video_quality_button_value_; |   video_quality_button_value_last_ = video_quality_button_value_; | ||||||
| @@ -304,17 +264,6 @@ int Render::LoadSettingsFromCacheFile() { | |||||||
|   enable_turn_last_ = enable_turn_; |   enable_turn_last_ = enable_turn_; | ||||||
|   enable_srtp_last_ = enable_srtp_; |   enable_srtp_last_ = enable_srtp_; | ||||||
| 
 | 
 | ||||||
|   config_center_.SetLanguage((ConfigCenter::LANGUAGE)language_button_value_); |  | ||||||
|   config_center_.SetVideoQuality( |  | ||||||
|       (ConfigCenter::VIDEO_QUALITY)video_quality_button_value_); |  | ||||||
|   config_center_.SetVideoFrameRate( |  | ||||||
|       (ConfigCenter::VIDEO_FRAME_RATE)video_frame_rate_button_value_); |  | ||||||
|   config_center_.SetVideoEncodeFormat( |  | ||||||
|       (ConfigCenter::VIDEO_ENCODE_FORMAT)video_encode_format_button_value_); |  | ||||||
|   config_center_.SetHardwareVideoCodec(enable_hardware_video_codec_); |  | ||||||
|   config_center_.SetTurn(enable_turn_); |  | ||||||
|   config_center_.SetSrtp(enable_srtp_); |  | ||||||
| 
 |  | ||||||
|   LOG_INFO("Load settings from cache file"); |   LOG_INFO("Load settings from cache file"); | ||||||
| 
 | 
 | ||||||
|   return 0; |   return 0; | ||||||
| @@ -328,18 +277,21 @@ int Render::ScreenCapturerInit() { | |||||||
|   last_frame_time_ = std::chrono::duration_cast<std::chrono::milliseconds>( |   last_frame_time_ = std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
|                          std::chrono::steady_clock::now().time_since_epoch()) |                          std::chrono::steady_clock::now().time_since_epoch()) | ||||||
|                          .count(); |                          .count(); | ||||||
|   int fps = config_center_.GetVideoFrameRate(); |   int fps = config_center_->GetVideoFrameRate() == | ||||||
|  |                     ConfigCenter::VIDEO_FRAME_RATE::FPS_30 | ||||||
|  |                 ? 30 | ||||||
|  |                 : 60; | ||||||
|   LOG_INFO("Init screen capturer with {} fps", fps); |   LOG_INFO("Init screen capturer with {} fps", fps); | ||||||
| 
 | 
 | ||||||
|   int screen_capturer_init_ret = screen_capturer_->Init( |   int screen_capturer_init_ret = screen_capturer_->Init( | ||||||
|       fps, |       fps, | ||||||
|       [this](unsigned char* data, int size, int width, int height, |       [this, fps](unsigned char* data, int size, int width, int height, | ||||||
|              const char* display_name) -> void { |                   const char* display_name) -> void { | ||||||
|         auto now_time = std::chrono::duration_cast<std::chrono::milliseconds>( |         auto now_time = std::chrono::duration_cast<std::chrono::milliseconds>( | ||||||
|                             std::chrono::steady_clock::now().time_since_epoch()) |                             std::chrono::steady_clock::now().time_since_epoch()) | ||||||
|                             .count(); |                             .count(); | ||||||
|         auto duration = now_time - last_frame_time_; |         auto duration = now_time - last_frame_time_; | ||||||
|         if (duration * config_center_.GetVideoFrameRate() >= 1000) {  // ~60 FPS
 |         if (duration * fps >= 1000) {  // ~60 FPS
 | ||||||
|           XVideoFrame frame; |           XVideoFrame frame; | ||||||
|           frame.data = (const char*)data; |           frame.data = (const char*)data; | ||||||
|           frame.size = size; |           frame.size = size; | ||||||
| @@ -474,25 +426,53 @@ int Render::StopKeyboardCapturer() { | |||||||
| 
 | 
 | ||||||
| int Render::CreateConnectionPeer() { | int Render::CreateConnectionPeer() { | ||||||
|   params_.use_cfg_file = false; |   params_.use_cfg_file = false; | ||||||
|   params_.signal_server_ip = "api.crossdesk.cn"; | 
 | ||||||
|   params_.signal_server_port = 9099; |   std::string server_ip; | ||||||
|   params_.stun_server_ip = "150.158.81.30"; |   int server_port; | ||||||
|  |   std::string server_cert_path; | ||||||
|  | 
 | ||||||
|  |   if (config_center_->IsSelfHosted()) { | ||||||
|  |     server_ip = config_center_->GetServerHost(); | ||||||
|  |     server_port = config_center_->GetServerPort(); | ||||||
|  |     server_cert_path = config_center_->GetCertFilePath(); | ||||||
|  |   } else { | ||||||
|  |     server_ip = config_center_->GetDefaultServerHost(); | ||||||
|  |     server_port = config_center_->GetDefaultServerPort(); | ||||||
|  |     server_cert_path = config_center_->GetDefaultCertFilePath(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   strncpy((char*)params_.signal_server_ip, server_ip.c_str(), | ||||||
|  |           sizeof(params_.signal_server_ip) - 1); | ||||||
|  |   params_.signal_server_ip[sizeof(params_.signal_server_ip) - 1] = '\0'; | ||||||
|  |   params_.signal_server_port = server_port; | ||||||
|  |   strncpy((char*)params_.stun_server_ip, server_ip.c_str(), | ||||||
|  |           sizeof(params_.stun_server_ip) - 1); | ||||||
|  |   params_.stun_server_ip[sizeof(params_.stun_server_ip) - 1] = '\0'; | ||||||
|   params_.stun_server_port = 3478; |   params_.stun_server_port = 3478; | ||||||
|   params_.turn_server_ip = "150.158.81.30"; |   strncpy((char*)params_.turn_server_ip, server_ip.c_str(), | ||||||
|  |           sizeof(params_.turn_server_ip) - 1); | ||||||
|  |   params_.turn_server_ip[sizeof(params_.turn_server_ip) - 1] = '\0'; | ||||||
|   params_.turn_server_port = 3478; |   params_.turn_server_port = 3478; | ||||||
|   params_.turn_server_username = "dijunkun"; |   strncpy((char*)params_.turn_server_username, "dijunkun", | ||||||
|   params_.turn_server_password = "dijunkunpw"; |           sizeof(params_.turn_server_username) - 1); | ||||||
|   params_.tls_cert_path = std::filesystem::exists(cert_path_) |   params_.turn_server_username[sizeof(params_.turn_server_username) - 1] = '\0'; | ||||||
|                               ? cert_path_.c_str() |   strncpy((char*)params_.turn_server_password, "dijunkunpw", | ||||||
|                               : "certs/crossdesk.cn_root.crt"; |           sizeof(params_.turn_server_password) - 1); | ||||||
|   params_.log_path = dll_log_path_.c_str(); |   params_.turn_server_password[sizeof(params_.turn_server_password) - 1] = '\0'; | ||||||
|   params_.hardware_acceleration = config_center_.IsHardwareVideoCodec(); |   strncpy(params_.tls_cert_path, server_cert_path.c_str(), | ||||||
|   params_.av1_encoding = config_center_.GetVideoEncodeFormat() == |           sizeof(params_.tls_cert_path) - 1); | ||||||
|  |   params_.tls_cert_path[sizeof(params_.tls_cert_path) - 1] = '\0'; | ||||||
|  | 
 | ||||||
|  |   strncpy(params_.log_path, dll_log_path_.c_str(), | ||||||
|  |           sizeof(params_.log_path) - 1); | ||||||
|  |   params_.log_path[sizeof(params_.log_path) - 1] = '\0'; | ||||||
|  |   params_.hardware_acceleration = config_center_->IsHardwareVideoCodec(); | ||||||
|  |   params_.av1_encoding = config_center_->GetVideoEncodeFormat() == | ||||||
|                                  ConfigCenter::VIDEO_ENCODE_FORMAT::AV1 |                                  ConfigCenter::VIDEO_ENCODE_FORMAT::AV1 | ||||||
|                              ? true |                              ? true | ||||||
|                              : false; |                              : false; | ||||||
|   params_.enable_turn = config_center_.IsEnableTurn(); |   params_.enable_turn = config_center_->IsEnableTurn(); | ||||||
|   params_.enable_srtp = config_center_.IsEnableSrtp(); |   params_.enable_srtp = config_center_->IsEnableSrtp(); | ||||||
|   params_.on_receive_video_buffer = nullptr; |   params_.on_receive_video_buffer = nullptr; | ||||||
|   params_.on_receive_audio_buffer = OnReceiveAudioBufferCb; |   params_.on_receive_audio_buffer = OnReceiveAudioBufferCb; | ||||||
|   params_.on_receive_data_buffer = OnReceiveDataBufferCb; |   params_.on_receive_data_buffer = OnReceiveDataBufferCb; | ||||||
| @@ -890,6 +870,20 @@ int Render::Run() { | |||||||
|     exec_log_path_ = path_manager_->GetLogPath().string(); |     exec_log_path_ = path_manager_->GetLogPath().string(); | ||||||
|     dll_log_path_ = path_manager_->GetLogPath().string(); |     dll_log_path_ = path_manager_->GetLogPath().string(); | ||||||
|     cache_path_ = path_manager_->GetCachePath().string(); |     cache_path_ = path_manager_->GetCachePath().string(); | ||||||
|  |     config_center_ = | ||||||
|  |         std::make_unique<ConfigCenter>(cache_path_ + "/config.ini", cert_path_); | ||||||
|  |     strncpy(signal_server_ip_tmp_, config_center_->GetServerHost().c_str(), | ||||||
|  |             sizeof(signal_server_ip_tmp_) - 1); | ||||||
|  |     signal_server_ip_tmp_[sizeof(signal_server_ip_tmp_) - 1] = '\0'; | ||||||
|  |     strncpy(signal_server_port_tmp_, | ||||||
|  |             std::to_string(config_center_->GetServerPort()).c_str(), | ||||||
|  |             sizeof(signal_server_port_tmp_) - 1); | ||||||
|  |     signal_server_port_tmp_[sizeof(signal_server_port_tmp_) - 1] = '\0'; | ||||||
|  |     strncpy(cert_file_path_, cert_path_.c_str(), sizeof(cert_file_path_) - 1); | ||||||
|  |     cert_file_path_[sizeof(cert_file_path_) - 1] = '\0'; | ||||||
|  |   } else { | ||||||
|  |     std::cerr << "Failed to create PathManager" << std::endl; | ||||||
|  |     return -1; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   InitializeLogger(); |   InitializeLogger(); | ||||||
| @@ -152,6 +152,8 @@ class Render { | |||||||
|   int RemoteWindow(); |   int RemoteWindow(); | ||||||
|   int RecentConnectionsWindow(); |   int RecentConnectionsWindow(); | ||||||
|   int SettingWindow(); |   int SettingWindow(); | ||||||
|  |   int SelfHostedServerWindow(); | ||||||
|  |   int ShowSimpleFileBrowser(); | ||||||
|   int ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props); |   int ControlWindow(std::shared_ptr<SubStreamWindowProperties>& props); | ||||||
|   int ControlBar(std::shared_ptr<SubStreamWindowProperties>& props); |   int ControlBar(std::shared_ptr<SubStreamWindowProperties>& props); | ||||||
|   int AboutWindow(); |   int AboutWindow(); | ||||||
| @@ -261,7 +263,7 @@ class Render { | |||||||
|  private: |  private: | ||||||
|   CDCache cd_cache_; |   CDCache cd_cache_; | ||||||
|   std::mutex cd_cache_mutex_; |   std::mutex cd_cache_mutex_; | ||||||
|   ConfigCenter config_center_; |   std::unique_ptr<ConfigCenter> config_center_; | ||||||
|   ConfigCenter::LANGUAGE localization_language_ = |   ConfigCenter::LANGUAGE localization_language_ = | ||||||
|       ConfigCenter::LANGUAGE::CHINESE; |       ConfigCenter::LANGUAGE::CHINESE; | ||||||
|   std::unique_ptr<PathManager> path_manager_; |   std::unique_ptr<PathManager> path_manager_; | ||||||
| @@ -383,6 +385,7 @@ class Render { | |||||||
|   bool password_validating_ = false; |   bool password_validating_ = false; | ||||||
|   uint32_t password_validating_time_ = 0; |   uint32_t password_validating_time_ = 0; | ||||||
|   bool show_settings_window_ = false; |   bool show_settings_window_ = false; | ||||||
|  |   bool show_self_hosted_server_config_window_ = false; | ||||||
|   bool rejoin_ = false; |   bool rejoin_ = false; | ||||||
|   bool local_id_copied_ = false; |   bool local_id_copied_ = false; | ||||||
|   bool show_password_ = true; |   bool show_password_ = true; | ||||||
| @@ -431,13 +434,22 @@ class Render { | |||||||
|   bool enable_hardware_video_codec_ = false; |   bool enable_hardware_video_codec_ = false; | ||||||
|   bool enable_turn_ = false; |   bool enable_turn_ = false; | ||||||
|   bool enable_srtp_ = false; |   bool enable_srtp_ = false; | ||||||
|  |   char signal_server_ip_[256] = "api.crossdesk.cn"; | ||||||
|  |   char signal_server_port_[6] = "9099"; | ||||||
|  |   char cert_file_path_[256] = ""; | ||||||
|  |   bool enable_self_hosted_server_ = false; | ||||||
|   int language_button_value_last_ = 0; |   int language_button_value_last_ = 0; | ||||||
|   int video_quality_button_value_last_ = 0; |   int video_quality_button_value_last_ = 0; | ||||||
|   int video_encode_format_button_value_last_ = 0; |   int video_encode_format_button_value_last_ = 0; | ||||||
|   bool enable_hardware_video_codec_last_ = false; |   bool enable_hardware_video_codec_last_ = false; | ||||||
|   bool enable_turn_last_ = false; |   bool enable_turn_last_ = false; | ||||||
|   bool enable_srtp_last_ = false; |   bool enable_srtp_last_ = false; | ||||||
|  |   char signal_server_ip_tmp_[256] = "api.crossdesk.cn"; | ||||||
|  |   char signal_server_port_tmp_[6] = "9099"; | ||||||
|   bool settings_window_pos_reset_ = true; |   bool settings_window_pos_reset_ = true; | ||||||
|  |   bool self_hosted_server_config_window_pos_reset_ = true; | ||||||
|  |   std::string selected_current_file_path_ = ""; | ||||||
|  |   std::string selected_file_ = ""; | ||||||
|   /* ------ main window property end ------ */ |   /* ------ main window property end ------ */ | ||||||
| 
 | 
 | ||||||
|   /* ------ sub stream window property start ------ */ |   /* ------ sub stream window property start ------ */ | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -57,6 +57,7 @@ int Render::TitleBar(bool main_window) { | |||||||
| 
 | 
 | ||||||
|       { |       { | ||||||
|         SettingWindow(); |         SettingWindow(); | ||||||
|  |         SelfHostedServerWindow(); | ||||||
|         AboutWindow(); |         AboutWindow(); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #include "layout_style.h" | #include "layout.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
| @@ -108,7 +108,7 @@ int Render::SettingWindow() { | |||||||
|       ImGui::Separator(); |       ImGui::Separator(); | ||||||
| 
 | 
 | ||||||
|       { |       { | ||||||
|         const char* video_frame_rate_items[] = {"30", "60"}; |         const char* video_frame_rate_items[] = {"30 fps", "60 fps"}; | ||||||
| 
 | 
 | ||||||
|         settings_items_offset += settings_items_padding; |         settings_items_offset += settings_items_padding; | ||||||
|         ImGui::SetCursorPosY(settings_items_offset + 2); |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
| @@ -133,8 +133,8 @@ int Render::SettingWindow() { | |||||||
| 
 | 
 | ||||||
|       { |       { | ||||||
|         const char* video_encode_format_items[] = { |         const char* video_encode_format_items[] = { | ||||||
|             localization::av1[localization_language_index_].c_str(), |             localization::h264[localization_language_index_].c_str(), | ||||||
|             localization::h264[localization_language_index_].c_str()}; |             localization::av1[localization_language_index_].c_str()}; | ||||||
| 
 | 
 | ||||||
|         settings_items_offset += settings_items_padding; |         settings_items_offset += settings_items_padding; | ||||||
|         ImGui::SetCursorPosY(settings_items_offset + 2); |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
| @@ -211,6 +211,28 @@ int Render::SettingWindow() { | |||||||
|         ImGui::Checkbox("##enable_srtp", &enable_srtp_); |         ImGui::Checkbox("##enable_srtp", &enable_srtp_); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  |       ImGui::Separator(); | ||||||
|  | 
 | ||||||
|  |       { | ||||||
|  |         settings_items_offset += settings_items_padding; | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
|  | 
 | ||||||
|  |         if (ImGui::Button(localization::self_hosted_server_config | ||||||
|  |                               [localization_language_index_] | ||||||
|  |                                   .c_str())) { | ||||||
|  |           show_self_hosted_server_config_window_ = true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |           ImGui::SetCursorPosX(ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN); | ||||||
|  |         } else { | ||||||
|  |           ImGui::SetCursorPosX(ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN); | ||||||
|  |         } | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset); | ||||||
|  |         ImGui::Checkbox("##enable_self_hosted_server", | ||||||
|  |                         &enable_self_hosted_server_); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       if (stream_window_inited_) { |       if (stream_window_inited_) { | ||||||
|         ImGui::EndDisabled(); |         ImGui::EndDisabled(); | ||||||
|       } |       } | ||||||
| @@ -221,7 +243,7 @@ int Render::SettingWindow() { | |||||||
|         ImGui::SetCursorPosX(SETTINGS_OK_BUTTON_PADDING_EN); |         ImGui::SetCursorPosX(SETTINGS_OK_BUTTON_PADDING_EN); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       settings_items_offset += settings_items_padding; |       settings_items_offset += settings_items_padding + 10; | ||||||
|       ImGui::SetCursorPosY(settings_items_offset); |       ImGui::SetCursorPosY(settings_items_offset); | ||||||
|       ImGui::PopStyleVar(); |       ImGui::PopStyleVar(); | ||||||
| 
 | 
 | ||||||
| @@ -229,12 +251,13 @@ int Render::SettingWindow() { | |||||||
|       if (ImGui::Button( |       if (ImGui::Button( | ||||||
|               localization::ok[localization_language_index_].c_str())) { |               localization::ok[localization_language_index_].c_str())) { | ||||||
|         show_settings_window_ = false; |         show_settings_window_ = false; | ||||||
|  |         show_self_hosted_server_config_window_ = false; | ||||||
| 
 | 
 | ||||||
|         // Language
 |         // Language
 | ||||||
|         if (language_button_value_ == 0) { |         if (language_button_value_ == 0) { | ||||||
|           config_center_.SetLanguage(ConfigCenter::LANGUAGE::CHINESE); |           config_center_->SetLanguage(ConfigCenter::LANGUAGE::CHINESE); | ||||||
|         } else { |         } else { | ||||||
|           config_center_.SetLanguage(ConfigCenter::LANGUAGE::ENGLISH); |           config_center_->SetLanguage(ConfigCenter::LANGUAGE::ENGLISH); | ||||||
|         } |         } | ||||||
|         language_button_value_last_ = language_button_value_; |         language_button_value_last_ = language_button_value_; | ||||||
|         localization_language_ = (ConfigCenter::LANGUAGE)language_button_value_; |         localization_language_ = (ConfigCenter::LANGUAGE)language_button_value_; | ||||||
| @@ -244,50 +267,55 @@ int Render::SettingWindow() { | |||||||
| 
 | 
 | ||||||
|         // Video quality
 |         // Video quality
 | ||||||
|         if (video_quality_button_value_ == 0) { |         if (video_quality_button_value_ == 0) { | ||||||
|           config_center_.SetVideoQuality(ConfigCenter::VIDEO_QUALITY::HIGH); |           config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::HIGH); | ||||||
|         } else if (video_quality_button_value_ == 1) { |         } else if (video_quality_button_value_ == 1) { | ||||||
|           config_center_.SetVideoQuality(ConfigCenter::VIDEO_QUALITY::MEDIUM); |           config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::MEDIUM); | ||||||
|         } else { |         } else { | ||||||
|           config_center_.SetVideoQuality(ConfigCenter::VIDEO_QUALITY::LOW); |           config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::LOW); | ||||||
|         } |         } | ||||||
|         video_quality_button_value_last_ = video_quality_button_value_; |         video_quality_button_value_last_ = video_quality_button_value_; | ||||||
| 
 | 
 | ||||||
|         // Video encode format
 |         // Video encode format
 | ||||||
|         if (video_encode_format_button_value_ == 0) { |         if (video_encode_format_button_value_ == 0) { | ||||||
|           config_center_.SetVideoEncodeFormat( |           config_center_->SetVideoEncodeFormat( | ||||||
|               ConfigCenter::VIDEO_ENCODE_FORMAT::AV1); |  | ||||||
|         } else if (video_encode_format_button_value_ == 1) { |  | ||||||
|           config_center_.SetVideoEncodeFormat( |  | ||||||
|               ConfigCenter::VIDEO_ENCODE_FORMAT::H264); |               ConfigCenter::VIDEO_ENCODE_FORMAT::H264); | ||||||
|  |         } else if (video_encode_format_button_value_ == 1) { | ||||||
|  |           config_center_->SetVideoEncodeFormat( | ||||||
|  |               ConfigCenter::VIDEO_ENCODE_FORMAT::AV1); | ||||||
|         } |         } | ||||||
|         video_encode_format_button_value_last_ = |         video_encode_format_button_value_last_ = | ||||||
|             video_encode_format_button_value_; |             video_encode_format_button_value_; | ||||||
| 
 | 
 | ||||||
|         // Hardware video codec
 |         // Hardware video codec
 | ||||||
|         if (enable_hardware_video_codec_) { |         if (enable_hardware_video_codec_) { | ||||||
|           config_center_.SetHardwareVideoCodec(true); |           config_center_->SetHardwareVideoCodec(true); | ||||||
|         } else { |         } else { | ||||||
|           config_center_.SetHardwareVideoCodec(false); |           config_center_->SetHardwareVideoCodec(false); | ||||||
|         } |         } | ||||||
|         enable_hardware_video_codec_last_ = enable_hardware_video_codec_; |         enable_hardware_video_codec_last_ = enable_hardware_video_codec_; | ||||||
| 
 | 
 | ||||||
|         // TURN mode
 |         // TURN mode
 | ||||||
|         if (enable_turn_) { |         if (enable_turn_) { | ||||||
|           config_center_.SetTurn(true); |           config_center_->SetTurn(true); | ||||||
|         } else { |         } else { | ||||||
|           config_center_.SetTurn(false); |           config_center_->SetTurn(false); | ||||||
|         } |         } | ||||||
|         enable_turn_last_ = enable_turn_; |         enable_turn_last_ = enable_turn_; | ||||||
| 
 | 
 | ||||||
|         // SRTP
 |         // SRTP
 | ||||||
|         if (enable_srtp_) { |         if (enable_srtp_) { | ||||||
|           config_center_.SetSrtp(true); |           config_center_->SetSrtp(true); | ||||||
|         } else { |         } else { | ||||||
|           config_center_.SetSrtp(false); |           config_center_->SetSrtp(false); | ||||||
|         } |         } | ||||||
|         enable_srtp_last_ = enable_srtp_; |         enable_srtp_last_ = enable_srtp_; | ||||||
| 
 | 
 | ||||||
|         SaveSettingsIntoCacheFile(); |         if (enable_self_hosted_server_) { | ||||||
|  |           config_center_->SetSelfHosted(true); | ||||||
|  |         } else { | ||||||
|  |           config_center_->SetSelfHosted(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         settings_window_pos_reset_ = true; |         settings_window_pos_reset_ = true; | ||||||
| 
 | 
 | ||||||
|         // Recreate peer instance
 |         // Recreate peer instance
 | ||||||
| @@ -306,6 +334,8 @@ int Render::SettingWindow() { | |||||||
|       if (ImGui::Button( |       if (ImGui::Button( | ||||||
|               localization::cancel[localization_language_index_].c_str())) { |               localization::cancel[localization_language_index_].c_str())) { | ||||||
|         show_settings_window_ = false; |         show_settings_window_ = false; | ||||||
|  |         show_self_hosted_server_config_window_ = false; | ||||||
|  | 
 | ||||||
|         if (language_button_value_ != language_button_value_last_) { |         if (language_button_value_ != language_button_value_last_) { | ||||||
|           language_button_value_ = language_button_value_last_; |           language_button_value_ = language_button_value_last_; | ||||||
|         } |         } | ||||||
							
								
								
									
										270
									
								
								src/gui/windows/server_settings_window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/gui/windows/server_settings_window.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,270 @@ | |||||||
|  | #include <filesystem> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | #ifdef _WIN32 | ||||||
|  | #include <windows.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "layout.h" | ||||||
|  | #include "localization.h" | ||||||
|  | #include "rd_log.h" | ||||||
|  | #include "render.h" | ||||||
|  |  | ||||||
|  | std::vector<std::string> GetRootEntries() { | ||||||
|  |   std::vector<std::string> roots; | ||||||
|  | #ifdef _WIN32 | ||||||
|  |   DWORD mask = GetLogicalDrives(); | ||||||
|  |   for (char letter = 'A'; letter <= 'Z'; ++letter) { | ||||||
|  |     if (mask & 1) { | ||||||
|  |       roots.push_back(std::string(1, letter) + ":\\"); | ||||||
|  |     } | ||||||
|  |     mask >>= 1; | ||||||
|  |   } | ||||||
|  | #else | ||||||
|  |   roots.push_back("/"); | ||||||
|  | #endif | ||||||
|  |   return roots; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Render::ShowSimpleFileBrowser() { | ||||||
|  |   std::string display_text; | ||||||
|  |   if (!selected_file_.empty()) { | ||||||
|  |     display_text = std::filesystem::path(selected_file_).filename().string(); | ||||||
|  |   } else if (selected_current_file_path_ != "Root") { | ||||||
|  |     display_text = | ||||||
|  |         std::filesystem::path(selected_current_file_path_).filename().string(); | ||||||
|  |     if (display_text.empty()) { | ||||||
|  |       display_text = selected_current_file_path_; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (display_text.empty()) { | ||||||
|  |     display_text = | ||||||
|  |         localization::select_a_file[localization_language_index_].c_str(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ImGui::BeginCombo("##select_a_file", display_text.c_str())) { | ||||||
|  |     if (selected_current_file_path_ == "Root" || | ||||||
|  |         !std::filesystem::exists(selected_current_file_path_) || | ||||||
|  |         !std::filesystem::is_directory(selected_current_file_path_)) { | ||||||
|  |       auto roots = GetRootEntries(); | ||||||
|  |       for (const auto& root : roots) { | ||||||
|  |         if (ImGui::Selectable(root.c_str())) { | ||||||
|  |           selected_current_file_path_ = root; | ||||||
|  |           selected_file_.clear(); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       std::filesystem::path p(selected_current_file_path_); | ||||||
|  |  | ||||||
|  |       if (ImGui::Selectable("..")) { | ||||||
|  |         if (p.has_parent_path() && p != p.root_path()) | ||||||
|  |           selected_current_file_path_ = p.parent_path().string(); | ||||||
|  |         else | ||||||
|  |           selected_current_file_path_ = "Root"; | ||||||
|  |         selected_file_.clear(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       try { | ||||||
|  |         for (const auto& entry : | ||||||
|  |              std::filesystem::directory_iterator(selected_current_file_path_)) { | ||||||
|  |           std::string name = entry.path().filename().string(); | ||||||
|  |           if (entry.is_directory()) { | ||||||
|  |             if (ImGui::Selectable(name.c_str())) { | ||||||
|  |               selected_current_file_path_ = entry.path().string(); | ||||||
|  |               selected_file_.clear(); | ||||||
|  |             } | ||||||
|  |           } else { | ||||||
|  |             if (ImGui::Selectable(name.c_str())) { | ||||||
|  |               selected_file_ = entry.path().string(); | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } catch (const std::exception& e) { | ||||||
|  |         ImGui::TextColored(ImVec4(1, 0, 0, 1), "Error: %s", e.what()); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ImGui::EndCombo(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int Render::SelfHostedServerWindow() { | ||||||
|  |   if (show_self_hosted_server_config_window_) { | ||||||
|  |     if (self_hosted_server_config_window_pos_reset_) { | ||||||
|  |       const ImGuiViewport* viewport = ImGui::GetMainViewport(); | ||||||
|  |       if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |         ImGui::SetNextWindowPos( | ||||||
|  |             ImVec2((viewport->WorkSize.x - viewport->WorkPos.x - | ||||||
|  |                     SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN) / | ||||||
|  |                        2, | ||||||
|  |                    (viewport->WorkSize.y - viewport->WorkPos.y - | ||||||
|  |                     SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN) / | ||||||
|  |                        2)); | ||||||
|  |  | ||||||
|  |         ImGui::SetNextWindowSize( | ||||||
|  |             ImVec2(SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN, | ||||||
|  |                    SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN)); | ||||||
|  |       } else { | ||||||
|  |         ImGui::SetNextWindowPos( | ||||||
|  |             ImVec2((viewport->WorkSize.x - viewport->WorkPos.x - | ||||||
|  |                     SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN) / | ||||||
|  |                        2, | ||||||
|  |                    (viewport->WorkSize.y - viewport->WorkPos.y - | ||||||
|  |                     SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN) / | ||||||
|  |                        2)); | ||||||
|  |  | ||||||
|  |         ImGui::SetNextWindowSize( | ||||||
|  |             ImVec2(SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN, | ||||||
|  |                    SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_EN)); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       self_hosted_server_config_window_pos_reset_ = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Settings | ||||||
|  |     { | ||||||
|  |       static int settings_items_padding = 30; | ||||||
|  |       int settings_items_offset = 0; | ||||||
|  |  | ||||||
|  |       ImGui::SetWindowFontScale(0.5f); | ||||||
|  |       ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||||
|  |       ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 5.0f); | ||||||
|  |       ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); | ||||||
|  |  | ||||||
|  |       ImGui::Begin(localization::self_hosted_server_settings | ||||||
|  |                        [localization_language_index_] | ||||||
|  |                            .c_str(), | ||||||
|  |                    nullptr, | ||||||
|  |                    ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | | ||||||
|  |                        ImGuiWindowFlags_NoSavedSettings); | ||||||
|  |       ImGui::SetWindowFontScale(1.0f); | ||||||
|  |       ImGui::SetWindowFontScale(0.5f); | ||||||
|  |       ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); | ||||||
|  |       { | ||||||
|  |         settings_items_offset += settings_items_padding; | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
|  |         ImGui::Text("%s", localization::self_hosted_server_address | ||||||
|  |                               [localization_language_index_] | ||||||
|  |                                   .c_str()); | ||||||
|  |         if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_CN); | ||||||
|  |         } else { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_HOST_INPUT_BOX_PADDING_EN); | ||||||
|  |         } | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset); | ||||||
|  |         ImGui::SetNextItemWidth(SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH); | ||||||
|  |  | ||||||
|  |         ImGui::InputText("##signal_server_ip_tmp_", signal_server_ip_tmp_, | ||||||
|  |                          IM_ARRAYSIZE(signal_server_ip_tmp_), | ||||||
|  |                          ImGuiInputTextFlags_AlwaysOverwrite); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ImGui::Separator(); | ||||||
|  |  | ||||||
|  |       { | ||||||
|  |         settings_items_offset += settings_items_padding; | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
|  |         ImGui::Text( | ||||||
|  |             "%s", | ||||||
|  |             localization::self_hosted_server_port[localization_language_index_] | ||||||
|  |                 .c_str()); | ||||||
|  |  | ||||||
|  |         if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN); | ||||||
|  |         } else { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN); | ||||||
|  |         } | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset); | ||||||
|  |         ImGui::SetNextItemWidth(SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH); | ||||||
|  |  | ||||||
|  |         ImGui::InputText("##signal_server_port_tmp_", signal_server_port_tmp_, | ||||||
|  |                          IM_ARRAYSIZE(signal_server_port_tmp_)); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ImGui::Separator(); | ||||||
|  |  | ||||||
|  |       { | ||||||
|  |         settings_items_offset += settings_items_padding; | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset + 2); | ||||||
|  |         ImGui::Text("%s", localization::self_hosted_server_certificate_path | ||||||
|  |                               [localization_language_index_] | ||||||
|  |                                   .c_str()); | ||||||
|  |  | ||||||
|  |         if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_CN); | ||||||
|  |         } else { | ||||||
|  |           ImGui::SetCursorPosX(SELF_HOSTED_SERVER_PORT_INPUT_BOX_PADDING_EN); | ||||||
|  |         } | ||||||
|  |         ImGui::SetCursorPosY(settings_items_offset); | ||||||
|  |         ImGui::SetNextItemWidth(SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH); | ||||||
|  |  | ||||||
|  |         ShowSimpleFileBrowser(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (stream_window_inited_) { | ||||||
|  |         ImGui::EndDisabled(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { | ||||||
|  |         ImGui::SetCursorPosX(SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_CN); | ||||||
|  |       } else { | ||||||
|  |         ImGui::SetCursorPosX(SELF_HOSTED_SERVER_CONFIG_OK_BUTTON_PADDING_EN); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       settings_items_offset += settings_items_padding + 10; | ||||||
|  |       ImGui::SetCursorPosY(settings_items_offset); | ||||||
|  |       ImGui::PopStyleVar(); | ||||||
|  |  | ||||||
|  |       // OK | ||||||
|  |       if (ImGui::Button( | ||||||
|  |               localization::ok[localization_language_index_].c_str())) { | ||||||
|  |         show_self_hosted_server_config_window_ = false; | ||||||
|  |  | ||||||
|  |         config_center_->SetServerHost(signal_server_ip_tmp_); | ||||||
|  |         config_center_->SetServerPort(atoi(signal_server_port_tmp_)); | ||||||
|  |         config_center_->SetCertFilePath(selected_file_); | ||||||
|  |         strncpy(signal_server_ip_, signal_server_ip_tmp_, | ||||||
|  |                 sizeof(signal_server_ip_) - 1); | ||||||
|  |         signal_server_ip_[sizeof(signal_server_ip_) - 1] = '\0'; | ||||||
|  |         strncpy(signal_server_port_, signal_server_port_tmp_, | ||||||
|  |                 sizeof(signal_server_port_) - 1); | ||||||
|  |         signal_server_port_[sizeof(signal_server_port_) - 1] = '\0'; | ||||||
|  |         strncpy(cert_file_path_, selected_file_.c_str(), | ||||||
|  |                 sizeof(cert_file_path_) - 1); | ||||||
|  |         cert_file_path_[sizeof(cert_file_path_) - 1] = '\0'; | ||||||
|  |  | ||||||
|  |         self_hosted_server_config_window_pos_reset_ = true; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ImGui::SameLine(); | ||||||
|  |       // Cancel | ||||||
|  |       if (ImGui::Button( | ||||||
|  |               localization::cancel[localization_language_index_].c_str())) { | ||||||
|  |         show_self_hosted_server_config_window_ = false; | ||||||
|  |         self_hosted_server_config_window_pos_reset_ = true; | ||||||
|  |  | ||||||
|  |         strncpy(signal_server_ip_tmp_, signal_server_ip_, | ||||||
|  |                 sizeof(signal_server_ip_tmp_) - 1); | ||||||
|  |         signal_server_ip_tmp_[sizeof(signal_server_ip_tmp_) - 1] = '\0'; | ||||||
|  |         strncpy(signal_server_port_tmp_, signal_server_port_, | ||||||
|  |                 sizeof(signal_server_port_tmp_) - 1); | ||||||
|  |         signal_server_port_tmp_[sizeof(signal_server_port_tmp_) - 1] = '\0'; | ||||||
|  |         config_center_->SetServerHost(signal_server_ip_tmp_); | ||||||
|  |         config_center_->SetServerPort(atoi(signal_server_port_tmp_)); | ||||||
|  |         selected_file_.clear(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ImGui::SetWindowFontScale(1.0f); | ||||||
|  |       ImGui::SetWindowFontScale(0.5f); | ||||||
|  |       ImGui::End(); | ||||||
|  |       ImGui::PopStyleVar(2); | ||||||
|  |       ImGui::PopStyleColor(); | ||||||
|  |       ImGui::SetWindowFontScale(1.0f); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| /* |  | ||||||
|  * @Author: DI JUNKUN |  | ||||||
|  * @Date: 2024-06-14 |  | ||||||
|  * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef _LAYOUT_STYLE_H_ |  | ||||||
| #define _LAYOUT_STYLE_H_ |  | ||||||
|  |  | ||||||
| #define MENU_WINDOW_WIDTH_CN 300 |  | ||||||
| #define MENU_WINDOW_HEIGHT_CN 280 |  | ||||||
| #define LOCAL_WINDOW_WIDTH_CN 300 |  | ||||||
| #define LOCAL_WINDOW_HEIGHT_CN 280 |  | ||||||
| #define REMOTE_WINDOW_WIDTH_CN 300 |  | ||||||
| #define REMOTE_WINDOW_HEIGHT_CN 280 |  | ||||||
| #define MENU_WINDOW_WIDTH_EN 190 |  | ||||||
| #define MENU_WINDOW_HEIGHT_EN 245 |  | ||||||
| #define IPUT_WINDOW_WIDTH 160 |  | ||||||
| #define INPUT_WINDOW_PADDING_CN 66 |  | ||||||
| #define INPUT_WINDOW_PADDING_EN 96 |  | ||||||
| #define SETTINGS_WINDOW_WIDTH_CN 182 |  | ||||||
| #define SETTINGS_WINDOW_WIDTH_EN 248 |  | ||||||
| #define SETTINGS_WINDOW_HEIGHT_CN 275 |  | ||||||
| #define SETTINGS_WINDOW_HEIGHT_EN 275 |  | ||||||
| #define LANGUAGE_SELECT_WINDOW_PADDING_CN 100 |  | ||||||
| #define LANGUAGE_SELECT_WINDOW_PADDING_EN 167 |  | ||||||
| #define VIDEO_QUALITY_SELECT_WINDOW_PADDING_CN 100 |  | ||||||
| #define VIDEO_QUALITY_SELECT_WINDOW_PADDING_EN 167 |  | ||||||
| #define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_CN 100 |  | ||||||
| #define VIDEO_FRAME_RATE_SELECT_WINDOW_PADDING_EN 167 |  | ||||||
| #define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_CN 100 |  | ||||||
| #define VIDEO_ENCODE_FORMAT_SELECT_WINDOW_PADDING_EN 167 |  | ||||||
| #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_CN 151 |  | ||||||
| #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218 |  | ||||||
| #define ENABLE_TURN_CHECKBOX_PADDING_CN 151 |  | ||||||
| #define ENABLE_TURN_CHECKBOX_PADDING_EN 218 |  | ||||||
| #define ENABLE_SRTP_CHECKBOX_PADDING_CN 151 |  | ||||||
| #define ENABLE_SRTP_CHECKBOX_PADDING_EN 218 |  | ||||||
| #define SETTINGS_SELECT_WINDOW_WIDTH 73 |  | ||||||
| #define SETTINGS_OK_BUTTON_PADDING_CN 55 |  | ||||||
| #define SETTINGS_OK_BUTTON_PADDING_EN 78 |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
							
								
								
									
										2
									
								
								thirdparty/minirtc
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								thirdparty/minirtc
									
									
									
									
										vendored
									
									
								
							 Submodule thirdparty/minirtc updated: dd3f6df18b...b8b54613fa
									
								
							
							
								
								
									
										34
									
								
								xmake.lua
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								xmake.lua
									
									
									
									
									
								
							| @@ -120,26 +120,38 @@ target("device_controller") | |||||||
|          "src/device_controller/keyboard/linux", {public = true}) |          "src/device_controller/keyboard/linux", {public = true}) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | target("thumbnail") | ||||||
|  |     set_kind("object") | ||||||
|  |     add_packages("libyuv", "openssl3") | ||||||
|  |     add_deps("rd_log", "common") | ||||||
|  |     add_files("src/thumbnail/*.cpp") | ||||||
|  |     add_includedirs("src/thumbnail", {public = true}) | ||||||
|  |  | ||||||
| target("config_center") | target("config_center") | ||||||
|     set_kind("object") |     set_kind("object") | ||||||
|     add_deps("rd_log") |     add_deps("rd_log") | ||||||
|     add_files("src/config_center/*.cpp") |     add_files("src/config_center/*.cpp") | ||||||
|     add_includedirs("src/config_center", {public = true}) |     add_includedirs("src/config_center", {public = true}) | ||||||
|  |  | ||||||
| target("localization") | target("assets") | ||||||
|     set_kind("headeronly") |     set_kind("headeronly") | ||||||
|     add_includedirs("src/localization", {public = true}) |     add_includedirs("src/gui/assets/localization",  | ||||||
|  |         "src/gui/assets/fonts",  | ||||||
|  |         "src/gui/assets/icons", | ||||||
|  |         "src/gui/assets/layouts", {public = true}) | ||||||
|  |  | ||||||
| target("single_window") | target("gui") | ||||||
|     set_kind("object") |     set_kind("object") | ||||||
|     add_packages("libyuv", "openssl3") |     add_packages("libyuv") | ||||||
|     add_deps("rd_log", "common", "localization", "config_center", "minirtc",  |     add_deps("rd_log", "common", "assets", "config_center", "minirtc",  | ||||||
|         "path_manager", "screen_capturer", "speaker_capturer", "device_controller") |         "path_manager", "screen_capturer", "speaker_capturer",  | ||||||
|     add_files("src/single_window/*.cpp") |         "device_controller", "thumbnail") | ||||||
|     add_includedirs("src/single_window", {public = true}) |     add_files("src/gui/*.cpp", "src/gui/panels/*.cpp", "src/gui/toolbars/*.cpp",  | ||||||
|     add_includedirs("fonts", {public = true}) |         "src/gui/windows/*.cpp") | ||||||
|  |     add_includedirs("src/gui", "src/gui/panels", "src/gui/toolbars",  | ||||||
|  |         "src/gui/windows", {public = true}) | ||||||
|  |  | ||||||
| target("crossdesk") | target("crossdesk") | ||||||
|     set_kind("binary") |     set_kind("binary") | ||||||
|     add_deps("rd_log", "common", "single_window") |     add_deps("rd_log", "common", "gui") | ||||||
|     add_files("src/gui/main.cpp") |     add_files("src/app/main.cpp") | ||||||
		Reference in New Issue
	
	Block a user