Compare commits
16 Commits
KASM-1810_
...
feature/KA
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
152821d77b | ||
|
|
906fcc3e67 | ||
|
|
ab32cbc53e | ||
|
|
a48811b12f | ||
|
|
4c4808d2bd | ||
|
|
e282851073 | ||
|
|
40d263368d | ||
|
|
377d3e5629 | ||
|
|
5b516e84d9 | ||
|
|
43c31d759b | ||
|
|
aa7d1b5a30 | ||
|
|
8b5600e8f3 | ||
|
|
bbd971e9f1 | ||
|
|
0467e938a2 | ||
|
|
01623eaffd | ||
|
|
3383ad52e4 |
@@ -1,33 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
is_kasmvnc() {
|
|
||||||
local package="$1";
|
|
||||||
|
|
||||||
echo "$package" | grep -q 'kasmvncserver_'
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepare_upload_filename() {
|
function prepare_upload_filename() {
|
||||||
local package="$1";
|
local package="$1";
|
||||||
|
|
||||||
if ! is_kasmvnc "$package"; then
|
|
||||||
export upload_filename="$package"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
.ci/detect_os_arch_package_format "$package" > /tmp/os_arch_package_format;
|
.ci/detect_os_arch_package_format "$package" > /tmp/os_arch_package_format;
|
||||||
source /tmp/os_arch_package_format;
|
source /tmp/os_arch_package_format;
|
||||||
detect_release_branch
|
detect_release_branch
|
||||||
|
|
||||||
detect_revision "$package" "$OS_ARCH"
|
|
||||||
if [ -n "$REVISION" ]; then
|
|
||||||
REVISION="_${REVISION}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$RELEASE_BRANCH" ]; then
|
if [ -n "$RELEASE_BRANCH" ]; then
|
||||||
export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}${REVISION}_${OS_ARCH}.${PACKAGE_FORMAT}";
|
export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}_${OS_ARCH}.${PACKAGE_FORMAT}";
|
||||||
else
|
else
|
||||||
export SANITIZED_BRANCH="$(echo $CI_COMMIT_REF_NAME | sed 's/\//_/g')";
|
export SANITIZED_BRANCH="$(echo $CI_COMMIT_REF_NAME | sed 's/\//_/g')";
|
||||||
export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}_${SANITIZED_BRANCH}_${CI_COMMIT_SHA:0:6}${REVISION}_${OS_ARCH}.${PACKAGE_FORMAT}";
|
export upload_filename="kasmvncserver_${PACKAGE_OS}_${RELEASE_VERSION}_${SANITIZED_BRANCH}_${CI_COMMIT_SHA:0:6}_${OS_ARCH}.${PACKAGE_FORMAT}";
|
||||||
fi
|
fi
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,7 +25,6 @@ function upload_to_s3() {
|
|||||||
export BUILD_STATUS="{\"key\":\"doc\", \"state\":\"SUCCESSFUL\", \"name\":\"${upload_filename}\", \"url\":\"${S3_URL}\"}";
|
export BUILD_STATUS="{\"key\":\"doc\", \"state\":\"SUCCESSFUL\", \"name\":\"${upload_filename}\", \"url\":\"${S3_URL}\"}";
|
||||||
curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=build-url&target_url=${S3_URL}";
|
curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=build-url&target_url=${S3_URL}";
|
||||||
};
|
};
|
||||||
|
|
||||||
function prepare_to_run_scripts_and_s3_uploads() {
|
function prepare_to_run_scripts_and_s3_uploads() {
|
||||||
export DEBIAN_FRONTEND=noninteractive;
|
export DEBIAN_FRONTEND=noninteractive;
|
||||||
apt-get update;
|
apt-get update;
|
||||||
@@ -56,16 +38,3 @@ detect_release_branch() {
|
|||||||
export RELEASE_BRANCH=1;
|
export RELEASE_BRANCH=1;
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
detect_revision() {
|
|
||||||
local package="$1"
|
|
||||||
local arch="$2"
|
|
||||||
|
|
||||||
REVISION=
|
|
||||||
|
|
||||||
if ! echo "$package" | grep -q '+'; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
REVISION=$(echo "$package" | sed "s/_${arch}.\+//" | sed 's/.\++//')
|
|
||||||
}
|
|
||||||
|
|||||||
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
builder/build
|
||||||
135
.gitlab-ci.yml
135
.gitlab-ci.yml
@@ -8,45 +8,24 @@ variables:
|
|||||||
GIT_FETCH_EXTRA_FLAGS: --tags
|
GIT_FETCH_EXTRA_FLAGS: --tags
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- www
|
|
||||||
- build
|
- build
|
||||||
- upload
|
- upload
|
||||||
|
|
||||||
.prepare_build: &prepare_build
|
.prepare_build: &prepare_build
|
||||||
|
- ls -l
|
||||||
- pwd
|
- pwd
|
||||||
- apk add bash
|
- apk add bash
|
||||||
- mkdir -p "$GITLAB_SHARED_DIND_DIR" && chmod 777 "$GITLAB_SHARED_DIND_DIR"
|
- mkdir -p "$GITLAB_SHARED_DIND_DIR" && chmod 777 "$GITLAB_SHARED_DIND_DIR"
|
||||||
|
|
||||||
.prepare_www: &prepare_www
|
|
||||||
- tar -zxf output/www/kasm_www.tar.gz -C builder/
|
|
||||||
|
|
||||||
.prepare_artfacts: &prepare_artfacts
|
.prepare_artfacts: &prepare_artfacts
|
||||||
|
- mkdir output
|
||||||
- cp -r builder/build/* output/
|
- cp -r builder/build/* output/
|
||||||
- rm output/*.tar.gz
|
- rm output/*.tar.gz
|
||||||
|
|
||||||
build_www:
|
|
||||||
stage: www
|
|
||||||
allow_failure: false
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
script:
|
|
||||||
- webpacked_www=$PWD/builder/www
|
|
||||||
- src_www=kasmweb
|
|
||||||
- docker build -t kasmweb/www -f builder/dockerfile.www.build .
|
|
||||||
- docker run --rm -v $PWD/builder/www:/build kasmweb/www:latest
|
|
||||||
- mkdir -p output/www
|
|
||||||
- cd builder
|
|
||||||
- tar -zcvf ../output/www/kasm_www.tar.gz www
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_ubuntu_bionic:
|
build_ubuntu_bionic:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
@@ -55,150 +34,46 @@ build_ubuntu_bionic:
|
|||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
build_ubuntu_bionic_arm:
|
|
||||||
stage: build
|
|
||||||
allow_failure: false
|
|
||||||
tags:
|
|
||||||
- arm
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
|
||||||
- *prepare_artfacts
|
|
||||||
script:
|
|
||||||
- bash builder/build-package ubuntu bionic
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_ubuntu_bionic_libjpeg_turbo:
|
|
||||||
stage: build
|
|
||||||
allow_failure: false
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
|
||||||
- *prepare_artfacts
|
|
||||||
script:
|
|
||||||
- bash builder/build-package ubuntu bionic +libjpeg-turbo_latest
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_ubuntu_focal:
|
build_ubuntu_focal:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
- bash builder/build-package ubuntu focal;
|
- bash builder/build-package ubuntu focal;
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [Cc][Ii]\]/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_ubuntu_focal_arm:
|
|
||||||
stage: build
|
|
||||||
allow_failure: true
|
|
||||||
tags:
|
|
||||||
- arm
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
|
||||||
- *prepare_artfacts
|
|
||||||
script:
|
|
||||||
- bash builder/build-package ubuntu focal;
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [Cc][Ii]\]/
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
build_debian_buster:
|
build_debian_buster:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
- bash builder/build-package debian buster;
|
- bash builder/build-package debian buster;
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [cC][Ii]\]/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_debian_buster_arm:
|
|
||||||
stage: build
|
|
||||||
allow_failure: true
|
|
||||||
tags:
|
|
||||||
- arm
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
|
||||||
- *prepare_artfacts
|
|
||||||
script:
|
|
||||||
- bash builder/build-package debian buster;
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [cC][Ii]\]/
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
build_debian_bullseye:
|
build_debian_bullseye:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
- bash builder/build-package debian bullseye;
|
- bash builder/build-package debian bullseye;
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [cC][Ii]\]/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- output/
|
|
||||||
|
|
||||||
build_debian_bullseye_arm:
|
|
||||||
stage: build
|
|
||||||
allow_failure: true
|
|
||||||
tags:
|
|
||||||
- arm
|
|
||||||
before_script:
|
|
||||||
- *prepare_build
|
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
|
||||||
- *prepare_artfacts
|
|
||||||
script:
|
|
||||||
- bash builder/build-package debian bullseye;
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $CI_COMMIT_MESSAGE =~ /\[full [cC][Ii]\]/
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- output/
|
- output/
|
||||||
|
|
||||||
build_kali_rolling:
|
build_kali_rolling:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
@@ -209,10 +84,8 @@ build_kali_rolling:
|
|||||||
|
|
||||||
build_centos7:
|
build_centos7:
|
||||||
stage: build
|
stage: build
|
||||||
allow_failure: true
|
|
||||||
before_script:
|
before_script:
|
||||||
- *prepare_build
|
- *prepare_build
|
||||||
- *prepare_www
|
|
||||||
after_script:
|
after_script:
|
||||||
- *prepare_artfacts
|
- *prepare_artfacts
|
||||||
script:
|
script:
|
||||||
@@ -230,11 +103,9 @@ upload:
|
|||||||
- export S3_BUILD_DIRECTORY="kasmvnc/${CI_COMMIT_SHA}"
|
- export S3_BUILD_DIRECTORY="kasmvnc/${CI_COMMIT_SHA}"
|
||||||
- prepare_to_run_scripts_and_s3_uploads
|
- prepare_to_run_scripts_and_s3_uploads
|
||||||
- export RELEASE_VERSION=$(.ci/next_release_version "$CI_COMMIT_REF_NAME")
|
- export RELEASE_VERSION=$(.ci/next_release_version "$CI_COMMIT_REF_NAME")
|
||||||
- for package in `find output/ -type f -name '*.deb' -or -name '*.rpm'`; do
|
- for package in `find output/ -type f -name 'kasmvncserver_*.deb' -or -name '*.rpm'`; do
|
||||||
prepare_upload_filename "$package";
|
prepare_upload_filename "$package";
|
||||||
echo;
|
echo;
|
||||||
echo "File to upload $upload_filename";
|
echo "File to upload $upload_filename";
|
||||||
upload_to_s3 "$package" "$upload_filename";
|
upload_to_s3 "$package" "$upload_filename";
|
||||||
UPLOAD_NAME=$(echo $upload_filename | sed 's#kasmvncserver_##' | sed -r 's#_([0-9]{1,3}\.){2}[0-9]{1,2}_\S+?([a-f0-9]{6})##' | sed -r 's#\.(deb|rpm)##');
|
|
||||||
curl --request POST --header "PRIVATE-TOKEN:${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/statuses/${CI_COMMIT_SHA}?state=success&name=${UPLOAD_NAME}&target_url=${S3_URL}";
|
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ include(CheckLibraryExists)
|
|||||||
include(CheckTypeSize)
|
include(CheckTypeSize)
|
||||||
include(CheckCSourceCompiles)
|
include(CheckCSourceCompiles)
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
include(CheckCSourceRuns)
|
include(CheckCSourceRuns)
|
||||||
|
|
||||||
include(CMakeMacroLibtoolFile)
|
include(CMakeMacroLibtoolFile)
|
||||||
@@ -209,9 +208,6 @@ if(ENABLE_PAM)
|
|||||||
endif()
|
endif()
|
||||||
set(HAVE_PAM ${ENABLE_PAM})
|
set(HAVE_PAM ${ENABLE_PAM})
|
||||||
|
|
||||||
# Check for SSE2
|
|
||||||
check_cxx_compiler_flag(-msse2 COMPILER_SUPPORTS_SSE2)
|
|
||||||
|
|
||||||
# Generate config.h and make sure the source finds it
|
# Generate config.h and make sure the source finds it
|
||||||
configure_file(config.h.in config.h)
|
configure_file(config.h.in config.h)
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
|
|||||||
15
Pipfile
15
Pipfile
@@ -1,15 +0,0 @@
|
|||||||
[[source]]
|
|
||||||
url = "https://pypi.python.org/simple"
|
|
||||||
verify_ssl = true
|
|
||||||
name = "pypi"
|
|
||||||
|
|
||||||
[packages]
|
|
||||||
mamba = "*"
|
|
||||||
expects = "*"
|
|
||||||
"path.py" = "*"
|
|
||||||
pexpect = "*"
|
|
||||||
|
|
||||||
[dev-packages]
|
|
||||||
|
|
||||||
[requires]
|
|
||||||
python_version = "3.8"
|
|
||||||
136
Pipfile.lock
generated
136
Pipfile.lock
generated
@@ -1,136 +0,0 @@
|
|||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"hash": {
|
|
||||||
"sha256": "6745d5e5d90e44a18d73a0e23bc3d3e68acb950af0b87df50b45272d25b9e615"
|
|
||||||
},
|
|
||||||
"pipfile-spec": 6,
|
|
||||||
"requires": {
|
|
||||||
"python_version": "3.8"
|
|
||||||
},
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"name": "pypi",
|
|
||||||
"url": "https://pypi.python.org/simple",
|
|
||||||
"verify_ssl": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"args": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:a785b8d837625e9b61c39108532d95b85274acd679693b71ebb5156848fcf814"
|
|
||||||
],
|
|
||||||
"version": "==0.1.0"
|
|
||||||
},
|
|
||||||
"clint": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:05224c32b1075563d0b16d0015faaf9da43aa214e4a2140e51f08789e7a4c5aa"
|
|
||||||
],
|
|
||||||
"version": "==0.5.1"
|
|
||||||
},
|
|
||||||
"coverage": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c",
|
|
||||||
"sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6",
|
|
||||||
"sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45",
|
|
||||||
"sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a",
|
|
||||||
"sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03",
|
|
||||||
"sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529",
|
|
||||||
"sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a",
|
|
||||||
"sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a",
|
|
||||||
"sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2",
|
|
||||||
"sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6",
|
|
||||||
"sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759",
|
|
||||||
"sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53",
|
|
||||||
"sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a",
|
|
||||||
"sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4",
|
|
||||||
"sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff",
|
|
||||||
"sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502",
|
|
||||||
"sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793",
|
|
||||||
"sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb",
|
|
||||||
"sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905",
|
|
||||||
"sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821",
|
|
||||||
"sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b",
|
|
||||||
"sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81",
|
|
||||||
"sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0",
|
|
||||||
"sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b",
|
|
||||||
"sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3",
|
|
||||||
"sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184",
|
|
||||||
"sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701",
|
|
||||||
"sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a",
|
|
||||||
"sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82",
|
|
||||||
"sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638",
|
|
||||||
"sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5",
|
|
||||||
"sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083",
|
|
||||||
"sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6",
|
|
||||||
"sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90",
|
|
||||||
"sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465",
|
|
||||||
"sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a",
|
|
||||||
"sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3",
|
|
||||||
"sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e",
|
|
||||||
"sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066",
|
|
||||||
"sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf",
|
|
||||||
"sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b",
|
|
||||||
"sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae",
|
|
||||||
"sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669",
|
|
||||||
"sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873",
|
|
||||||
"sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b",
|
|
||||||
"sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6",
|
|
||||||
"sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb",
|
|
||||||
"sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160",
|
|
||||||
"sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c",
|
|
||||||
"sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079",
|
|
||||||
"sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d",
|
|
||||||
"sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
|
||||||
"version": "==5.5"
|
|
||||||
},
|
|
||||||
"expects": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:419902ccafe81b7e9559eeb6b7a07ef9d5c5604eddb93000f0642b3b2d594f4c"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==0.9.0"
|
|
||||||
},
|
|
||||||
"mamba": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:75cfc6dfd287dcccaf86dd753cf48e0a7337487c7c3fafda05a6a67ded6da496"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==0.11.2"
|
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:2de925e8d421f93bcea80d511b81accfb6a7e6b249afa4a5559557b0cf817097",
|
|
||||||
"sha256:340054c5bb459fc9fd40e7eb6768c5989f3e599d18224238465b5333bc8faa7d"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.6'",
|
|
||||||
"version": "==16.2.0"
|
|
||||||
},
|
|
||||||
"path.py": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:8d885e8b2497aed005703d94e0fd97943401f035e42a136810308bff034529a8",
|
|
||||||
"sha256:a43e82eb2c344c3fd0b9d6352f6b856f40b8b7d3d65cc05978b42c3715668496"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==12.5.0"
|
|
||||||
},
|
|
||||||
"pexpect": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
|
|
||||||
"sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==4.8.0"
|
|
||||||
},
|
|
||||||
"ptyprocess": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35",
|
|
||||||
"sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"
|
|
||||||
],
|
|
||||||
"version": "==0.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"develop": {}
|
|
||||||
}
|
|
||||||
36
README.md
36
README.md
@@ -42,30 +42,30 @@ Future Goals:
|
|||||||
#### Debian-based
|
#### Debian-based
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
wget https://github.com/kasmtech/KasmVNC/releases/download/v0.9.2-beta/kasmvncserver_ubuntu_bionic_0.9.2_amd64.deb
|
wget -qO- https://github.com/kasmtech/KasmVNC/releases/download/v0.9.1-beta/kasmvncserver_0.9.1~beta-1_amd64.deb
|
||||||
|
|
||||||
sudo apt-get install ./kasmvncserver_0.9.1~beta-1_amd64.deb
|
sudo dpkg -i kasmvncserver_0.9.1~beta-1_amd64.deb
|
||||||
|
sudo apt-get -f install
|
||||||
|
|
||||||
|
# We provide an example script to run KasmVNC at #
|
||||||
|
# /usr/share/doc/kasmvncserver/examples/kasmvncserver-easy-start. It runs a VNC
|
||||||
|
# server on display :10 and on interface 0.0.0.0. If you're happy with those
|
||||||
|
# defaults you can just use it as is:
|
||||||
|
sudo ln -s /usr/share/doc/kasmvncserver/examples/kasmvncserver-easy-start /usr/bin/
|
||||||
|
|
||||||
# Add your user to the ssl-cert group
|
# Add your user to the ssl-cert group
|
||||||
sudo addgroup $USER ssl-cert
|
sudo addgroup $USER ssl-cert
|
||||||
# You will need to re-connect in order to pick up the group change
|
# You will need to re-connect in order to pick up the group change
|
||||||
|
|
||||||
# Run KasmVNC on display :10 and on interface 0.0.0.0:
|
# Create ~/.vnc directory and corresponding files.
|
||||||
KASMVNC_OPTIONS=':10 -depth 24 -geometry 1280x1050
|
kasmvncserver-easy-start -d && kasmvncserver-easy-start -kill
|
||||||
-cert /etc/ssl/certs/ssl-cert-snakeoil.pem
|
|
||||||
-key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24
|
|
||||||
-interface 0.0.0.0 -httpd /usr/share/kasmvnc/www'
|
|
||||||
vncserver $KASMVNC_OPTIONS
|
|
||||||
|
|
||||||
# On the first run, vncserver will ask you to create a KasmVNC user and choose a desktop
|
# Modify vncstartup to launch your environment of choice, in this example LXDE
|
||||||
# environment you want to run. It can detect Cinnamon, Mate, LXDE, KDE, Gnome,
|
# This may be optional depending on your system configuration
|
||||||
# XFCE. You can also choose to manually edit xstartup.
|
echo '/usr/bin/lxsession -s LXDE &' >> ~/.vnc/xstartup
|
||||||
# After you chose a desktop environment or to manually edit xstartup,
|
|
||||||
# vncserver won't ask you again, unless you run it as:
|
|
||||||
vncserver $KASMVNC_OPTIONS -select-de
|
|
||||||
|
|
||||||
# You can select a specific Desktop Environment like this:
|
# Start KasmVNC with debug logging:
|
||||||
vncserver $KASMVNC_OPTIONS -select-de mate
|
kasmvncserver-easy-start -d
|
||||||
|
|
||||||
# Tail the logs
|
# Tail the logs
|
||||||
tail -f ~/.vnc/`hostname`:10.log
|
tail -f ~/.vnc/`hostname`:10.log
|
||||||
@@ -73,10 +73,10 @@ tail -f ~/.vnc/`hostname`:10.log
|
|||||||
|
|
||||||
Now navigate to your system at https://[ip-address]:8443/
|
Now navigate to your system at https://[ip-address]:8443/
|
||||||
|
|
||||||
To stop the KasmVNC you started earlier on display 10:
|
To stop a running KasmVNC:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
vncserver -kill :10
|
kasmvncserver-easy-start -kill
|
||||||
```
|
```
|
||||||
|
|
||||||
The options for vncserver:
|
The options for vncserver:
|
||||||
|
|||||||
@@ -3,17 +3,8 @@ Docker CE
|
|||||||
|
|
||||||
# Build a deb/rpm package
|
# Build a deb/rpm package
|
||||||
```
|
```
|
||||||
# builder/build-package <os> <os_codename> <build_tag>
|
# builder/build-package <os> <os_codename>
|
||||||
# os_codename is what "lsb_release -c" outputs, e.g. buster, focal.
|
# os_codename is what "lsb_release -c" outputs, e.g. buster, focal.
|
||||||
#
|
|
||||||
# build_tag allows building multiple versions of deb package (rpm not supported)
|
|
||||||
# targeting a single distro release (e.g. Ubuntu Bionic). If build_tag is given,
|
|
||||||
# the package name will include build_tag as part of Debian revision. For
|
|
||||||
# example:
|
|
||||||
# * with build_tag: kasmvncserver_0.9.1~beta-1+libjpeg-turbo-latest_amd64.deb
|
|
||||||
# * without build_tag: kasmvncserver_0.9.1~beta-1_amd64.deb
|
|
||||||
# You need to have .build and .deb.build for the build_tag.
|
|
||||||
#
|
|
||||||
# Packages will be placed under builder/build/
|
# Packages will be placed under builder/build/
|
||||||
|
|
||||||
builder/build-package ubuntu bionic
|
builder/build-package ubuntu bionic
|
||||||
@@ -79,63 +70,3 @@ packages installed with XFCE.
|
|||||||
```
|
```
|
||||||
builder/test-deb-barebones ubuntu focal
|
builder/test-deb-barebones ubuntu focal
|
||||||
```
|
```
|
||||||
|
|
||||||
# Preparing a release
|
|
||||||
|
|
||||||
Deb and rpm packages need their versions bumped to the new release version. It
|
|
||||||
can be done with:
|
|
||||||
|
|
||||||
```
|
|
||||||
builder/bump-package-version 0.9.4-beta
|
|
||||||
```
|
|
||||||
|
|
||||||
This will update corresponding package files, use `git diff` to see changes.
|
|
||||||
|
|
||||||
If you've ran the command and curious about Debian version specifics, here's an
|
|
||||||
explanation:
|
|
||||||
Deb version will be `0.9.4~beta-1`. `~` (and not `-`) is required by packaging
|
|
||||||
guidelines, and `-1` is Debian package revision for `0.9.4` upstream release. If
|
|
||||||
a Debian-specific patch was later added on top of `0.9.4`, it'd be `-2` for the
|
|
||||||
next Debian version. Rpm has a corresponding revision in its .spec file.
|
|
||||||
|
|
||||||
# CI development
|
|
||||||
|
|
||||||
S3 upload code is extracted to various files in `.ci`. It's possible to iterate
|
|
||||||
locally by doing stuff like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
bash -c '
|
|
||||||
. .ci/upload.sh;
|
|
||||||
prepare_upload_filename "bionic/kasmvncserver_0.9.1~beta-1+libjpeg-turbo-latest_amd64.deb";
|
|
||||||
echo $upload_filename;'
|
|
||||||
```
|
|
||||||
|
|
||||||
# ARM
|
|
||||||
|
|
||||||
KasmVNC is supported on ARM, however, the build process needs to be broken into two parts with one occuring on a x64 system and the other on an ARM system. All our testing and official builds are done on AWS Graviton instances.
|
|
||||||
|
|
||||||
### Build www code on x86 System
|
|
||||||
The www code is webpacked for performance and thus requires building. There are NPM packages, phantomjs, which do not have an ARM build. Therefore, this must be built on x86 and then copied over to the ARM system for final packaging.
|
|
||||||
|
|
||||||
```
|
|
||||||
cd ~/KasmVNC
|
|
||||||
mkdir builder/www
|
|
||||||
sudo docker build -t kasmweb/www -f builder/dockerfile.www.build .
|
|
||||||
sudo docker run --rm -v $PWD/builder/www:/build kasmweb/www:latest
|
|
||||||
cd builder
|
|
||||||
tar -zcvf /tmp/kasm_www.tar.gz www
|
|
||||||
```
|
|
||||||
|
|
||||||
Now transfer ```kasm_www.tar.gz``` to the ARM system.
|
|
||||||
|
|
||||||
### Build KasmVNC ARM
|
|
||||||
These instructions assume KasmVNC has been cloned at $HOME and ```kasm_www.tar.gz``` has been placed at $HOME as well, adjust for your environment.
|
|
||||||
|
|
||||||
```
|
|
||||||
cd ~
|
|
||||||
tar -zxf kasm_www.tar.gz -C KasmVNC/builder/
|
|
||||||
cd KasmVNC
|
|
||||||
sudo builder/build-package ubuntu bionic
|
|
||||||
```
|
|
||||||
The resulting deb package can be found under ~/KasmVNC/builder/build/bionic
|
|
||||||
Replace ```bionic``` with ```focal``` to build for Ubuntu 20.04LTS. At this time, only Ubuntu Bionic has been tested, however, other Debian based builds we support should also work.
|
|
||||||
|
|||||||
@@ -5,17 +5,12 @@ set -e
|
|||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
. builder/os_ver_cli.sh
|
. builder/os_ver_cli.sh
|
||||||
|
|
||||||
L_UID=$(id -u) #Ubuntu already has UID env var, but this should work on all Linix systems
|
docker build -t debbuilder_${os}:${os_codename} -f \
|
||||||
L_GID=$(id -g)
|
builder/dockerfile.${os}_${os_codename}.deb.build .
|
||||||
|
|
||||||
builder_image=debbuilder_${os}:${os_codename}${build_tag_for_images}
|
|
||||||
docker build --build-arg KASMVNC_PACKAGE_DIR="builder/build/${os_codename}" \
|
|
||||||
--build-arg L_UID="$L_UID" \
|
|
||||||
-t "$builder_image" -f \
|
|
||||||
builder/dockerfile.${os}_${os_codename}${build_tag}.deb.build .
|
|
||||||
|
|
||||||
deb_output_dir=$(cd .. && echo $PWD)
|
deb_output_dir=$(cd .. && echo $PWD)
|
||||||
docker run --rm -v "$deb_output_dir":/src -e BUILD_TAG="$build_tag" \
|
L_UID=$(id -u) #Ubuntu already has UID env var, but this should work on all Linix systems
|
||||||
--user "$L_UID:$L_GID" \
|
L_GID=$(id -g)
|
||||||
"$builder_image" /bin/bash -c \
|
docker run --rm -v "$deb_output_dir":/src --user $L_UID:$L_GID \
|
||||||
|
debbuilder_${os}:${os_codename} /bin/bash -c \
|
||||||
'/src/*/builder/build-deb-inside-docker'
|
'/src/*/builder/build-deb-inside-docker'
|
||||||
|
|||||||
@@ -2,31 +2,12 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
prepare_docker_copy_of_debian_dir_and_cd_to_id() {
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
local mounted_src_dir="$PWD"
|
|
||||||
local docker_src_dir="$HOME/src"
|
|
||||||
|
|
||||||
mkdir "$docker_src_dir"
|
|
||||||
cd "$docker_src_dir"
|
|
||||||
cp -a "$mounted_src_dir/debian/" .
|
|
||||||
ln -s "$mounted_src_dir/builder" .
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_docker_copy_of_debian_dir_and_cd_to_id
|
|
||||||
|
|
||||||
os=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
|
os=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
|
||||||
os_codename=$(lsb_release -cs)
|
os_codename=$(lsb_release -cs)
|
||||||
os_dir="builder/build/${os_codename}"
|
os_dir="builder/build/${os_codename}"
|
||||||
|
|
||||||
if [ "$BUILD_TAG" = "+libjpeg-turbo_latest" ]; then
|
|
||||||
echo 'libjpeg 62 libjpeg-turbo (>= 2.1.1)' > debian/shlibs.local
|
|
||||||
|
|
||||||
debian_revision="$(echo $BUILD_TAG | tr _ -)"
|
|
||||||
sed -i -e "1 s/)/$debian_revision)/" debian/changelog
|
|
||||||
fi
|
|
||||||
|
|
||||||
dpkg-buildpackage -us -uc -b
|
dpkg-buildpackage -us -uc -b
|
||||||
mkdir -p "$os_dir"
|
mkdir -p "$os_dir"
|
||||||
cp ../*.deb "$os_dir"
|
cp ../*.deb "$os_dir"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ set -e
|
|||||||
|
|
||||||
os="$1"
|
os="$1"
|
||||||
codename="$2"
|
codename="$2"
|
||||||
build_tag="$3"
|
|
||||||
|
|
||||||
detect_package_format() {
|
detect_package_format() {
|
||||||
package_format=rpm
|
package_format=rpm
|
||||||
@@ -13,17 +12,8 @@ detect_package_format() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
warn_build_tag_not_supported_for_rpm_and_exit() {
|
|
||||||
if [[ "$build_tag" && "$package_format" = "rpm" ]]; then
|
|
||||||
echo >&2 "<build_tag> isn't supported for rpm"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
detect_package_format
|
detect_package_format
|
||||||
warn_build_tag_not_supported_for_rpm_and_exit
|
builder/build-tarball "$os" "$codename"
|
||||||
|
builder/build-${package_format} "$os" "$codename"
|
||||||
builder/build-tarball "$os" "$codename" "$build_tag"
|
|
||||||
builder/build-${package_format} "$os" "$codename" "$build_tag"
|
|
||||||
|
|||||||
@@ -2,18 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
warn_build_tag_not_supported_for_rpm_and_exit() {
|
|
||||||
local build_tag="$1"
|
|
||||||
|
|
||||||
if [[ -n "$build_tag" ]]; then
|
|
||||||
echo >&2 "<build_tag> isn't supported for rpm"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
. builder/os_ver_cli.sh
|
. builder/os_ver_cli.sh
|
||||||
warn_build_tag_not_supported_for_rpm_and_exit "$build_tag"
|
|
||||||
|
|
||||||
docker build -t kasmvnc_rpmbuilder_${os}:${os_codename} -f \
|
docker build -t kasmvnc_rpmbuilder_${os}:${os_codename} -f \
|
||||||
builder/dockerfile.${os}_${os_codename}.rpm.build .
|
builder/dockerfile.${os}_${os_codename}.rpm.build .
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
build_www_dir() {
|
build_www_dir() {
|
||||||
local webpacked_www=$PWD/builder/www
|
local webpacked_www=$PWD/builder/www
|
||||||
@@ -12,13 +13,6 @@ build_www_dir() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
move_libjpeg_turbo_to_os_specific_dir() {
|
|
||||||
chown $L_UID:$L_GID $shared_with_docker_dir/${os_codename}/*
|
|
||||||
mkdir -p $PWD/builder/build/${os_codename}/
|
|
||||||
mv $shared_with_docker_dir/${os_codename}/libjpeg-turbo*.deb \
|
|
||||||
$PWD/builder/build/${os_codename}/
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_with_docker_dir=${GITLAB_SHARED_DIND_DIR:-/tmp}
|
shared_with_docker_dir=${GITLAB_SHARED_DIND_DIR:-/tmp}
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
@@ -26,21 +20,13 @@ cd "$(dirname "$0")/.."
|
|||||||
|
|
||||||
build_www_dir
|
build_www_dir
|
||||||
|
|
||||||
builder_image=kasmvncbuilder:$os_codename${build_tag_for_images}
|
docker build -t kasmvncbuilder:$os_codename \
|
||||||
docker build -t "$builder_image" \
|
-f builder/dockerfile.${os}_${os_codename}.build .
|
||||||
-f builder/dockerfile.${os}_${os_codename}${build_tag}.build .
|
|
||||||
mkdir -p builder/build
|
mkdir -p builder/build
|
||||||
docker run -v $shared_with_docker_dir:/build -e BUILD_TAG="$build_tag" \
|
docker run -v $shared_with_docker_dir:/build --rm kasmvncbuilder:$os_codename
|
||||||
--rm "$builder_image"
|
|
||||||
|
|
||||||
L_GID=$(id -g)
|
L_GID=$(id -g)
|
||||||
L_UID=$(id -u)
|
L_UID=$(id -u)
|
||||||
tarball_name="kasmvnc.${os}_${os_codename}.tar.gz"
|
tarball_name="kasmvnc.${os}_${os_codename}.tar.gz"
|
||||||
tarball_name_with_build_tag="kasmvnc.${os}_${os_codename}${build_tag}.tar.gz"
|
|
||||||
chown $L_UID:$L_GID $shared_with_docker_dir/$tarball_name
|
chown $L_UID:$L_GID $shared_with_docker_dir/$tarball_name
|
||||||
mv $shared_with_docker_dir/$tarball_name \
|
mv $shared_with_docker_dir/$tarball_name $PWD/builder/build/
|
||||||
$PWD/builder/build/"$tarball_name_with_build_tag"
|
|
||||||
|
|
||||||
if [ "$build_tag" = "+libjpeg-turbo_latest" ]; then
|
|
||||||
move_libjpeg_turbo_to_os_specific_dir
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
detect_quilt() {
|
detect_quilt() {
|
||||||
if which quilt 1>/dev/null; then
|
if which quilt 1>/dev/null; then
|
||||||
QUILT_PRESENT=1
|
QUILT_PRESENT=1
|
||||||
@@ -17,7 +19,7 @@ cd /tmp
|
|||||||
# default to the version of x in Ubuntu 18.04, otherwise caller will need to specify
|
# default to the version of x in Ubuntu 18.04, otherwise caller will need to specify
|
||||||
XORG_VER=${XORG_VER:-"1.19.6"}
|
XORG_VER=${XORG_VER:-"1.19.6"}
|
||||||
XORG_PATCH=$(echo "$XORG_VER" | grep -Po '^\d.\d+' | sed 's#\.##')
|
XORG_PATCH=$(echo "$XORG_VER" | grep -Po '^\d.\d+' | sed 's#\.##')
|
||||||
wget --no-check-certificate https://www.x.org/archive/individual/xserver/xorg-server-${XORG_VER}.tar.bz2
|
wget https://www.x.org/archive/individual/xserver/xorg-server-${XORG_VER}.tar.bz2
|
||||||
|
|
||||||
#git clone https://kasmweb@bitbucket.org/kasmtech/kasmvnc.git
|
#git clone https://kasmweb@bitbucket.org/kasmtech/kasmvnc.git
|
||||||
#cd kasmvnc
|
#cd kasmvnc
|
||||||
@@ -30,19 +32,16 @@ sed -i -e '/find_package(FLTK/s@^@#@' \
|
|||||||
-e '/add_subdirectory(tests/s@^@#@' \
|
-e '/add_subdirectory(tests/s@^@#@' \
|
||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
|
||||||
cmake -D CMAKE_BUILD_TYPE=RelWithDebInfo . -DBUILD_VIEWER:BOOL=OFF
|
cmake -D CMAKE_BUILD_TYPE=RelWithDebInfo .
|
||||||
make -j5
|
make -j5
|
||||||
|
|
||||||
tar -C unix/xserver -xf /tmp/xorg-server-${XORG_VER}.tar.bz2 --strip-components=1
|
tar -C unix/xserver -xvf /tmp/xorg-server-${XORG_VER}.tar.bz2 --strip-components=1
|
||||||
|
|
||||||
cd unix/xserver
|
cd unix/xserver
|
||||||
patch -Np1 -i ../xserver${XORG_PATCH}.patch
|
patch -Np1 -i ../xserver${XORG_PATCH}.patch
|
||||||
case "$XORG_VER" in
|
if [[ $XORG_VER =~ ^1\.20\..*$ ]]; then
|
||||||
1.20.*)
|
|
||||||
if [ -f ../xserver120.7.patch ]; then
|
|
||||||
patch -Np1 -i ../xserver120.7.patch
|
patch -Np1 -i ../xserver120.7.patch
|
||||||
fi ;;
|
fi
|
||||||
esac
|
|
||||||
|
|
||||||
autoreconf -i
|
autoreconf -i
|
||||||
# Configuring Xorg is long and has many distro-specific paths.
|
# Configuring Xorg is long and has many distro-specific paths.
|
||||||
@@ -75,8 +74,6 @@ mkdir lib
|
|||||||
cd lib
|
cd lib
|
||||||
if [ -d /usr/lib/x86_64-linux-gnu/dri ]; then
|
if [ -d /usr/lib/x86_64-linux-gnu/dri ]; then
|
||||||
ln -s /usr/lib/x86_64-linux-gnu/dri dri
|
ln -s /usr/lib/x86_64-linux-gnu/dri dri
|
||||||
elif [ -d /usr/lib/aarch64-linux-gnu/dri ]; then
|
|
||||||
ln -s /usr/lib/aarch64-linux-gnu/dri dri
|
|
||||||
else
|
else
|
||||||
ln -s /usr/lib64/dri dri
|
ln -s /usr/lib64/dri dri
|
||||||
fi
|
fi
|
||||||
@@ -85,11 +82,9 @@ cd /src
|
|||||||
detect_quilt
|
detect_quilt
|
||||||
if [ -n "$QUILT_PRESENT" ]; then
|
if [ -n "$QUILT_PRESENT" ]; then
|
||||||
quilt push -a
|
quilt push -a
|
||||||
|
echo 'Patches applied!'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
make servertarball
|
make servertarball
|
||||||
|
|
||||||
cp kasmvnc*.tar.gz /build/kasmvnc.${KASMVNC_BUILD_OS}_${KASMVNC_BUILD_OS_CODENAME}.tar.gz
|
cp kasmvnc*.tar.gz /build/kasmvnc.${KASMVNC_BUILD_OS}_${KASMVNC_BUILD_OS_CODENAME}.tar.gz
|
||||||
if [ "$BUILD_TAG" = "+libjpeg-turbo_latest" ]; then
|
|
||||||
mkdir -p /build/${KASMVNC_BUILD_OS_CODENAME}/
|
|
||||||
cp /libjpeg-turbo/libjpeg*.deb /build/${KASMVNC_BUILD_OS_CODENAME}/
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
update_version_to_meet_packaging_standards() {
|
|
||||||
new_version=$(echo "$new_version" |
|
|
||||||
sed -e 's/\([0-9]\)-\([a-zA-Z]\)/\1~\2/')
|
|
||||||
}
|
|
||||||
|
|
||||||
add_debian_revision_to_new_version() {
|
|
||||||
echo "$new_version-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
bump_rpm() {
|
|
||||||
sed -i "s/^Version:.\+/Version: $new_version/" centos/kasmvncserver.spec
|
|
||||||
}
|
|
||||||
|
|
||||||
bump_deb() {
|
|
||||||
local image="debbump_package_version:dev"
|
|
||||||
local L_UID=$(id -u)
|
|
||||||
local L_GID=$(id -g)
|
|
||||||
local debian_version=$(add_debian_revision_to_new_version)
|
|
||||||
|
|
||||||
docker build -t "$image" -f builder/dockerfile.bump-package-version .
|
|
||||||
docker run --rm -v "$PWD":/src --user "$L_UID:$L_GID" \
|
|
||||||
"$image" /bin/bash -c \
|
|
||||||
"cd /src && builder/bump-package-version-inside-docker-deb $debian_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
new_version="$1"
|
|
||||||
|
|
||||||
if [[ -z "$new_version" ]]; then
|
|
||||||
echo >&2 "Usage: $(basename "$0") <new_version>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
|
||||||
|
|
||||||
update_version_to_meet_packaging_standards
|
|
||||||
bump_rpm
|
|
||||||
bump_deb
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
new_version="$1"
|
|
||||||
|
|
||||||
update_version() {
|
|
||||||
dch --newversion $new_version 'New upstream release.'
|
|
||||||
}
|
|
||||||
|
|
||||||
mark_as_released() {
|
|
||||||
dch --release ""
|
|
||||||
}
|
|
||||||
|
|
||||||
update_version
|
|
||||||
mark_as_released
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
FROM debian:buster
|
|
||||||
|
|
||||||
ENV DEBEMAIL="Kasm Technologies LLC <info@kasmweb.com>"
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get -y install vim devscripts
|
|
||||||
@@ -3,7 +3,6 @@ FROM centos:centos7
|
|||||||
ENV KASMVNC_BUILD_OS centos
|
ENV KASMVNC_BUILD_OS centos
|
||||||
ENV KASMVNC_BUILD_OS_CODENAME core
|
ENV KASMVNC_BUILD_OS_CODENAME core
|
||||||
|
|
||||||
RUN yum update -y ca-certificates
|
|
||||||
RUN yum install -y build-dep xorg-server libxfont-dev sudo
|
RUN yum install -y build-dep xorg-server libxfont-dev sudo
|
||||||
RUN yum install -y gcc cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN yum install -y gcc cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN yum install -y libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev openssl-devel
|
RUN yum install -y libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev openssl-devel
|
||||||
@@ -11,12 +10,13 @@ RUN yum install -y make
|
|||||||
RUN yum group install -y "Development Tools"
|
RUN yum group install -y "Development Tools"
|
||||||
RUN yum install -y xorg-x11-server-devel zlib-devel libjpeg-turbo-devel
|
RUN yum install -y xorg-x11-server-devel zlib-devel libjpeg-turbo-devel
|
||||||
RUN yum install -y libxkbfile-devel libXfont2-devel xorg-x11-font-utils \
|
RUN yum install -y libxkbfile-devel libXfont2-devel xorg-x11-font-utils \
|
||||||
xorg-x11-xtrans-devel xorg-x11-xkb-utils-devel
|
xorg-x11-xtrans-devel xorg-x11-xkb-utils-devel libXrandr-devel pam-devel \
|
||||||
|
gnutls-devel libX11-devel libXtst-devel libXcursor-devel
|
||||||
RUN yum install -y mesa-dri-drivers
|
RUN yum install -y mesa-dri-drivers
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ RUN yum install -y epel-release && yum groupinstall xfce -y
|
|||||||
RUN yum erase -y pm-utils xscreensaver*
|
RUN yum erase -y pm-utils xscreensaver*
|
||||||
RUN yum install -y redhat-lsb-core
|
RUN yum install -y redhat-lsb-core
|
||||||
RUN yum install -y vim less
|
RUN yum install -y vim less
|
||||||
RUN yum localinstall -y --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm
|
|
||||||
|
|
||||||
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ RUN apt-get update && \
|
|||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -9,11 +9,4 @@ RUN apt-get update && \
|
|||||||
COPY ./debian/control /tmp
|
COPY ./debian/control /tmp
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
ARG L_UID
|
USER 1000
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ COPY startup/ $STARTUPDIR
|
|||||||
### START CUSTOM STUFF ####
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
|
|
||||||
### END CUSTOM STUFF ###
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM debian:buster-slim
|
FROM debian:buster-slim
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; apt-get update && dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN apt-get update && dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
RUN apt-get update && apt-get -y install xterm
|
RUN apt-get update && apt-get -y install xterm
|
||||||
|
|
||||||
COPY startup/deb/kasmvncserver-easy-start /usr/local/bin
|
COPY startup/deb/kasmvncserver-easy-start /usr/local/bin
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ RUN apt-get update && \
|
|||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -9,11 +9,4 @@ RUN apt-get update && \
|
|||||||
COPY ./debian/control /tmp
|
COPY ./debian/control /tmp
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
ARG L_UID
|
USER 1000
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
|
|||||||
@@ -34,14 +34,6 @@ RUN apt-get purge -y pm-utils xscreensaver*
|
|||||||
RUN apt-get update && apt-get install -y vim less
|
RUN apt-get update && apt-get install -y vim less
|
||||||
RUN apt-get update && apt-get -y install lsb-release
|
RUN apt-get update && apt-get -y install lsb-release
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y task-cinnamon-desktop
|
|
||||||
RUN apt-get update && apt-get install -y task-gnome-desktop
|
|
||||||
RUN mkdir -p /usr/share/man/man1
|
|
||||||
RUN apt-get update && apt-get install -y apt-utils openjdk-11-jre
|
|
||||||
RUN apt-get update && apt-get install -y task-lxde-desktop
|
|
||||||
RUN apt-get update && apt-get install -y task-mate-desktop
|
|
||||||
RUN apt-get update && apt-get install -y task-kde-desktop
|
|
||||||
|
|
||||||
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
||||||
|
|
||||||
RUN mkdir -p $STARTUPDIR
|
RUN mkdir -p $STARTUPDIR
|
||||||
@@ -50,8 +42,8 @@ COPY startup/ $STARTUPDIR
|
|||||||
### START CUSTOM STUFF ####
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
|
|
||||||
### END CUSTOM STUFF ###
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ RUN dnf install -y make
|
|||||||
RUN dnf group install -y "Development Tools"
|
RUN dnf group install -y "Development Tools"
|
||||||
RUN dnf install -y xorg-x11-server-devel zlib-devel libjpeg-turbo-devel
|
RUN dnf install -y xorg-x11-server-devel zlib-devel libjpeg-turbo-devel
|
||||||
RUN dnf install -y libxkbfile-devel libXfont2-devel xorg-x11-font-utils \
|
RUN dnf install -y libxkbfile-devel libXfont2-devel xorg-x11-font-utils \
|
||||||
xorg-x11-xtrans-devel xorg-x11-xkb-utils-devel
|
xorg-x11-xtrans-devel xorg-x11-xkb-utils-devel libXrandr-devel libXcursor-devel
|
||||||
RUN dnf install -y mesa-dri-drivers
|
RUN dnf install -y mesa-dri-drivers
|
||||||
RUN dnf install -y bzip2 redhat-lsb-core
|
RUN dnf install -y bzip2 redhat-lsb-core
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ RUN apt-get update && \
|
|||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -9,11 +9,4 @@ RUN apt-get update && \
|
|||||||
COPY ./debian/control /tmp
|
COPY ./debian/control /tmp
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
ARG L_UID
|
USER 1000
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ COPY startup/ $STARTUPDIR
|
|||||||
### START CUSTOM STUFF ####
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
|
|
||||||
### END CUSTOM STUFF ###
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
FROM ubuntu:18.04
|
|
||||||
|
|
||||||
ENV KASMVNC_BUILD_OS ubuntu
|
|
||||||
ENV KASMVNC_BUILD_OS_CODENAME bionic
|
|
||||||
ENV XORG_VER 1.20.10
|
|
||||||
|
|
||||||
RUN sed -i 's$# deb-src$deb-src$' /etc/apt/sources.list
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get -y install sudo
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
|
||||||
RUN apt-get update && apt-get -y install cmake git libgnutls28-dev vim wget tightvncserver
|
|
||||||
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y cmake nasm gcc
|
|
||||||
RUN git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git
|
|
||||||
RUN export MAKEFLAGS=-j`nproc`; cd libjpeg-turbo && cmake -G"Unix Makefiles" && make deb
|
|
||||||
RUN export MAKEFLAGS=-j`nproc`; cd libjpeg-turbo && cmake -DCMAKE_INSTALL_PREFIX=/usr/local -G"Unix Makefiles" && make && make install
|
|
||||||
|
|
||||||
# Additions for webp
|
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
|
||||||
./configure --enable-static --disable-shared && \
|
|
||||||
make && make install
|
|
||||||
|
|
||||||
# Fix for older required libs
|
|
||||||
#RUN cd /tmp && wget http://launchpadlibrarian.net/347526424/libxfont1-dev_1.5.2-4ubuntu2_amd64.deb && \
|
|
||||||
# wget http://launchpadlibrarian.net/347526425/libxfont1_1.5.2-4ubuntu2_amd64.deb && \
|
|
||||||
# dpkg -i libxfont1_1.5.2-4ubuntu2_amd64.deb && \
|
|
||||||
# dpkg -i libxfont1-dev_1.5.2-4ubuntu2_amd64.deb
|
|
||||||
|
|
||||||
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo
|
|
||||||
|
|
||||||
COPY --chown=docker:docker . /src
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
ENTRYPOINT ["/src/builder/build.sh"]
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
FROM ubuntu:bionic
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get -y install vim build-essential devscripts equivs
|
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
|
||||||
COPY $KASMVNC_PACKAGE_DIR/libjpeg-turbo*deb /tmp
|
|
||||||
RUN apt-get install /tmp/libjpeg-turbo*deb
|
|
||||||
|
|
||||||
# Install build-deps for the package.
|
|
||||||
COPY ./debian/control /tmp
|
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
|
||||||
|
|
||||||
ENV LD_LIBRARY_PATH="/opt/libjpeg-turbo/lib64/:$LD_LIBRARY_PATH"
|
|
||||||
|
|
||||||
ARG L_UID
|
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
FROM ubuntu:bionic
|
|
||||||
|
|
||||||
ENV DISPLAY=:1 \
|
|
||||||
VNC_PORT=8443 \
|
|
||||||
VNC_RESOLUTION=1280x720 \
|
|
||||||
MAX_FRAME_RATE=24 \
|
|
||||||
VNCOPTIONS="-PreferBandwidth -DynamicQualityMin=4 -DynamicQualityMax=7" \
|
|
||||||
HOME=/home/user \
|
|
||||||
TERM=xterm \
|
|
||||||
STARTUPDIR=/dockerstartup \
|
|
||||||
INST_SCRIPTS=/dockerstartup/install \
|
|
||||||
KASM_RX_HOME=/dockerstartup/kasmrx \
|
|
||||||
DEBIAN_FRONTEND=noninteractive \
|
|
||||||
VNC_COL_DEPTH=24 \
|
|
||||||
VNC_RESOLUTION=1280x1024 \
|
|
||||||
VNC_PW=vncpassword \
|
|
||||||
VNC_USER=user \
|
|
||||||
VNC_VIEW_ONLY_PW=vncviewonlypassword \
|
|
||||||
LD_LIBRARY_PATH=/opt/libjpeg-turbo/lib64/:/usr/local/lib/ \
|
|
||||||
OMP_WAIT_POLICY=PASSIVE \
|
|
||||||
SHELL=/bin/bash \
|
|
||||||
SINGLE_APPLICATION=0 \
|
|
||||||
KASMVNC_BUILD_OS=ubuntu \
|
|
||||||
KASMVNC_BUILD_OS_CODENAME=bionic
|
|
||||||
|
|
||||||
EXPOSE $VNC_PORT
|
|
||||||
|
|
||||||
WORKDIR $HOME
|
|
||||||
|
|
||||||
### REQUIRED STUFF ###
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext wget
|
|
||||||
RUN apt-get purge -y pm-utils xscreensaver*
|
|
||||||
RUN apt-get update && apt-get install -y vim less
|
|
||||||
RUN apt-get update && apt-get -y install lsb-release
|
|
||||||
|
|
||||||
RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
|
|
||||||
|
|
||||||
RUN mkdir -p $STARTUPDIR
|
|
||||||
COPY startup/ $STARTUPDIR
|
|
||||||
|
|
||||||
### START CUSTOM STUFF ####
|
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
|
||||||
COPY $KASMVNC_PACKAGE_DIR/libjpeg-turbo_*.deb /tmp
|
|
||||||
RUN apt-get install /tmp/libjpeg-turbo*deb
|
|
||||||
|
|
||||||
ARG BUILD_DEBIAN_REVISION
|
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*$BUILD_DEBIAN_REVISION*.deb /tmp
|
|
||||||
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
|
||||||
|
|
||||||
### END CUSTOM STUFF ###
|
|
||||||
|
|
||||||
RUN chown -R 1000:0 $HOME
|
|
||||||
USER 1000:ssl-cert
|
|
||||||
WORKDIR $HOME
|
|
||||||
|
|
||||||
ENTRYPOINT [ "/dockerstartup/vnc_startup.sh" ]
|
|
||||||
@@ -11,11 +11,11 @@ RUN apt-get update && \
|
|||||||
|
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -7,11 +7,4 @@ RUN apt-get update && \
|
|||||||
COPY ./debian/control /tmp
|
COPY ./debian/control /tmp
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
ARG L_UID
|
USER 1000
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ COPY startup/ $STARTUPDIR
|
|||||||
### START CUSTOM STUFF ####
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
|
|
||||||
### END CUSTOM STUFF ###
|
### END CUSTOM STUFF ###
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM ubuntu:focal
|
FROM ubuntu:focal
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; apt-get update && dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN apt-get update && dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
RUN apt-get update && apt-get -y install xterm lsb-release
|
RUN apt-get update && apt-get -y install xterm lsb-release
|
||||||
|
|
||||||
RUN useradd -m foo && addgroup foo ssl-cert
|
RUN useradd -m foo && addgroup foo ssl-cert
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ RUN apt-get update && \
|
|||||||
RUN apt-get update && apt-get install -y --no-install-recommends tzdata
|
RUN apt-get update && apt-get install -y --no-install-recommends tzdata
|
||||||
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
|
||||||
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
RUN apt-get update && apt-get -y install cmake git libjpeg-dev libgnutls28-dev vim wget tightvncserver
|
||||||
RUN apt-get update && apt-get -y install libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev
|
RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev libxcursor-dev
|
||||||
|
|
||||||
# Additions for webp
|
# Additions for webp
|
||||||
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
RUN cd /tmp && wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||||
RUN cd /tmp && tar -xzf /tmp/libwebp-*
|
RUN cd /tmp && tar -xzvf /tmp/libwebp-*
|
||||||
RUN cd /tmp/libwebp-1.0.2 && \
|
RUN cd /tmp/libwebp-1.0.2 && \
|
||||||
./configure --enable-static --disable-shared && \
|
./configure --enable-static --disable-shared && \
|
||||||
make && make install
|
make && make install
|
||||||
|
|||||||
@@ -9,11 +9,4 @@ RUN apt-get update && \
|
|||||||
COPY ./debian/control /tmp
|
COPY ./debian/control /tmp
|
||||||
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
RUN apt-get update && echo YYY | mk-build-deps --install --remove /tmp/control
|
||||||
|
|
||||||
ARG L_UID
|
USER 1000
|
||||||
RUN if [ "$L_UID" -eq 0 ]; then \
|
|
||||||
useradd -m docker; \
|
|
||||||
else \
|
|
||||||
useradd -m docker -u $L_UID;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
USER docker
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ COPY startup/ $STARTUPDIR
|
|||||||
### START CUSTOM STUFF ####
|
### START CUSTOM STUFF ####
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
ARG KASMVNC_PACKAGE_DIR
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp/
|
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
||||||
RUN rm -f /tmp/kasmvncserver_*+*.deb; dpkg -i /tmp/*.deb; apt-get -yf install
|
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
||||||
|
|
||||||
RUN mkdir ~/.vnc && echo '/usr/bin/xfce4-session &' >> ~/.vnc/xstartup && \
|
RUN mkdir ~/.vnc && echo '/usr/bin/xfce4-session &' >> ~/.vnc/xstartup && \
|
||||||
chmod +x ~/.vnc/xstartup
|
chmod +x ~/.vnc/xstartup
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
FROM ubuntu:focal
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
ENV VNC_PORT 8443
|
|
||||||
ENV VNC_PORT2 8444
|
|
||||||
ENV VNC_PORT3 8445
|
|
||||||
EXPOSE $VNC_PORT
|
|
||||||
EXPOSE $VNC_PORT2
|
|
||||||
EXPOSE $VNC_PORT3
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext wget
|
|
||||||
RUN apt-get update && apt-get install -y vim less
|
|
||||||
RUN apt-get update && apt-get -y install lsb-release
|
|
||||||
RUN apt-get update && apt-get -y install net-tools
|
|
||||||
|
|
||||||
# RUN mkdir -p /usr/share/man/man1
|
|
||||||
# RUN apt-get update && apt-get install -y apt-utils openjdk-11-jre
|
|
||||||
RUN apt-get update && apt-get install -y ubuntu-mate-desktop
|
|
||||||
RUN apt-get update && apt-get install -y lxde
|
|
||||||
RUN apt-get update && apt-get install -y lxqt
|
|
||||||
RUN apt-get update && apt-get install -y kde-full
|
|
||||||
RUN apt-get update && apt-get install -y cinnamon
|
|
||||||
RUN apt-get update && apt-get install -y ubuntu-gnome-desktop
|
|
||||||
RUN apt-get purge -y pm-utils xscreensaver*
|
|
||||||
RUN apt-get purge -y clipit magnus kgpg
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y python3-pip
|
|
||||||
RUN apt-get update && apt-get install -y strace
|
|
||||||
|
|
||||||
RUN useradd -m docker
|
|
||||||
ENV USER docker
|
|
||||||
|
|
||||||
ARG KASMVNC_PACKAGE_DIR
|
|
||||||
COPY $KASMVNC_PACKAGE_DIR/kasmvncserver_*.deb /tmp
|
|
||||||
RUN dpkg -i /tmp/*.deb; apt-get -yf install
|
|
||||||
|
|
||||||
ENV HOME /home/docker
|
|
||||||
RUN chown -R 1000:0 $HOME
|
|
||||||
USER 1000:ssl-cert
|
|
||||||
WORKDIR $HOME
|
|
||||||
|
|
||||||
RUN pip3 install --user pipenv
|
|
||||||
RUN echo 'PATH="/src/unix:~/.local/bin/:$PATH"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias s="sh /src/s"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias k="vncserver -kill :1; pkill baloo_file; pkill gpg-agent; pkill ssh-agent; pkill xiccd"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias r="k; s"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias go="sh /src/s; vncserver -kill :1"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias ns="netstat -nltp"' >> ~/.bashrc
|
|
||||||
RUN echo 'alias mamba="pipenv run mamba spec/"' >> ~/.bashrc
|
|
||||||
|
|
||||||
ENV LC_ALL=C.UTF-8
|
|
||||||
ENV LANG=C.UTF-8
|
|
||||||
|
|
||||||
ENTRYPOINT ["bash", "-ic", "cd /src && pipenv install; exec bash"]
|
|
||||||
@@ -3,11 +3,6 @@ default_os_codename=bionic
|
|||||||
|
|
||||||
os=${1:-$default_os}
|
os=${1:-$default_os}
|
||||||
os_codename=${2:-$default_os_codename}
|
os_codename=${2:-$default_os_codename}
|
||||||
build_tag="${3:-}"
|
|
||||||
if [[ -n "$build_tag" ]]; then
|
|
||||||
build_tag_for_images="_${build_tag#+}"
|
|
||||||
build_debian_revision="$(echo $build_tag | tr _ -)"
|
|
||||||
fi
|
|
||||||
os_image="$os:$os_codename"
|
os_image="$os:$os_codename"
|
||||||
|
|
||||||
echo "Building for $os_image"
|
echo "Building for $os_image"
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
debug() {
|
|
||||||
if [ -z "$debug" ]; then return; fi
|
|
||||||
|
|
||||||
echo "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_debug() {
|
|
||||||
debug=1
|
|
||||||
log_option="-log *:stderr:100"
|
|
||||||
}
|
|
||||||
|
|
||||||
kill_vnc_server() {
|
|
||||||
vncserver -kill $display
|
|
||||||
}
|
|
||||||
|
|
||||||
process_cli_options() {
|
|
||||||
for option in "$@"; do
|
|
||||||
case "$option" in
|
|
||||||
--help)
|
|
||||||
show_help
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
-d|--debug)
|
|
||||||
enable_debug
|
|
||||||
;;
|
|
||||||
-k|--kill)
|
|
||||||
kill_vnc_server
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
-s|--select-de)
|
|
||||||
action=select-de-and-start
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Unsupported argument: $option"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
show_help() {
|
|
||||||
cat >&2 <<-USAGE
|
|
||||||
Usage: $(basename "$0") [options]
|
|
||||||
-d, --debug Debug output
|
|
||||||
-k, --kill Kill vncserver
|
|
||||||
-s, --select-de Select desktop environent to run
|
|
||||||
--help Show this help
|
|
||||||
USAGE
|
|
||||||
}
|
|
||||||
@@ -4,8 +4,43 @@ set -e
|
|||||||
|
|
||||||
display=:10
|
display=:10
|
||||||
interface=0.0.0.0
|
interface=0.0.0.0
|
||||||
|
cert_group=ssl-cert
|
||||||
|
|
||||||
|
if [[ "$1" = "--help" ]]; then
|
||||||
|
cat >&2 <<-USAGE
|
||||||
|
Usage: `basename $0` [options]
|
||||||
|
-d Debug output
|
||||||
|
-kill Kill vncserver
|
||||||
|
--help show this help
|
||||||
|
USAGE
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" = "-d" ]]; then
|
||||||
|
log_option="-log *:stderr:100"
|
||||||
|
fi
|
||||||
|
|
||||||
|
action=start
|
||||||
|
if [[ "$1" = "-kill" ]]; then
|
||||||
|
action=kill
|
||||||
|
fi
|
||||||
|
|
||||||
|
if groups | grep -qvw ssl-cert; then
|
||||||
|
cat <<-EOF
|
||||||
|
Can't access TLS certificate.
|
||||||
|
Please add your user to $cert_group via 'addgroup <user> ssl-cert'
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$action" = "kill" ]]; then
|
||||||
|
vncserver -kill $display
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
vncserver $display -interface $interface
|
||||||
|
vncserver -kill $display
|
||||||
vncserver $display -depth 24 -geometry 1280x1050 -websocketPort 8443 \
|
vncserver $display -depth 24 -geometry 1280x1050 -websocketPort 8443 \
|
||||||
-cert /etc/ssl/certs/ssl-cert-snakeoil.pem \
|
-cert /etc/ssl/certs/ssl-cert-snakeoil.pem \
|
||||||
-key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24 \
|
-key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24 \
|
||||||
-interface $interface -httpd /usr/share/kasmvnc/www
|
-interface $interface -httpd /usr/share/kasmvnc/www $log_option
|
||||||
|
|||||||
@@ -1,258 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
xstartup_script=~/.vnc/xstartup
|
|
||||||
de_was_selected_file="$HOME/.vnc/.de-was-selected"
|
|
||||||
|
|
||||||
debug() {
|
|
||||||
if [ -z "$debug" ]; then return; fi
|
|
||||||
|
|
||||||
echo "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_debug() {
|
|
||||||
debug=1
|
|
||||||
}
|
|
||||||
|
|
||||||
process_cli_options() {
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
local option="$1"
|
|
||||||
shift
|
|
||||||
|
|
||||||
case "$option" in
|
|
||||||
--help|-h)
|
|
||||||
show_help
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
-d|--debug)
|
|
||||||
enable_debug
|
|
||||||
;;
|
|
||||||
-y|--assume-yes)
|
|
||||||
assume_yes=1
|
|
||||||
;;
|
|
||||||
-s|--select-de)
|
|
||||||
action=select-de
|
|
||||||
if [[ -n "$1" && "${1:0:1}" != "-" ]]; then
|
|
||||||
selected_de="$1"
|
|
||||||
assume_yes_for_xstartup_overwrite=1
|
|
||||||
if [ "$selected_de" = "manual" ]; then
|
|
||||||
selected_de="$manual_xstartup_choice"
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo >&2 "Unsupported argument: $option"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
show_help() {
|
|
||||||
cat >&2 <<-USAGE
|
|
||||||
Usage: $(basename "$0") [options]
|
|
||||||
-d, --debug Debug output
|
|
||||||
-y, --assume-yes Automatic "yes" to prompts
|
|
||||||
-s, --select-de Select desktop environent to run
|
|
||||||
--help Show this help
|
|
||||||
USAGE
|
|
||||||
}
|
|
||||||
|
|
||||||
add_uppercase_desktop_environment_keys() {
|
|
||||||
local de_cmd
|
|
||||||
|
|
||||||
for de in "${!all_desktop_environments[@]}"; do
|
|
||||||
de_cmd=${all_desktop_environments[$de]};
|
|
||||||
all_desktop_environments[${de^^}]="$de_cmd"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
process_cli_options "$@"
|
|
||||||
|
|
||||||
manual_xstartup_choice="Manually edit xstartup"
|
|
||||||
declare -A all_desktop_environments=(
|
|
||||||
[Cinnamon]="exec cinnamon-session"
|
|
||||||
[Mate]="XDG_CURRENT_DESKTOP=MATE exec dbus-launch --exit-with-session mate-session"
|
|
||||||
[LXDE]="exec lxsession"
|
|
||||||
[Lxqt]="exec startlxqt"
|
|
||||||
[KDE]="exec startkde"
|
|
||||||
[Gnome]="XDG_CURRENT_DESKTOP=GNOME exec dbus-launch --exit-with-session /usr/bin/gnome-session"
|
|
||||||
[XFCE]="exec xfce4-session")
|
|
||||||
|
|
||||||
readarray -t sorted_desktop_environments < <(for de in "${!all_desktop_environments[@]}"; do echo "$de"; done | sort)
|
|
||||||
|
|
||||||
all_desktop_environments[$manual_xstartup_choice]=""
|
|
||||||
sorted_desktop_environments+=("$manual_xstartup_choice")
|
|
||||||
add_uppercase_desktop_environment_keys
|
|
||||||
|
|
||||||
detected_desktop_environments=()
|
|
||||||
declare -A numbered_desktop_environments
|
|
||||||
|
|
||||||
print_detected_desktop_environments() {
|
|
||||||
declare -i i=1
|
|
||||||
|
|
||||||
echo "Please choose Desktop Environment to run:"
|
|
||||||
for detected_de in "${detected_desktop_environments[@]}"; do
|
|
||||||
echo "[$i] $detected_de"
|
|
||||||
numbered_desktop_environments[$i]=$detected_de
|
|
||||||
i+=1
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_desktop_environments() {
|
|
||||||
for de_name in "${sorted_desktop_environments[@]}"; do
|
|
||||||
if [[ "$de_name" = "$manual_xstartup_choice" ]]; then
|
|
||||||
detected_desktop_environments+=("$de_name")
|
|
||||||
continue;
|
|
||||||
fi
|
|
||||||
|
|
||||||
local executable=${all_desktop_environments[$de_name]}
|
|
||||||
executable=($executable)
|
|
||||||
executable=${executable[-1]}
|
|
||||||
|
|
||||||
if detect_desktop_environment "$de_name" "$executable"; then
|
|
||||||
detected_desktop_environments+=("$de_name")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
ask_user_to_choose_de() {
|
|
||||||
while : ; do
|
|
||||||
print_detected_desktop_environments
|
|
||||||
read -r de_number_to_run
|
|
||||||
de_name_from_number "$de_number_to_run"
|
|
||||||
if [[ -n "$de_name" ]]; then
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Incorrect number: $de_number_to_run"
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
remember_de_choice() {
|
|
||||||
touch "$de_was_selected_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
de_was_selected_on_previous_run() {
|
|
||||||
[[ -f "$de_was_selected_file" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_desktop_environment() {
|
|
||||||
local de_name="$1"
|
|
||||||
local executable="$2"
|
|
||||||
|
|
||||||
if command -v "$executable" &>/dev/null; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
did_user_forbid_replacing_xstartup() {
|
|
||||||
grep -q -v KasmVNC-safe-to-replace-this-file "$xstartup_script"
|
|
||||||
}
|
|
||||||
|
|
||||||
de_cmd_from_name() {
|
|
||||||
de_cmd=${all_desktop_environments[${de_name^^}]}
|
|
||||||
}
|
|
||||||
|
|
||||||
de_name_from_number() {
|
|
||||||
local de_number_to_run="$1"
|
|
||||||
|
|
||||||
de_name=${numbered_desktop_environments[$de_number_to_run]}
|
|
||||||
}
|
|
||||||
|
|
||||||
warn_xstartup_will_be_overwriten() {
|
|
||||||
if [[ -n "$assume_yes" || -n "$assume_yes_for_xstartup_overwrite" ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$xstartup_script" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "WARNING: $xstartup_script will be overwritten y/N?"
|
|
||||||
read -r do_overwrite_xstartup
|
|
||||||
if [[ "$do_overwrite_xstartup" = "y" || "$do_overwrite_xstartup" = "Y" ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_de_to_run_via_xstartup() {
|
|
||||||
warn_xstartup_will_be_overwriten
|
|
||||||
generate_xstartup "$de_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_xstartup() {
|
|
||||||
local de_name="$1"
|
|
||||||
|
|
||||||
de_cmd_from_name
|
|
||||||
|
|
||||||
cat <<-SCRIPT > "$xstartup_script"
|
|
||||||
#!/bin/sh
|
|
||||||
$de_cmd
|
|
||||||
SCRIPT
|
|
||||||
chmod +x "$xstartup_script"
|
|
||||||
}
|
|
||||||
|
|
||||||
user_asked_to_select_de() {
|
|
||||||
[[ "$action" = "select-de" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
user_specified_de() {
|
|
||||||
[ -n "$selected_de" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
check_de_name_is_valid() {
|
|
||||||
local selected_de="$1"
|
|
||||||
local de_cmd=${all_desktop_environments["${selected_de^^}"]:-}
|
|
||||||
if [ -z "$de_cmd" ]; then
|
|
||||||
echo >&2 "'$selected_de': not supported Desktop Environment"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
de_installed() {
|
|
||||||
local de_name="${1^^}"
|
|
||||||
|
|
||||||
for de in "${detected_desktop_environments[@]}"; do
|
|
||||||
if [ "${de^^}" = "$de_name" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
check_de_installed() {
|
|
||||||
local de_name="$1"
|
|
||||||
|
|
||||||
if ! de_installed "$de_name"; then
|
|
||||||
echo >&2 "'$de_name': Desktop Environment not installed"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if user_asked_to_select_de || ! de_was_selected_on_previous_run; then
|
|
||||||
if user_specified_de; then
|
|
||||||
check_de_name_is_valid "$selected_de"
|
|
||||||
fi
|
|
||||||
|
|
||||||
detect_desktop_environments
|
|
||||||
if user_specified_de; then
|
|
||||||
check_de_installed "$selected_de"
|
|
||||||
de_name="$selected_de"
|
|
||||||
else
|
|
||||||
ask_user_to_choose_de
|
|
||||||
fi
|
|
||||||
|
|
||||||
debug "You selected $de_name desktop environment"
|
|
||||||
if [[ "$de_name" != "$manual_xstartup_choice" ]]; then
|
|
||||||
setup_de_to_run_via_xstartup
|
|
||||||
fi
|
|
||||||
remember_de_choice
|
|
||||||
fi
|
|
||||||
@@ -61,6 +61,9 @@ kasmvncpasswd -d -u "$VNC_USER-to-delete" $HOME/.kasmpasswd
|
|||||||
chmod 0600 $HOME/.kasmpasswd
|
chmod 0600 $HOME/.kasmpasswd
|
||||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout $HOME/.vnc/self.pem -out $HOME/.vnc/self.pem -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/emailAddress=none@none.none"
|
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout $HOME/.vnc/self.pem -out $HOME/.vnc/self.pem -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/emailAddress=none@none.none"
|
||||||
|
|
||||||
|
vncserver :1 -interface 0.0.0.0
|
||||||
|
vncserver -kill :1
|
||||||
|
|
||||||
if [[ -f $PASSWD_PATH ]]; then
|
if [[ -f $PASSWD_PATH ]]; then
|
||||||
rm -f $PASSWD_PATH
|
rm -f $PASSWD_PATH
|
||||||
fi
|
fi
|
||||||
@@ -83,10 +86,10 @@ vncserver -kill $DISPLAY &> $HOME/.vnc/vnc_startup.log \
|
|||||||
|
|
||||||
detect_www_dir
|
detect_www_dir
|
||||||
detect_cert_location
|
detect_cert_location
|
||||||
[ -n "$KASMVNC_VERBOSE_LOGGING" ] && verbose_logging_option="-debug"
|
[ -n "$KASMVNC_VERBOSE_LOGGING" ] && verbose_logging_option="-log *:stderr:100"
|
||||||
|
|
||||||
echo -e "start vncserver with param: VNC_COL_DEPTH=$VNC_COL_DEPTH, VNC_RESOLUTION=$VNC_RESOLUTION\n..."
|
echo -e "start vncserver with param: VNC_COL_DEPTH=$VNC_COL_DEPTH, VNC_RESOLUTION=$VNC_RESOLUTION\n..."
|
||||||
vncserver $DISPLAY -select-de xfce -depth $VNC_COL_DEPTH -geometry $VNC_RESOLUTION -FrameRate=$MAX_FRAME_RATE -websocketPort $VNC_PORT $cert_option -sslOnly -interface 0.0.0.0 $VNCOPTIONS $package_www_dir_option $verbose_logging_option #&> $STARTUPDIR/no_vnc_startup.log
|
vncserver $DISPLAY -depth $VNC_COL_DEPTH -geometry $VNC_RESOLUTION -FrameRate=$MAX_FRAME_RATE -websocketPort $VNC_PORT $cert_option -sslOnly -interface 0.0.0.0 $VNCOPTIONS $package_www_dir_option $verbose_logging_option #&> $STARTUPDIR/no_vnc_startup.log
|
||||||
|
|
||||||
PID_SUN=$!
|
PID_SUN=$!
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ set -e
|
|||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
. ./os_ver_cli.sh
|
. ./os_ver_cli.sh
|
||||||
|
|
||||||
tester_image=kasmvnctester_${os}:$os_codename${build_tag_for_images}
|
|
||||||
docker build --build-arg KASMVNC_PACKAGE_DIR="build/${os_codename}" \
|
docker build --build-arg KASMVNC_PACKAGE_DIR="build/${os_codename}" \
|
||||||
--build-arg BUILD_DEBIAN_REVISION="$build_debian_revision" \
|
-t kasmvnctester_${os}:$os_codename \
|
||||||
-t "$tester_image" \
|
-f dockerfile.${os}_${os_codename}.deb.test .
|
||||||
-f dockerfile.${os}_${os_codename}${build_tag}.deb.test .
|
|
||||||
docker run -it -p 443:8443 --rm \
|
docker run -it -p 443:8443 --rm \
|
||||||
-e KASMVNC_VERBOSE_LOGGING=$KASMVNC_VERBOSE_LOGGING \
|
-e KASMVNC_VERBOSE_LOGGING=$KASMVNC_VERBOSE_LOGGING \
|
||||||
-e "VNC_USER=foo" -e "VNC_PW=foobar" \
|
-e "VNC_USER=foo" -e "VNC_PW=foobar" \
|
||||||
"$tester_image"
|
kasmvnctester_${os}:$os_codename
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
. ./os_ver_cli.sh
|
|
||||||
|
|
||||||
docker build --build-arg KASMVNC_PACKAGE_DIR="build/${os_codename}" \
|
|
||||||
-t kasmvnctester_${os}:$os_codename \
|
|
||||||
-f dockerfile.${os}_${os_codename}.vncserver.test .
|
|
||||||
docker run -it -v $(realpath ${PWD}/..):/src -p 8443:8443 -p 8444:8444 \
|
|
||||||
-p 8445:8445 --rm \
|
|
||||||
-e KASMVNC_VERBOSE_LOGGING=$KASMVNC_VERBOSE_LOGGING \
|
|
||||||
-e "VNC_USER=foo" -e "VNC_PW=foobar" \
|
|
||||||
kasmvnctester_${os}:$os_codename
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: kasmvncserver
|
Name: kasmvncserver
|
||||||
Version: 0.9.3~beta
|
Version: 0.9.1~beta
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: VNC server accessible from a web browser
|
Summary: VNC server accessible from a web browser
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ License: GPLv2+
|
|||||||
URL: https://github.com/kasmtech/KasmVNC
|
URL: https://github.com/kasmtech/KasmVNC
|
||||||
|
|
||||||
BuildRequires: rsync
|
BuildRequires: rsync
|
||||||
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl, perl-Switch, rpmfusion-free-release, perl-Hash-Merge-Simple, perl-Scalar-List-Utils
|
Requires: xorg-x11-xauth, xorg-x11-xkb-utils, xkeyboard-config, xorg-x11-server-utils, openssl, perl
|
||||||
Conflicts: tigervnc-server, tigervnc-server-minimal
|
Conflicts: tigervnc-server, tigervnc-server-minimal
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -48,12 +48,11 @@ DESTDIR=$RPM_BUILD_ROOT
|
|||||||
DST_MAN=$DESTDIR/usr/share/man/man1
|
DST_MAN=$DESTDIR/usr/share/man/man1
|
||||||
|
|
||||||
mkdir -p $DESTDIR/usr/bin $DESTDIR/usr/share/man/man1 \
|
mkdir -p $DESTDIR/usr/bin $DESTDIR/usr/share/man/man1 \
|
||||||
$DESTDIR/usr/share/doc/kasmvncserver $DESTDIR/usr/lib
|
$DESTDIR/usr/share/doc/kasmvncserver
|
||||||
cp $SRC_BIN/Xvnc $DESTDIR/usr/bin;
|
cp $SRC_BIN/Xvnc $DESTDIR/usr/bin;
|
||||||
cp $SRC_BIN/vncserver $DESTDIR/usr/bin;
|
cp $SRC_BIN/vncserver $DESTDIR/usr/bin;
|
||||||
cp $SRC_BIN/vncconfig $DESTDIR/usr/bin;
|
cp $SRC_BIN/vncconfig $DESTDIR/usr/bin;
|
||||||
cp $SRC_BIN/kasmvncpasswd $DESTDIR/usr/bin;
|
cp $SRC_BIN/kasmvncpasswd $DESTDIR/usr/bin;
|
||||||
cp -r $SRC/lib/kasmvnc/ $DESTDIR/usr/lib/kasmvncserver
|
|
||||||
cd $DESTDIR/usr/bin && ln -s kasmvncpasswd vncpasswd;
|
cd $DESTDIR/usr/bin && ln -s kasmvncpasswd vncpasswd;
|
||||||
cp -r $SRC/share/doc/kasmvnc*/* $DESTDIR/usr/share/doc/kasmvncserver/
|
cp -r $SRC/share/doc/kasmvnc*/* $DESTDIR/usr/share/doc/kasmvncserver/
|
||||||
rsync -r --exclude '.git*' --exclude po2js --exclude xgettext-html \
|
rsync -r --exclude '.git*' --exclude po2js --exclude xgettext-html \
|
||||||
@@ -63,11 +62,12 @@ cp $SRC/man/man1/Xvnc.1 $DESTDIR/usr/share/man/man1/;
|
|||||||
cp $SRC/share/man/man1/vncserver.1 $DST_MAN;
|
cp $SRC/share/man/man1/vncserver.1 $DST_MAN;
|
||||||
cp $SRC/share/man/man1/vncconfig.1 $DST_MAN;
|
cp $SRC/share/man/man1/vncconfig.1 $DST_MAN;
|
||||||
cp $SRC/share/man/man1/vncpasswd.1 $DST_MAN;
|
cp $SRC/share/man/man1/vncpasswd.1 $DST_MAN;
|
||||||
|
cp $SRC/share/man/man1/kasmxpoxy.1 $DST_MAN;
|
||||||
cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
|
cd $DST_MAN && ln -s vncpasswd.1 kasmvncpasswd.1;
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
/usr/bin/*
|
/usr/bin/*
|
||||||
/usr/lib/kasmvncserver
|
|
||||||
/usr/share/man/man1/*
|
/usr/share/man/man1/*
|
||||||
/usr/share/kasmvnc/www
|
/usr/share/kasmvnc/www
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <network/GetAPI.h>
|
#include <network/GetAPI.h>
|
||||||
#include <rfb/ConnParams.h>
|
#include <rfb/ConnParams.h>
|
||||||
#include <rfb/EncodeManager.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
#include <rfb/LogWriter.h>
|
||||||
#include <rfb/JpegCompressor.h>
|
#include <rfb/JpegCompressor.h>
|
||||||
#include <rfb/xxhash.h>
|
#include <rfb/xxhash.h>
|
||||||
@@ -33,6 +32,10 @@ using namespace rfb;
|
|||||||
|
|
||||||
static LogWriter vlog("GetAPIMessager");
|
static LogWriter vlog("GetAPIMessager");
|
||||||
|
|
||||||
|
PixelBuffer *progressiveBilinearScale(const PixelBuffer *pb,
|
||||||
|
const uint16_t tgtw, const uint16_t tgth,
|
||||||
|
const float tgtdiff);
|
||||||
|
|
||||||
struct TightJPEGConfiguration {
|
struct TightJPEGConfiguration {
|
||||||
int quality;
|
int quality;
|
||||||
int subsampling;
|
int subsampling;
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ static const char *parse_get(const char * const in, const char * const opt, unsi
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void percent_decode(const char *src, char *dst, const uint8_t filter) {
|
static void percent_decode(const char *src, char *dst) {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!*src)
|
if (!*src)
|
||||||
break;
|
break;
|
||||||
@@ -127,32 +127,7 @@ static void percent_decode(const char *src, char *dst, const uint8_t filter) {
|
|||||||
hex[2] = '\0';
|
hex[2] = '\0';
|
||||||
|
|
||||||
src += 2;
|
src += 2;
|
||||||
*dst = strtol(hex, NULL, 16);
|
*dst++ = strtol(hex, NULL, 16);
|
||||||
|
|
||||||
if (filter) {
|
|
||||||
// Avoid directory traversal
|
|
||||||
if (*dst == '/')
|
|
||||||
*dst = '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*dst = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void percent_encode(const char *src, char *dst) {
|
|
||||||
while (1) {
|
|
||||||
if (!*src)
|
|
||||||
break;
|
|
||||||
if (isalnum(*src) || *src == '.' || *src == ',') {
|
|
||||||
*dst++ = *src++;
|
|
||||||
} else {
|
|
||||||
*dst++ = '%';
|
|
||||||
sprintf(dst, "%02X", *src);
|
|
||||||
dst += 2;
|
|
||||||
src++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,7 +746,6 @@ def:
|
|||||||
|
|
||||||
static void dirlisting(ws_ctx_t *ws_ctx, const char fullpath[], const char path[]) {
|
static void dirlisting(ws_ctx_t *ws_ctx, const char fullpath[], const char path[]) {
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
char enc[PATH_MAX * 3 + 1];
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
// Redirect?
|
// Redirect?
|
||||||
@@ -805,13 +779,11 @@ static void dirlisting(ws_ctx_t *ws_ctx, const char fullpath[], const char path[
|
|||||||
if (!strcmp(names[i]->d_name, ".") || !strcmp(names[i]->d_name, ".."))
|
if (!strcmp(names[i]->d_name, ".") || !strcmp(names[i]->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
percent_encode(names[i]->d_name, enc);
|
|
||||||
|
|
||||||
if (names[i]->d_type == DT_DIR)
|
if (names[i]->d_type == DT_DIR)
|
||||||
sprintf(buf, "<li><a href=\"%s/\">%s/</a></li>", enc,
|
sprintf(buf, "<li><a href=\"%s/\">%s/</a></li>", names[i]->d_name,
|
||||||
names[i]->d_name);
|
names[i]->d_name);
|
||||||
else
|
else
|
||||||
sprintf(buf, "<li><a href=\"%s\">%s</a></li>", enc,
|
sprintf(buf, "<li><a href=\"%s\">%s</a></li>", names[i]->d_name,
|
||||||
names[i]->d_name);
|
names[i]->d_name);
|
||||||
|
|
||||||
ws_send(ws_ctx, buf, strlen(buf));
|
ws_send(ws_ctx, buf, strlen(buf));
|
||||||
@@ -850,15 +822,13 @@ static void servefile(ws_ctx_t *ws_ctx, const char *in) {
|
|||||||
len = strlen(path);
|
len = strlen(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
percent_decode(path, buf, 1);
|
wserr("Requested file '%s'\n", path);
|
||||||
|
sprintf(fullpath, "%s/%s", settings.httpdir, path);
|
||||||
wserr("Requested file '%s'\n", buf);
|
|
||||||
sprintf(fullpath, "%s/%s", settings.httpdir, buf);
|
|
||||||
|
|
||||||
DIR *dir = opendir(fullpath);
|
DIR *dir = opendir(fullpath);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
dirlisting(ws_ctx, fullpath, buf);
|
dirlisting(ws_ctx, fullpath, path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,14 +976,14 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|||||||
if (len) {
|
if (len) {
|
||||||
memcpy(buf, param, len);
|
memcpy(buf, param, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
percent_decode(buf, decname, 0);
|
percent_decode(buf, decname);
|
||||||
}
|
}
|
||||||
|
|
||||||
param = parse_get(args, "password", &len);
|
param = parse_get(args, "password", &len);
|
||||||
if (len) {
|
if (len) {
|
||||||
memcpy(buf, param, len);
|
memcpy(buf, param, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
percent_decode(buf, decpw, 0);
|
percent_decode(buf, decpw);
|
||||||
|
|
||||||
struct crypt_data cdata;
|
struct crypt_data cdata;
|
||||||
cdata.initialized = 0;
|
cdata.initialized = 0;
|
||||||
@@ -1053,7 +1023,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|||||||
if (len) {
|
if (len) {
|
||||||
memcpy(buf, param, len);
|
memcpy(buf, param, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
percent_decode(buf, decname, 0);
|
percent_decode(buf, decname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decname[0])
|
if (!decname[0])
|
||||||
@@ -1082,7 +1052,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|||||||
if (len) {
|
if (len) {
|
||||||
memcpy(buf, param, len);
|
memcpy(buf, param, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
percent_decode(buf, decname, 0);
|
percent_decode(buf, decname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decname[0])
|
if (!decname[0])
|
||||||
@@ -1127,7 +1097,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
|||||||
if (len) {
|
if (len) {
|
||||||
memcpy(buf, param, len);
|
memcpy(buf, param, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
percent_decode(buf, decname, 0);
|
percent_decode(buf, decname);
|
||||||
} else {
|
} else {
|
||||||
wserr("client param required\n");
|
wserr("client param required\n");
|
||||||
goto nope;
|
goto nope;
|
||||||
@@ -1350,8 +1320,6 @@ ws_ctx_t *do_handshake(int sock) {
|
|||||||
} else {
|
} else {
|
||||||
// Client tried an empty password, just fail them
|
// Client tried an empty password, just fail them
|
||||||
response[0] = '\0';
|
response[0] = '\0';
|
||||||
authbuf[0] = 'a';
|
|
||||||
authbuf[1] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ static void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
|||||||
int maxfd, client = ws_ctx->sockfd;
|
int maxfd, client = ws_ctx->sockfd;
|
||||||
unsigned int opcode, left, ret;
|
unsigned int opcode, left, ret;
|
||||||
unsigned int tout_start, tout_end, cout_start, cout_end;
|
unsigned int tout_start, tout_end, cout_start, cout_end;
|
||||||
unsigned int tin_end;
|
unsigned int tin_start, tin_end;
|
||||||
ssize_t len, bytes;
|
ssize_t len, bytes;
|
||||||
|
|
||||||
tout_start = tout_end = cout_start = cout_end =
|
tout_start = tout_end = cout_start = cout_end =
|
||||||
tin_end = 0;
|
tin_start = tin_end = 0;
|
||||||
maxfd = client > target ? client+1 : target+1;
|
maxfd = client > target ? client+1 : target+1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -165,7 +165,7 @@ static void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(client, &rlist)) {
|
if (FD_ISSET(client, &rlist)) {
|
||||||
bytes = ws_recv(ws_ctx, ws_ctx->tin_buf + tin_end, BUFSIZE-1-tin_end);
|
bytes = ws_recv(ws_ctx, ws_ctx->tin_buf + tin_end, BUFSIZE-1);
|
||||||
if (pipe_error) { break; }
|
if (pipe_error) { break; }
|
||||||
if (bytes <= 0) {
|
if (bytes <= 0) {
|
||||||
handler_emsg("client closed connection\n");
|
handler_emsg("client closed connection\n");
|
||||||
@@ -180,13 +180,13 @@ static void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
*/
|
*/
|
||||||
if (ws_ctx->hybi) {
|
if (ws_ctx->hybi) {
|
||||||
len = decode_hybi(ws_ctx->tin_buf,
|
len = decode_hybi(ws_ctx->tin_buf + tin_start,
|
||||||
tin_end,
|
tin_end-tin_start,
|
||||||
ws_ctx->tout_buf, BUFSIZE-1,
|
ws_ctx->tout_buf, BUFSIZE-1,
|
||||||
&opcode, &left);
|
&opcode, &left);
|
||||||
} else {
|
} else {
|
||||||
len = decode_hixie(ws_ctx->tin_buf,
|
len = decode_hixie(ws_ctx->tin_buf + tin_start,
|
||||||
tin_end,
|
tin_end-tin_start,
|
||||||
ws_ctx->tout_buf, BUFSIZE-1,
|
ws_ctx->tout_buf, BUFSIZE-1,
|
||||||
&opcode, &left);
|
&opcode, &left);
|
||||||
}
|
}
|
||||||
@@ -208,13 +208,10 @@ static void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (left) {
|
if (left) {
|
||||||
const unsigned tin_start = tin_end - left;
|
tin_start = tin_end - left;
|
||||||
//handler_emsg("partial frame from client, %u left, start %u end %u, lens %lu %lu\n",
|
//printf("partial frame from client");
|
||||||
// left, tin_start, tin_end, bytes, len);
|
|
||||||
memmove(ws_ctx->tin_buf, ws_ctx->tin_buf + tin_start, left);
|
|
||||||
tin_end = left;
|
|
||||||
} else {
|
} else {
|
||||||
//handler_emsg("handled %lu/%lu bytes\n", bytes, len);
|
tin_start = 0;
|
||||||
tin_end = 0;
|
tin_end = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ set(RFB_SOURCES
|
|||||||
Security.cxx
|
Security.cxx
|
||||||
SecurityServer.cxx
|
SecurityServer.cxx
|
||||||
SecurityClient.cxx
|
SecurityClient.cxx
|
||||||
SelfBench.cxx
|
|
||||||
SSecurityPlain.cxx
|
SSecurityPlain.cxx
|
||||||
SSecurityStack.cxx
|
SSecurityStack.cxx
|
||||||
SSecurityVncAuth.cxx
|
SSecurityVncAuth.cxx
|
||||||
@@ -64,7 +63,6 @@ set(RFB_SOURCES
|
|||||||
VNCServerST.cxx
|
VNCServerST.cxx
|
||||||
ZRLEEncoder.cxx
|
ZRLEEncoder.cxx
|
||||||
ZRLEDecoder.cxx
|
ZRLEDecoder.cxx
|
||||||
cpuid.cxx
|
|
||||||
encodings.cxx
|
encodings.cxx
|
||||||
util.cxx
|
util.cxx
|
||||||
xxhash.c)
|
xxhash.c)
|
||||||
@@ -98,27 +96,6 @@ if(GNUTLS_FOUND)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# SSE2
|
|
||||||
|
|
||||||
set(SSE2_SOURCES
|
|
||||||
scale_sse2.cxx)
|
|
||||||
|
|
||||||
set(SCALE_DUMMY_SOURCES
|
|
||||||
scale_dummy.cxx)
|
|
||||||
|
|
||||||
if(COMPILER_SUPPORTS_SSE2)
|
|
||||||
set_source_files_properties(${SSE2_SOURCES} PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS} -msse2)
|
|
||||||
set(RFB_SOURCES
|
|
||||||
${RFB_SOURCES}
|
|
||||||
${SSE2_SOURCES}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
set(RFB_SOURCES
|
|
||||||
${RFB_SOURCES}
|
|
||||||
${SCALE_DUMMY_SOURCES}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(rfb STATIC ${RFB_SOURCES})
|
add_library(rfb STATIC ${RFB_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(rfb ${RFB_LIBRARIES})
|
target_link_libraries(rfb ${RFB_LIBRARIES})
|
||||||
|
|||||||
@@ -22,12 +22,10 @@
|
|||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <rfb/cpuid.h>
|
|
||||||
#include <rfb/EncCache.h>
|
#include <rfb/EncCache.h>
|
||||||
#include <rfb/EncodeManager.h>
|
#include <rfb/EncodeManager.h>
|
||||||
#include <rfb/Encoder.h>
|
#include <rfb/Encoder.h>
|
||||||
#include <rfb/Palette.h>
|
#include <rfb/Palette.h>
|
||||||
#include <rfb/scale_sse2.h>
|
|
||||||
#include <rfb/SConnection.h>
|
#include <rfb/SConnection.h>
|
||||||
#include <rfb/ServerCore.h>
|
#include <rfb/ServerCore.h>
|
||||||
#include <rfb/SMsgWriter.h>
|
#include <rfb/SMsgWriter.h>
|
||||||
@@ -897,7 +895,7 @@ void EncodeManager::updateVideoStats(const std::vector<Rect> &rects, const Pixel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelBuffer *rfb::nearestScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
static PixelBuffer *nearestScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
||||||
const float diff)
|
const float diff)
|
||||||
{
|
{
|
||||||
ManagedPixelBuffer *newpb = new ManagedPixelBuffer(pb->getPF(), w, h);
|
ManagedPixelBuffer *newpb = new ManagedPixelBuffer(pb->getPF(), w, h);
|
||||||
@@ -922,7 +920,7 @@ PixelBuffer *rfb::nearestScale(const PixelBuffer *pb, const uint16_t w, const ui
|
|||||||
return newpb;
|
return newpb;
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelBuffer *rfb::bilinearScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
static PixelBuffer *bilinearScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
||||||
const float diff)
|
const float diff)
|
||||||
{
|
{
|
||||||
ManagedPixelBuffer *newpb = new ManagedPixelBuffer(pb->getPF(), w, h);
|
ManagedPixelBuffer *newpb = new ManagedPixelBuffer(pb->getPF(), w, h);
|
||||||
@@ -970,68 +968,10 @@ PixelBuffer *rfb::bilinearScale(const PixelBuffer *pb, const uint16_t w, const u
|
|||||||
return newpb;
|
return newpb;
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelBuffer *rfb::progressiveBilinearScale(const PixelBuffer *pb,
|
PixelBuffer *progressiveBilinearScale(const PixelBuffer *pb,
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
const uint16_t tgtw, const uint16_t tgth,
|
||||||
const float tgtdiff)
|
const float tgtdiff)
|
||||||
{
|
{
|
||||||
if (supportsSSE2()) {
|
|
||||||
if (tgtdiff >= 0.5f) {
|
|
||||||
ManagedPixelBuffer *newpb = new ManagedPixelBuffer(pb->getPF(), tgtw, tgth);
|
|
||||||
|
|
||||||
int oldstride, newstride;
|
|
||||||
const rdr::U8 *oldpx = pb->getBuffer(pb->getRect(), &oldstride);
|
|
||||||
rdr::U8 *newpx = newpb->getBufferRW(newpb->getRect(), &newstride);
|
|
||||||
|
|
||||||
SSE2_scale(oldpx, tgtw, tgth, newpx, oldstride, newstride, tgtdiff);
|
|
||||||
return newpb;
|
|
||||||
}
|
|
||||||
|
|
||||||
PixelBuffer *newpb;
|
|
||||||
uint16_t neww, newh, oldw, oldh;
|
|
||||||
bool del = false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
oldw = pb->getRect().width();
|
|
||||||
oldh = pb->getRect().height();
|
|
||||||
neww = oldw / 2;
|
|
||||||
newh = oldh / 2;
|
|
||||||
|
|
||||||
newpb = new ManagedPixelBuffer(pb->getPF(), neww, newh);
|
|
||||||
|
|
||||||
int oldstride, newstride;
|
|
||||||
const rdr::U8 *oldpx = pb->getBuffer(pb->getRect(), &oldstride);
|
|
||||||
rdr::U8 *newpx = ((ManagedPixelBuffer *) newpb)->getBufferRW(newpb->getRect(),
|
|
||||||
&newstride);
|
|
||||||
|
|
||||||
SSE2_halve(oldpx, neww, newh, newpx, oldstride, newstride);
|
|
||||||
|
|
||||||
if (del)
|
|
||||||
delete pb;
|
|
||||||
del = true;
|
|
||||||
|
|
||||||
pb = newpb;
|
|
||||||
} while (tgtw * 2 < neww);
|
|
||||||
|
|
||||||
// Final, non-halving step
|
|
||||||
if (tgtw != neww || tgth != newh) {
|
|
||||||
oldw = pb->getRect().width();
|
|
||||||
oldh = pb->getRect().height();
|
|
||||||
|
|
||||||
newpb = new ManagedPixelBuffer(pb->getPF(), tgtw, tgth);
|
|
||||||
|
|
||||||
int oldstride, newstride;
|
|
||||||
const rdr::U8 *oldpx = pb->getBuffer(pb->getRect(), &oldstride);
|
|
||||||
rdr::U8 *newpx = ((ManagedPixelBuffer *) newpb)->getBufferRW(newpb->getRect(),
|
|
||||||
&newstride);
|
|
||||||
|
|
||||||
SSE2_scale(oldpx, tgtw, tgth, newpx, oldstride, newstride, tgtw / (float) oldw);
|
|
||||||
if (del)
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newpb;
|
|
||||||
} // SSE2
|
|
||||||
|
|
||||||
if (tgtdiff >= 0.5f)
|
if (tgtdiff >= 0.5f)
|
||||||
return bilinearScale(pb, tgtw, tgth, tgtdiff);
|
return bilinearScale(pb, tgtw, tgth, tgtdiff);
|
||||||
|
|
||||||
|
|||||||
@@ -215,13 +215,6 @@ namespace rfb {
|
|||||||
virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
|
virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelBuffer *nearestScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
|
||||||
const float diff);
|
|
||||||
PixelBuffer *bilinearScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
|
||||||
const float diff);
|
|
||||||
PixelBuffer *progressiveBilinearScale(const PixelBuffer *pb, const uint16_t w, const uint16_t h,
|
|
||||||
const float diff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ namespace rfb {
|
|||||||
virtual void pointerEvent(const Point& __unused_attr pos,
|
virtual void pointerEvent(const Point& __unused_attr pos,
|
||||||
int __unused_attr buttonMask,
|
int __unused_attr buttonMask,
|
||||||
const bool __unused_attr skipClick,
|
const bool __unused_attr skipClick,
|
||||||
const bool __unused_attr skipRelease,
|
const bool __unused_attr skipRelease) { }
|
||||||
int scrollX,
|
|
||||||
int scrollY) { }
|
|
||||||
virtual void clientCutText(const char* __unused_attr str,
|
virtual void clientCutText(const char* __unused_attr str,
|
||||||
int __unused_attr len) { }
|
int __unused_attr len) { }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -284,26 +284,74 @@ void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SMsgHandler::setEncodings(nEncodings, encodings);
|
SMsgHandler::setEncodings(nEncodings, encodings);
|
||||||
|
|
||||||
|
if (cp.supportsExtendedClipboard) {
|
||||||
|
rdr::U32 sizes[] = { 0 };
|
||||||
|
writer()->writeClipboardCaps(rfb::clipboardUTF8 |
|
||||||
|
rfb::clipboardRequest |
|
||||||
|
rfb::clipboardPeek |
|
||||||
|
rfb::clipboardNotify |
|
||||||
|
rfb::clipboardProvide,
|
||||||
|
sizes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConnection::clearBinaryClipboard()
|
void SConnection::clientCutText(const char* str, int len)
|
||||||
{
|
{
|
||||||
binaryClipboard.clear();
|
hasLocalClipboard = false;
|
||||||
|
|
||||||
|
strFree(clientClipboard);
|
||||||
|
clientClipboard = NULL;
|
||||||
|
|
||||||
|
clientClipboard = latin1ToUTF8(str);
|
||||||
|
|
||||||
|
handleClipboardAnnounce(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConnection::addBinaryClipboard(const char mime[], const rdr::U8 *data,
|
void SConnection::handleClipboardRequest(rdr::U32 flags)
|
||||||
const rdr::U32 len)
|
|
||||||
{
|
{
|
||||||
binaryClipboard_t bin;
|
if (!(flags & rfb::clipboardUTF8))
|
||||||
strncpy(bin.mime, mime, sizeof(bin.mime));
|
return;
|
||||||
bin.mime[sizeof(bin.mime) - 1] = '\0';
|
if (!hasLocalClipboard)
|
||||||
|
return;
|
||||||
bin.data.resize(len);
|
handleClipboardRequest();
|
||||||
memcpy(&bin.data[0], data, len);
|
|
||||||
|
|
||||||
binaryClipboard.push_back(bin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SConnection::handleClipboardPeek(rdr::U32 flags)
|
||||||
|
{
|
||||||
|
if (!hasLocalClipboard)
|
||||||
|
return;
|
||||||
|
if (cp.clipboardFlags() & rfb::clipboardNotify)
|
||||||
|
writer()->writeClipboardNotify(rfb::clipboardUTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConnection::handleClipboardNotify(rdr::U32 flags)
|
||||||
|
{
|
||||||
|
strFree(clientClipboard);
|
||||||
|
clientClipboard = NULL;
|
||||||
|
|
||||||
|
if (flags & rfb::clipboardUTF8) {
|
||||||
|
handleClipboardAnnounce(true);
|
||||||
|
hasLocalClipboard = false;
|
||||||
|
} else {
|
||||||
|
handleClipboardAnnounce(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConnection::handleClipboardProvide(rdr::U32 flags,
|
||||||
|
const size_t* lengths,
|
||||||
|
const rdr::U8* const* data)
|
||||||
|
{
|
||||||
|
if (!(flags & rfb::clipboardUTF8))
|
||||||
|
return;
|
||||||
|
|
||||||
|
strFree(clientClipboard);
|
||||||
|
clientClipboard = NULL;
|
||||||
|
|
||||||
|
clientClipboard = convertLF((const char*)data[0], lengths[0]);
|
||||||
|
|
||||||
|
handleClipboardData(clientClipboard, strlen(clientClipboard));
|
||||||
|
}
|
||||||
|
|
||||||
void SConnection::supportsQEMUKeyEvent()
|
void SConnection::supportsQEMUKeyEvent()
|
||||||
{
|
{
|
||||||
@@ -397,13 +445,56 @@ void SConnection::enableContinuousUpdates(bool enable,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SConnection::handleClipboardRequest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void SConnection::handleClipboardAnnounce(bool available)
|
void SConnection::handleClipboardAnnounce(bool available)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SConnection::handleClipboardData(const char* data, int len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConnection::requestClipboard()
|
||||||
|
{
|
||||||
|
if (clientClipboard != NULL) {
|
||||||
|
handleClipboardData(clientClipboard, strlen(clientClipboard));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp.supportsExtendedClipboard &&
|
||||||
|
(cp.clipboardFlags() & rfb::clipboardRequest))
|
||||||
|
writer()->writeClipboardRequest(rfb::clipboardUTF8);
|
||||||
|
}
|
||||||
|
|
||||||
void SConnection::announceClipboard(bool available)
|
void SConnection::announceClipboard(bool available)
|
||||||
{
|
{
|
||||||
hasLocalClipboard = available;
|
hasLocalClipboard = available;
|
||||||
|
|
||||||
|
if (cp.supportsExtendedClipboard &&
|
||||||
|
(cp.clipboardFlags() & rfb::clipboardNotify))
|
||||||
|
writer()->writeClipboardNotify(available ? rfb::clipboardUTF8 : 0);
|
||||||
|
else {
|
||||||
|
if (available)
|
||||||
|
handleClipboardRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConnection::sendClipboardData(const char* data, int len)
|
||||||
|
{
|
||||||
|
if (cp.supportsExtendedClipboard &&
|
||||||
|
(cp.clipboardFlags() & rfb::clipboardProvide)) {
|
||||||
|
CharArray filtered(convertCRLF(data));
|
||||||
|
size_t sizes[1] = { strlen(filtered.buf) + 1 };
|
||||||
|
const rdr::U8* data[1] = { (const rdr::U8*)filtered.buf };
|
||||||
|
writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
|
||||||
|
} else {
|
||||||
|
CharArray latin1(utf8ToLatin1(data));
|
||||||
|
|
||||||
|
writer()->writeServerCutText(latin1.buf, strlen(latin1.buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConnection::writeFakeColourMap(void)
|
void SConnection::writeFakeColourMap(void)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include <rdr/OutStream.h>
|
#include <rdr/OutStream.h>
|
||||||
#include <rfb/SMsgHandler.h>
|
#include <rfb/SMsgHandler.h>
|
||||||
#include <rfb/SecurityServer.h>
|
#include <rfb/SecurityServer.h>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace rfb {
|
namespace rfb {
|
||||||
|
|
||||||
@@ -74,9 +73,14 @@ namespace rfb {
|
|||||||
|
|
||||||
virtual void setEncodings(int nEncodings, const rdr::S32* encodings);
|
virtual void setEncodings(int nEncodings, const rdr::S32* encodings);
|
||||||
|
|
||||||
virtual void clearBinaryClipboard();
|
virtual void clientCutText(const char* str, int len);
|
||||||
virtual void addBinaryClipboard(const char mime[], const rdr::U8 *data,
|
|
||||||
const rdr::U32 len);
|
virtual void handleClipboardRequest(rdr::U32 flags);
|
||||||
|
virtual void handleClipboardPeek(rdr::U32 flags);
|
||||||
|
virtual void handleClipboardNotify(rdr::U32 flags);
|
||||||
|
virtual void handleClipboardProvide(rdr::U32 flags,
|
||||||
|
const size_t* lengths,
|
||||||
|
const rdr::U8* const* data);
|
||||||
|
|
||||||
virtual void supportsQEMUKeyEvent();
|
virtual void supportsQEMUKeyEvent();
|
||||||
|
|
||||||
@@ -123,11 +127,25 @@ namespace rfb {
|
|||||||
virtual void enableContinuousUpdates(bool enable,
|
virtual void enableContinuousUpdates(bool enable,
|
||||||
int x, int y, int w, int h);
|
int x, int y, int w, int h);
|
||||||
|
|
||||||
|
// handleClipboardRequest() is called whenever the client requests
|
||||||
|
// the server to send over its clipboard data. It will only be
|
||||||
|
// called after the server has first announced a clipboard change
|
||||||
|
// via announceClipboard().
|
||||||
|
virtual void handleClipboardRequest();
|
||||||
|
|
||||||
// handleClipboardAnnounce() is called to indicate a change in the
|
// handleClipboardAnnounce() is called to indicate a change in the
|
||||||
// clipboard on the client. Call requestClipboard() to access the
|
// clipboard on the client. Call requestClipboard() to access the
|
||||||
// actual data.
|
// actual data.
|
||||||
virtual void handleClipboardAnnounce(bool available);
|
virtual void handleClipboardAnnounce(bool available);
|
||||||
|
|
||||||
|
// handleClipboardData() is called when the client has sent over
|
||||||
|
// the clipboard data as a result of a previous call to
|
||||||
|
// requestClipboard(). Note that this function might never be
|
||||||
|
// called if the clipboard data was no longer available when the
|
||||||
|
// client received the request.
|
||||||
|
virtual void handleClipboardData(const char* data, int len);
|
||||||
|
|
||||||
|
|
||||||
virtual void add_changed_all() {}
|
virtual void add_changed_all() {}
|
||||||
|
|
||||||
// setAccessRights() allows a security package to limit the access rights
|
// setAccessRights() allows a security package to limit the access rights
|
||||||
@@ -148,11 +166,22 @@ namespace rfb {
|
|||||||
|
|
||||||
// Other methods
|
// Other methods
|
||||||
|
|
||||||
|
// requestClipboard() will result in a request to the client to
|
||||||
|
// transfer its clipboard data. A call to handleClipboardData()
|
||||||
|
// will be made once the data is available.
|
||||||
|
virtual void requestClipboard();
|
||||||
|
|
||||||
// announceClipboard() informs the client of changes to the
|
// announceClipboard() informs the client of changes to the
|
||||||
// clipboard on the server. The client may later request the
|
// clipboard on the server. The client may later request the
|
||||||
// clipboard data via handleClipboardRequest().
|
// clipboard data via handleClipboardRequest().
|
||||||
virtual void announceClipboard(bool available);
|
virtual void announceClipboard(bool available);
|
||||||
|
|
||||||
|
// sendClipboardData() transfers the clipboard data to the client
|
||||||
|
// and should be called whenever the client has requested the
|
||||||
|
// clipboard via handleClipboardRequest().
|
||||||
|
virtual void sendClipboardData(const char* data, int len);
|
||||||
|
|
||||||
|
|
||||||
// authenticated() returns true if the client has authenticated
|
// authenticated() returns true if the client has authenticated
|
||||||
// successfully.
|
// successfully.
|
||||||
bool authenticated() { return (state_ == RFBSTATE_INITIALISATION ||
|
bool authenticated() { return (state_ == RFBSTATE_INITIALISATION ||
|
||||||
@@ -192,19 +221,12 @@ namespace rfb {
|
|||||||
|
|
||||||
rdr::S32 getPreferredEncoding() { return preferredEncoding; }
|
rdr::S32 getPreferredEncoding() { return preferredEncoding; }
|
||||||
|
|
||||||
struct binaryClipboard_t {
|
|
||||||
char mime[32];
|
|
||||||
std::vector<unsigned char> data;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setState(stateEnum s) { state_ = s; }
|
void setState(stateEnum s) { state_ = s; }
|
||||||
|
|
||||||
void setReader(SMsgReader *r) { reader_ = r; }
|
void setReader(SMsgReader *r) { reader_ = r; }
|
||||||
void setWriter(SMsgWriter *w) { writer_ = w; }
|
void setWriter(SMsgWriter *w) { writer_ = w; }
|
||||||
|
|
||||||
std::vector<binaryClipboard_t> binaryClipboard;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void writeFakeColourMap(void);
|
void writeFakeColourMap(void);
|
||||||
|
|
||||||
|
|||||||
@@ -78,13 +78,23 @@ namespace rfb {
|
|||||||
// the relevant RFB protocol messages from clients.
|
// the relevant RFB protocol messages from clients.
|
||||||
// See InputHandler for method signatures.
|
// See InputHandler for method signatures.
|
||||||
|
|
||||||
|
// handleClipboardRequest() is called whenever a client requests
|
||||||
|
// the server to send over its clipboard data. It will only be
|
||||||
|
// called after the server has first announced a clipboard change
|
||||||
|
// via VNCServer::announceClipboard().
|
||||||
|
virtual void handleClipboardRequest() {}
|
||||||
|
|
||||||
// handleClipboardAnnounce() is called to indicate a change in the
|
// handleClipboardAnnounce() is called to indicate a change in the
|
||||||
// clipboard on a client. Call VNCServer::requestClipboard() to
|
// clipboard on a client. Call VNCServer::requestClipboard() to
|
||||||
// access the actual data.
|
// access the actual data.
|
||||||
virtual void handleClipboardAnnounce(bool __unused_attr available) {}
|
virtual void handleClipboardAnnounce(bool __unused_attr available) {}
|
||||||
|
|
||||||
virtual void handleClipboardAnnounceBinary(const unsigned __unused_attr num,
|
// handleClipboardData() is called when a client has sent over
|
||||||
const char __unused_attr mimes[][32]) {}
|
// the clipboard data as a result of a previous call to
|
||||||
|
// VNCServer::requestClipboard(). Note that this function might
|
||||||
|
// never be called if the clipboard data was no longer available
|
||||||
|
// when the client received the request.
|
||||||
|
virtual void handleClipboardData(const char* __unused_attr data, int len __unused_attr) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~SDesktop() {}
|
virtual ~SDesktop() {}
|
||||||
|
|||||||
@@ -64,16 +64,26 @@ void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)
|
|||||||
supportsQEMUKeyEvent();
|
supportsQEMUKeyEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgHandler::handleClipboardAnnounceBinary(const unsigned, const char mimes[][32])
|
void SMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
|
||||||
|
{
|
||||||
|
cp.setClipboardCaps(flags, lengths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgHandler::handleClipboardRequest(rdr::U32 flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgHandler::clearBinaryClipboard()
|
void SMsgHandler::handleClipboardPeek(rdr::U32 flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgHandler::addBinaryClipboard(const char mime[], const rdr::U8 *data,
|
void SMsgHandler::handleClipboardNotify(rdr::U32 flags)
|
||||||
const rdr::U32 len)
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgHandler::handleClipboardProvide(rdr::U32 flags,
|
||||||
|
const size_t* lengths,
|
||||||
|
const rdr::U8* const* data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,10 +54,14 @@ namespace rfb {
|
|||||||
virtual void enableContinuousUpdates(bool enable,
|
virtual void enableContinuousUpdates(bool enable,
|
||||||
int x, int y, int w, int h) = 0;
|
int x, int y, int w, int h) = 0;
|
||||||
|
|
||||||
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
virtual void handleClipboardCaps(rdr::U32 flags,
|
||||||
virtual void clearBinaryClipboard();
|
const rdr::U32* lengths);
|
||||||
virtual void addBinaryClipboard(const char mime[], const rdr::U8 *data,
|
virtual void handleClipboardRequest(rdr::U32 flags);
|
||||||
const rdr::U32 len);
|
virtual void handleClipboardPeek(rdr::U32 flags);
|
||||||
|
virtual void handleClipboardNotify(rdr::U32 flags);
|
||||||
|
virtual void handleClipboardProvide(rdr::U32 flags,
|
||||||
|
const size_t* lengths,
|
||||||
|
const rdr::U8* const* data);
|
||||||
|
|
||||||
virtual void sendStats(const bool toClient = true) = 0;
|
virtual void sendStats(const bool toClient = true) = 0;
|
||||||
virtual void handleFrameStats(rdr::U32 all, rdr::U32 render) = 0;
|
virtual void handleFrameStats(rdr::U32 all, rdr::U32 render) = 0;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ using namespace rfb;
|
|||||||
|
|
||||||
static LogWriter vlog("SMsgReader");
|
static LogWriter vlog("SMsgReader");
|
||||||
|
|
||||||
|
static IntParameter maxCutText("MaxCutText", "Maximum permitted length of an incoming clipboard update", 256*1024);
|
||||||
|
|
||||||
SMsgReader::SMsgReader(SMsgHandler* handler_, rdr::InStream* is_)
|
SMsgReader::SMsgReader(SMsgHandler* handler_, rdr::InStream* is_)
|
||||||
: handler(handler_), is(is_)
|
: handler(handler_), is(is_)
|
||||||
{
|
{
|
||||||
@@ -81,9 +83,6 @@ void SMsgReader::readMsg()
|
|||||||
case msgTypeFrameStats:
|
case msgTypeFrameStats:
|
||||||
readFrameStats();
|
readFrameStats();
|
||||||
break;
|
break;
|
||||||
case msgTypeBinaryClipboard:
|
|
||||||
readBinaryClipboard();
|
|
||||||
break;
|
|
||||||
case msgTypeKeyEvent:
|
case msgTypeKeyEvent:
|
||||||
readKeyEvent();
|
readKeyEvent();
|
||||||
break;
|
break;
|
||||||
@@ -224,9 +223,7 @@ void SMsgReader::readPointerEvent()
|
|||||||
int mask = is->readU8();
|
int mask = is->readU8();
|
||||||
int x = is->readU16();
|
int x = is->readU16();
|
||||||
int y = is->readU16();
|
int y = is->readU16();
|
||||||
int scrollX = is->readS16();
|
handler->pointerEvent(Point(x, y), mask, false, false);
|
||||||
int scrollY = is->readS16();
|
|
||||||
handler->pointerEvent(Point(x, y), mask, false, false, scrollX, scrollY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -241,54 +238,109 @@ void SMsgReader::readClientCutText()
|
|||||||
readExtendedClipboard(slen);
|
readExtendedClipboard(slen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (len > (size_t)maxCutText) {
|
||||||
is->skip(len);
|
is->skip(len);
|
||||||
vlog.error("Client sent old cuttext msg, ignoring");
|
vlog.error("Cut text too long (%d bytes) - ignoring", len);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
CharArray ca(len+1);
|
||||||
void SMsgReader::readBinaryClipboard()
|
ca.buf[len] = 0;
|
||||||
{
|
|
||||||
const rdr::U8 num = is->readU8();
|
|
||||||
rdr::U8 i, valid = 0;
|
|
||||||
char tmpmimes[num][32];
|
|
||||||
|
|
||||||
handler->clearBinaryClipboard();
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
const rdr::U8 mimelen = is->readU8();
|
|
||||||
if (mimelen > 32 - 1) {
|
|
||||||
vlog.error("Mime too long (%u)", mimelen);
|
|
||||||
}
|
|
||||||
|
|
||||||
char mime[mimelen + 1];
|
|
||||||
mime[mimelen] = '\0';
|
|
||||||
is->readBytes(mime, mimelen);
|
|
||||||
|
|
||||||
strncpy(tmpmimes[valid], mime, 32);
|
|
||||||
tmpmimes[valid][31] = '\0';
|
|
||||||
|
|
||||||
const rdr::U32 len = is->readU32();
|
|
||||||
CharArray ca(len);
|
|
||||||
is->readBytes(ca.buf, len);
|
is->readBytes(ca.buf, len);
|
||||||
|
handler->clientCutText(ca.buf, len);
|
||||||
if (rfb::Server::DLP_ClipAcceptMax && len > (unsigned) rfb::Server::DLP_ClipAcceptMax) {
|
|
||||||
vlog.info("DLP: refused to receive binary clipboard, too large");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vlog.debug("Received binary clipboard, type %s, %u bytes", mime, len);
|
|
||||||
|
|
||||||
handler->addBinaryClipboard(mime, (rdr::U8 *) ca.buf, len);
|
|
||||||
valid++;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler->handleClipboardAnnounceBinary(valid, tmpmimes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgReader::readExtendedClipboard(rdr::S32 len)
|
void SMsgReader::readExtendedClipboard(rdr::S32 len)
|
||||||
{
|
{
|
||||||
|
rdr::U32 flags;
|
||||||
|
rdr::U32 action;
|
||||||
|
|
||||||
if (len < 4)
|
if (len < 4)
|
||||||
throw Exception("Invalid extended clipboard message");
|
throw Exception("Invalid extended clipboard message");
|
||||||
vlog.error("Client sent old cuttext msg, ignoring");
|
if (len > maxCutText) {
|
||||||
|
vlog.error("Extended clipboard message too long (%d bytes) - ignoring", len);
|
||||||
is->skip(len);
|
is->skip(len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = is->readU32();
|
||||||
|
action = flags & clipboardActionMask;
|
||||||
|
|
||||||
|
if (action & clipboardCaps) {
|
||||||
|
int i;
|
||||||
|
size_t num;
|
||||||
|
rdr::U32 lengths[16];
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (flags & (1 << i))
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < (rdr::S32)(4 + 4*num))
|
||||||
|
throw Exception("Invalid extended clipboard message");
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (flags & (1 << i))
|
||||||
|
lengths[num++] = is->readU32();
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->handleClipboardCaps(flags, lengths);
|
||||||
|
} else if (action == clipboardProvide) {
|
||||||
|
rdr::ZlibInStream zis;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
size_t num;
|
||||||
|
size_t lengths[16];
|
||||||
|
rdr::U8* buffers[16];
|
||||||
|
|
||||||
|
zis.setUnderlying(is, len - 4);
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (!(flags & 1 << i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lengths[num] = zis.readU32();
|
||||||
|
if (lengths[num] > (size_t)maxCutText) {
|
||||||
|
vlog.error("Extended clipboard data too long (%d bytes) - ignoring",
|
||||||
|
(unsigned)lengths[num]);
|
||||||
|
zis.skip(lengths[num]);
|
||||||
|
flags &= ~(1 << i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[num] = new rdr::U8[lengths[num]];
|
||||||
|
zis.readBytes(buffers[num], lengths[num]);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
zis.flushUnderlying();
|
||||||
|
zis.setUnderlying(NULL, 0);
|
||||||
|
|
||||||
|
handler->handleClipboardProvide(flags, lengths, buffers);
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (!(flags & 1 << i))
|
||||||
|
continue;
|
||||||
|
delete [] buffers[num++];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (action) {
|
||||||
|
case clipboardRequest:
|
||||||
|
handler->handleClipboardRequest(flags);
|
||||||
|
break;
|
||||||
|
case clipboardPeek:
|
||||||
|
handler->handleClipboardPeek(flags);
|
||||||
|
break;
|
||||||
|
case clipboardNotify:
|
||||||
|
handler->handleClipboardNotify(flags);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception("Invalid extended clipboard action");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgReader::readRequestStats()
|
void SMsgReader::readRequestStats()
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ namespace rfb {
|
|||||||
void readExtendedClipboard(rdr::S32 len);
|
void readExtendedClipboard(rdr::S32 len);
|
||||||
void readRequestStats();
|
void readRequestStats();
|
||||||
void readFrameStats();
|
void readFrameStats();
|
||||||
void readBinaryClipboard();
|
|
||||||
|
|
||||||
void readQEMUMessage();
|
void readQEMUMessage();
|
||||||
void readQEMUKeyEvent();
|
void readQEMUKeyEvent();
|
||||||
|
|||||||
@@ -85,21 +85,118 @@ void SMsgWriter::writeBell()
|
|||||||
endMsg();
|
endMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMsgWriter::writeBinaryClipboard(const std::vector<SConnection::binaryClipboard_t> &b)
|
void SMsgWriter::writeServerCutText(const char* str, int len)
|
||||||
{
|
{
|
||||||
startMsg(msgTypeBinaryClipboard);
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
os->writeU8(b.size());
|
os->writeU32(len);
|
||||||
rdr::U8 i;
|
os->writeBytes(str, len);
|
||||||
for (i = 0; i < b.size(); i++) {
|
endMsg();
|
||||||
const rdr::U8 mimelen = strlen(b[i].mime);
|
|
||||||
os->writeU8(mimelen);
|
|
||||||
os->writeBytes(b[i].mime, mimelen);
|
|
||||||
|
|
||||||
os->writeU32(b[i].data.size());
|
|
||||||
os->writeBytes(&b[i].data[0], b[i].data.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeClipboardCaps(rdr::U32 caps,
|
||||||
|
const rdr::U32* lengths)
|
||||||
|
{
|
||||||
|
size_t i, count;
|
||||||
|
|
||||||
|
if (!cp->supportsExtendedClipboard)
|
||||||
|
throw Exception("Client does not support extended clipboard");
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (caps & (1 << i))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
|
os->writeS32(-(4 + 4 * count));
|
||||||
|
|
||||||
|
os->writeU32(caps | clipboardCaps);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (caps & (1 << i))
|
||||||
|
os->writeU32(lengths[count++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeClipboardRequest(rdr::U32 flags)
|
||||||
|
{
|
||||||
|
if (!cp->supportsExtendedClipboard)
|
||||||
|
throw Exception("Client does not support extended clipboard");
|
||||||
|
if (!(cp->clipboardFlags() & clipboardRequest))
|
||||||
|
throw Exception("Client does not support clipboard \"request\" action");
|
||||||
|
|
||||||
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
|
os->writeS32(-4);
|
||||||
|
os->writeU32(flags | clipboardRequest);
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeClipboardPeek(rdr::U32 flags)
|
||||||
|
{
|
||||||
|
if (!cp->supportsExtendedClipboard)
|
||||||
|
throw Exception("Client does not support extended clipboard");
|
||||||
|
if (!(cp->clipboardFlags() & clipboardPeek))
|
||||||
|
throw Exception("Client does not support clipboard \"peek\" action");
|
||||||
|
|
||||||
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
|
os->writeS32(-4);
|
||||||
|
os->writeU32(flags | clipboardPeek);
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeClipboardNotify(rdr::U32 flags)
|
||||||
|
{
|
||||||
|
if (!cp->supportsExtendedClipboard)
|
||||||
|
throw Exception("Client does not support extended clipboard");
|
||||||
|
if (!(cp->clipboardFlags() & clipboardNotify))
|
||||||
|
throw Exception("Client does not support clipboard \"notify\" action");
|
||||||
|
|
||||||
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
|
os->writeS32(-4);
|
||||||
|
os->writeU32(flags | clipboardNotify);
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeClipboardProvide(rdr::U32 flags,
|
||||||
|
const size_t* lengths,
|
||||||
|
const rdr::U8* const* data)
|
||||||
|
{
|
||||||
|
rdr::MemOutStream mos;
|
||||||
|
rdr::ZlibOutStream zos;
|
||||||
|
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
if (!cp->supportsExtendedClipboard)
|
||||||
|
throw Exception("Client does not support extended clipboard");
|
||||||
|
if (!(cp->clipboardFlags() & clipboardProvide))
|
||||||
|
throw Exception("Client does not support clipboard \"provide\" action");
|
||||||
|
|
||||||
|
zos.setUnderlying(&mos);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (i = 0;i < 16;i++) {
|
||||||
|
if (!(flags & (1 << i)))
|
||||||
|
continue;
|
||||||
|
zos.writeU32(lengths[count]);
|
||||||
|
zos.writeBytes(data[count], lengths[count]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
zos.flush();
|
||||||
|
|
||||||
|
startMsg(msgTypeServerCutText);
|
||||||
|
os->pad(3);
|
||||||
|
os->writeS32(-(4 + mos.length()));
|
||||||
|
os->writeU32(flags | clipboardProvide);
|
||||||
|
os->writeBytes(mos.data(), mos.length());
|
||||||
endMsg();
|
endMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <rdr/types.h>
|
#include <rdr/types.h>
|
||||||
#include <rfb/encodings.h>
|
#include <rfb/encodings.h>
|
||||||
#include <rfb/ScreenSet.h>
|
#include <rfb/ScreenSet.h>
|
||||||
#include <rfb/SConnection.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace rdr { class OutStream; }
|
namespace rdr { class OutStream; }
|
||||||
|
|
||||||
@@ -56,8 +54,14 @@ namespace rfb {
|
|||||||
|
|
||||||
// writeBell() and writeServerCutText() do the obvious thing.
|
// writeBell() and writeServerCutText() do the obvious thing.
|
||||||
void writeBell();
|
void writeBell();
|
||||||
|
void writeServerCutText(const char* str, int len);
|
||||||
|
|
||||||
void writeBinaryClipboard(const std::vector<SConnection::binaryClipboard_t> &b);
|
void writeClipboardCaps(rdr::U32 caps, const rdr::U32* lengths);
|
||||||
|
void writeClipboardRequest(rdr::U32 flags);
|
||||||
|
void writeClipboardPeek(rdr::U32 flags);
|
||||||
|
void writeClipboardNotify(rdr::U32 flags);
|
||||||
|
void writeClipboardProvide(rdr::U32 flags, const size_t* lengths,
|
||||||
|
const rdr::U8* const* data);
|
||||||
|
|
||||||
void writeStats(const char* str, int len);
|
void writeStats(const char* str, int len);
|
||||||
|
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rfb/ComparingUpdateTracker.h>
|
|
||||||
#include <rfb/EncodeManager.h>
|
|
||||||
#include <rfb/LogWriter.h>
|
|
||||||
#include <rfb/SConnection.h>
|
|
||||||
#include <rfb/ServerCore.h>
|
|
||||||
#include <rfb/PixelBuffer.h>
|
|
||||||
#include <rfb/TightJPEGEncoder.h>
|
|
||||||
#include <rfb/TightWEBPEncoder.h>
|
|
||||||
#include <rfb/util.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
using namespace rfb;
|
|
||||||
static LogWriter vlog("SelfBench");
|
|
||||||
|
|
||||||
static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
|
|
||||||
|
|
||||||
#define RUNS 64
|
|
||||||
|
|
||||||
#define W 1600
|
|
||||||
#define H 1200
|
|
||||||
|
|
||||||
void SelfBench() {
|
|
||||||
|
|
||||||
unsigned i, runs;
|
|
||||||
struct timeval start;
|
|
||||||
|
|
||||||
ManagedPixelBuffer f1(pfRGBX, W, H);
|
|
||||||
ManagedPixelBuffer f2(pfRGBX, W, H);
|
|
||||||
ManagedPixelBuffer screen(pfRGBX, W, H);
|
|
||||||
|
|
||||||
int stride;
|
|
||||||
rdr::U8 *f1ptr = f1.getBufferRW(f1.getRect(), &stride);
|
|
||||||
rdr::U8 *f2ptr = f2.getBufferRW(f2.getRect(), &stride);
|
|
||||||
rdr::U8 * const screenptr = screen.getBufferRW(screen.getRect(), &stride);
|
|
||||||
|
|
||||||
rdr::U8 * const f1orig = f1ptr;
|
|
||||||
rdr::U8 * const f2orig = f2ptr;
|
|
||||||
|
|
||||||
for (i = 0; i < W * H * 4; i += 4) {
|
|
||||||
f1ptr[0] = rand();
|
|
||||||
f1ptr[1] = rand();
|
|
||||||
f1ptr[2] = rand();
|
|
||||||
|
|
||||||
f2ptr[0] = rand();
|
|
||||||
f2ptr[1] = rand();
|
|
||||||
f2ptr[2] = rand();
|
|
||||||
|
|
||||||
f1ptr += 4;
|
|
||||||
f2ptr += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
vlog.info("Running micro-benchmarks (single-threaded, runs depending on task)");
|
|
||||||
|
|
||||||
// Encoding
|
|
||||||
std::vector<uint8_t> vec;
|
|
||||||
|
|
||||||
TightJPEGEncoder jpeg(NULL);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
jpeg.compressOnly(&f1, 8, vec, false);
|
|
||||||
}
|
|
||||||
vlog.info("Jpeg compression at quality 8 took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
jpeg.compressOnly(&f1, 4, vec, false);
|
|
||||||
}
|
|
||||||
vlog.info("Jpeg compression at quality 4 took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
|
|
||||||
TightWEBPEncoder webp(NULL);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS / 8;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
webp.compressOnly(&f1, 8, vec, false);
|
|
||||||
}
|
|
||||||
vlog.info("Webp compression at quality 8 took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS / 4;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
webp.compressOnly(&f1, 4, vec, false);
|
|
||||||
}
|
|
||||||
vlog.info("Webp compression at quality 4 took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
// Scaling
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = nearestScale(&f1, W * 0.8, H * 0.8, 0.8);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Nearest scaling to 80%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = nearestScale(&f1, W * 0.4, H * 0.4, 0.4);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Nearest scaling to 40%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = bilinearScale(&f1, W * 0.8, H * 0.8, 0.8);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Bilinear scaling to 80%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = bilinearScale(&f1, W * 0.4, H * 0.4, 0.4);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Bilinear scaling to 40%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = progressiveBilinearScale(&f1, W * 0.8, H * 0.8, 0.8);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Progressive bilinear scaling to 80%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
PixelBuffer *pb = progressiveBilinearScale(&f1, W * 0.4, H * 0.4, 0.4);
|
|
||||||
delete pb;
|
|
||||||
}
|
|
||||||
vlog.info("Progressive bilinear scaling to 40%% took %u ms (%u runs)", msSince(&start), runs);
|
|
||||||
|
|
||||||
// Analysis
|
|
||||||
ComparingUpdateTracker *comparer = new ComparingUpdateTracker(&screen);
|
|
||||||
Region cursorReg;
|
|
||||||
|
|
||||||
Server::detectScrolling.setParam(false);
|
|
||||||
Server::detectHorizontal.setParam(false);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
memcpy(screenptr, i % 2 ? f1orig : f2orig, W * H * 4);
|
|
||||||
comparer->compare(true, cursorReg);
|
|
||||||
}
|
|
||||||
vlog.info("Analysis took %u ms (%u runs) (incl. memcpy overhead)", msSince(&start), runs);
|
|
||||||
|
|
||||||
Server::detectScrolling.setParam(true);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
memcpy(screenptr, i % 2 ? f1orig : f2orig, W * H * 4);
|
|
||||||
comparer->compare(false, cursorReg);
|
|
||||||
}
|
|
||||||
vlog.info("Analysis w/ scroll detection took %u ms (%u runs) (incl. memcpy overhead)", msSince(&start), runs);
|
|
||||||
|
|
||||||
Server::detectHorizontal.setParam(true);
|
|
||||||
delete comparer;
|
|
||||||
comparer = new ComparingUpdateTracker(&screen);
|
|
||||||
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
runs = RUNS / 2;
|
|
||||||
for (i = 0; i < runs; i++) {
|
|
||||||
memcpy(screenptr, i % 2 ? f1orig : f2orig, W * H * 4);
|
|
||||||
comparer->compare(false, cursorReg);
|
|
||||||
}
|
|
||||||
vlog.info("Analysis w/ horizontal scroll detection took %u ms (%u runs) (incl. memcpy overhead)", msSince(&start), runs);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
@@ -113,10 +113,6 @@ rfb::BoolParameter rfb::Server::ignoreClientSettingsKasm
|
|||||||
("IgnoreClientSettingsKasm",
|
("IgnoreClientSettingsKasm",
|
||||||
"Ignore the additional client settings exposed in Kasm.",
|
"Ignore the additional client settings exposed in Kasm.",
|
||||||
false);
|
false);
|
||||||
rfb::BoolParameter rfb::Server::selfBench
|
|
||||||
("SelfBench",
|
|
||||||
"Run self-benchmarks and exit.",
|
|
||||||
false);
|
|
||||||
rfb::IntParameter rfb::Server::dynamicQualityMin
|
rfb::IntParameter rfb::Server::dynamicQualityMin
|
||||||
("DynamicQualityMin",
|
("DynamicQualityMin",
|
||||||
"The minimum dynamic JPEG quality, 0 = low, 9 = high",
|
"The minimum dynamic JPEG quality, 0 = low, 9 = high",
|
||||||
@@ -149,15 +145,15 @@ rfb::IntParameter rfb::Server::webpVideoQuality
|
|||||||
rfb::IntParameter rfb::Server::DLP_ClipSendMax
|
rfb::IntParameter rfb::Server::DLP_ClipSendMax
|
||||||
("DLP_ClipSendMax",
|
("DLP_ClipSendMax",
|
||||||
"Limit clipboard bytes to send to clients in one transaction",
|
"Limit clipboard bytes to send to clients in one transaction",
|
||||||
0, 0, INT_MAX);
|
10000, 0, INT_MAX);
|
||||||
rfb::IntParameter rfb::Server::DLP_ClipAcceptMax
|
rfb::IntParameter rfb::Server::DLP_ClipAcceptMax
|
||||||
("DLP_ClipAcceptMax",
|
("DLP_ClipAcceptMax",
|
||||||
"Limit clipboard bytes to receive from clients in one transaction",
|
"Limit clipboard bytes to receive from clients in one transaction",
|
||||||
0, 0, INT_MAX);
|
10000, 0, INT_MAX);
|
||||||
rfb::IntParameter rfb::Server::DLP_ClipDelay
|
rfb::IntParameter rfb::Server::DLP_ClipDelay
|
||||||
("DLP_ClipDelay",
|
("DLP_ClipDelay",
|
||||||
"This many milliseconds must pass between clipboard actions",
|
"This many milliseconds must pass between clipboard actions",
|
||||||
0, 0, INT_MAX);
|
1000, 0, INT_MAX);
|
||||||
rfb::IntParameter rfb::Server::DLP_KeyRateLimit
|
rfb::IntParameter rfb::Server::DLP_KeyRateLimit
|
||||||
("DLP_KeyRateLimit",
|
("DLP_KeyRateLimit",
|
||||||
"Reject keyboard presses over this many per second",
|
"Reject keyboard presses over this many per second",
|
||||||
@@ -171,10 +167,6 @@ rfb::StringParameter rfb::Server::DLP_Region
|
|||||||
("DLP_Region",
|
("DLP_Region",
|
||||||
"Black out anything outside this region",
|
"Black out anything outside this region",
|
||||||
"");
|
"");
|
||||||
rfb::StringParameter rfb::Server::DLP_Clip_Types
|
|
||||||
("DLP_ClipTypes",
|
|
||||||
"Allowed binary clipboard mimetypes",
|
|
||||||
"text/html,image/png");
|
|
||||||
|
|
||||||
rfb::BoolParameter rfb::Server::DLP_RegionAllowClick
|
rfb::BoolParameter rfb::Server::DLP_RegionAllowClick
|
||||||
("DLP_RegionAllowClick",
|
("DLP_RegionAllowClick",
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ namespace rfb {
|
|||||||
static IntParameter DLP_KeyRateLimit;
|
static IntParameter DLP_KeyRateLimit;
|
||||||
static StringParameter DLP_ClipLog;
|
static StringParameter DLP_ClipLog;
|
||||||
static StringParameter DLP_Region;
|
static StringParameter DLP_Region;
|
||||||
static StringParameter DLP_Clip_Types;
|
|
||||||
static BoolParameter DLP_RegionAllowClick;
|
static BoolParameter DLP_RegionAllowClick;
|
||||||
static BoolParameter DLP_RegionAllowRelease;
|
static BoolParameter DLP_RegionAllowRelease;
|
||||||
static IntParameter jpegVideoQuality;
|
static IntParameter jpegVideoQuality;
|
||||||
@@ -75,7 +74,6 @@ namespace rfb {
|
|||||||
static BoolParameter detectScrolling;
|
static BoolParameter detectScrolling;
|
||||||
static BoolParameter detectHorizontal;
|
static BoolParameter detectHorizontal;
|
||||||
static BoolParameter ignoreClientSettingsKasm;
|
static BoolParameter ignoreClientSettingsKasm;
|
||||||
static BoolParameter selfBench;
|
|
||||||
static PresetParameter preferBandwidth;
|
static PresetParameter preferBandwidth;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ static const struct TightWEBPConfiguration conf[10] = {
|
|||||||
{ 24, 0 }, // 1
|
{ 24, 0 }, // 1
|
||||||
{ 30, 0 }, // 2
|
{ 30, 0 }, // 2
|
||||||
{ 37, 0 }, // 3
|
{ 37, 0 }, // 3
|
||||||
{ 42, 0 }, // 4
|
{ 42, 1 }, // 4
|
||||||
{ 65, 0 }, // 5
|
{ 65, 1 }, // 5
|
||||||
{ 78, 0 }, // 6
|
{ 78, 1 }, // 6
|
||||||
{ 85, 0 }, // 7
|
{ 85, 2 }, // 7
|
||||||
{ 88, 0 }, // 8
|
{ 88, 3 }, // 8
|
||||||
{ 100, 0 } // 9
|
{ 100, 4 } // 9
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ void TightWEBPEncoder::compressOnly(const PixelBuffer* pb, const uint8_t quality
|
|||||||
method = conf[qualityIn].method;
|
method = conf[qualityIn].method;
|
||||||
} else {
|
} else {
|
||||||
quality = 8;
|
quality = 8;
|
||||||
method = 0;
|
method = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPConfigInit(&cfg);
|
WebPConfigInit(&cfg);
|
||||||
@@ -214,7 +214,7 @@ void TightWEBPEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
|
|||||||
method = conf[qualityLevel].method;
|
method = conf[qualityLevel].method;
|
||||||
} else {
|
} else {
|
||||||
quality = 8;
|
quality = 8;
|
||||||
method = 0;
|
method = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPConfigInit(&cfg);
|
WebPConfigInit(&cfg);
|
||||||
@@ -265,7 +265,7 @@ rdr::U32 TightWEBPEncoder::benchmark() const
|
|||||||
rdr::U8* buffer;
|
rdr::U8* buffer;
|
||||||
struct timeval start;
|
struct timeval start;
|
||||||
int stride, i;
|
int stride, i;
|
||||||
const uint8_t quality = 8, method = 2;
|
const uint8_t quality = 8, method = 4;
|
||||||
WebPConfig cfg;
|
WebPConfig cfg;
|
||||||
WebPPicture pic;
|
WebPPicture pic;
|
||||||
WebPMemoryWriter wrt;
|
WebPMemoryWriter wrt;
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
|||||||
inProcessMessages(false),
|
inProcessMessages(false),
|
||||||
pendingSyncFence(false), syncFence(false), fenceFlags(0),
|
pendingSyncFence(false), syncFence(false), fenceFlags(0),
|
||||||
fenceDataLen(0), fenceData(NULL), congestionTimer(this),
|
fenceDataLen(0), fenceData(NULL), congestionTimer(this),
|
||||||
losslessTimer(this), kbdLogTimer(this), binclipTimer(this),
|
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
|
||||||
server(server_), updates(false),
|
|
||||||
updateRenderedCursor(false), removeRenderedCursor(false),
|
updateRenderedCursor(false), removeRenderedCursor(false),
|
||||||
continuousUpdates(false), encodeManager(this, &server_->encCache),
|
continuousUpdates(false), encodeManager(this, &server_->encCache),
|
||||||
needsPermCheck(false), pointerEventTime(0),
|
needsPermCheck(false), pointerEventTime(0),
|
||||||
@@ -414,6 +413,18 @@ static void keylog(unsigned keysym, const char *client) {
|
|||||||
flushKeylog(client);
|
flushKeylog(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::requestClipboardOrClose()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!(accessRights & AccessCutText)) return;
|
||||||
|
if (!rfb::Server::acceptCutText) return;
|
||||||
|
if (state() != RFBSTATE_NORMAL) return;
|
||||||
|
requestClipboard();
|
||||||
|
} catch(rdr::Exception& e) {
|
||||||
|
close(e.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::announceClipboardOrClose(bool available)
|
void VNCSConnectionST::announceClipboardOrClose(bool available)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -426,51 +437,29 @@ void VNCSConnectionST::announceClipboardOrClose(bool available)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::clearBinaryClipboardData()
|
void VNCSConnectionST::sendClipboardDataOrClose(const char* data)
|
||||||
{
|
|
||||||
clearBinaryClipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VNCSConnectionST::sendBinaryClipboardDataOrClose(const char* mime,
|
|
||||||
const unsigned char *data,
|
|
||||||
const unsigned len)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!(accessRights & AccessCutText)) return;
|
if (!(accessRights & AccessCutText)) return;
|
||||||
if (!rfb::Server::sendCutText) return;
|
if (!rfb::Server::sendCutText) return;
|
||||||
if (rfb::Server::DLP_ClipSendMax && len > (unsigned) rfb::Server::DLP_ClipSendMax) {
|
if (msSince(&lastClipboardOp) < (unsigned) rfb::Server::DLP_ClipDelay) {
|
||||||
vlog.info("DLP: client %s: refused to send binary clipboard, too large",
|
vlog.info("DLP: client %s: refused to send clipboard, too soon",
|
||||||
sock->getPeerAddress());
|
sock->getPeerAddress());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int len = strlen(data);
|
||||||
cliplog((const char *) data, len, len, "sent", sock->getPeerAddress());
|
const int origlen = len;
|
||||||
|
if (rfb::Server::DLP_ClipSendMax && len > rfb::Server::DLP_ClipSendMax)
|
||||||
|
len = rfb::Server::DLP_ClipSendMax;
|
||||||
|
cliplog(data, len, origlen, "sent", sock->getPeerAddress());
|
||||||
if (state() != RFBSTATE_NORMAL) return;
|
if (state() != RFBSTATE_NORMAL) return;
|
||||||
|
sendClipboardData(data, len);
|
||||||
addBinaryClipboard(mime, data, len);
|
gettimeofday(&lastClipboardOp, NULL);
|
||||||
binclipTimer.start(100);
|
|
||||||
} catch(rdr::Exception& e) {
|
} catch(rdr::Exception& e) {
|
||||||
close(e.str());
|
close(e.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::getBinaryClipboardData(const char* mime, const unsigned char **data,
|
|
||||||
unsigned *len)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < binaryClipboard.size(); i++) {
|
|
||||||
if (!strcmp(binaryClipboard[i].mime, mime)) {
|
|
||||||
*data = &binaryClipboard[i].data[0];
|
|
||||||
*len = binaryClipboard[i].data.size();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vlog.error("Binary clipboard data for mime %s not found", mime);
|
|
||||||
*data = (const unsigned char *) "";
|
|
||||||
*len = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VNCSConnectionST::setDesktopNameOrClose(const char *name)
|
void VNCSConnectionST::setDesktopNameOrClose(const char *name)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -703,7 +692,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
|
|||||||
setCursor();
|
setCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY)
|
void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease)
|
||||||
{
|
{
|
||||||
pointerEventTime = lastEventTime = time(0);
|
pointerEventTime = lastEventTime = time(0);
|
||||||
server->lastUserInputTime = lastEventTime;
|
server->lastUserInputTime = lastEventTime;
|
||||||
@@ -731,7 +720,7 @@ void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server->desktop->pointerEvent(pointerEventPos, buttonMask, skipclick, skiprelease, scrollX, scrollY);
|
server->desktop->pointerEvent(pointerEventPos, buttonMask, skipclick, skiprelease);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,6 +1014,12 @@ void VNCSConnectionST::enableContinuousUpdates(bool enable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::handleClipboardRequest()
|
||||||
|
{
|
||||||
|
if (!(accessRights & AccessCutText)) return;
|
||||||
|
server->handleClipboardRequest(this);
|
||||||
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::handleClipboardAnnounce(bool available)
|
void VNCSConnectionST::handleClipboardAnnounce(bool available)
|
||||||
{
|
{
|
||||||
if (!(accessRights & AccessCutText)) return;
|
if (!(accessRights & AccessCutText)) return;
|
||||||
@@ -1032,12 +1027,24 @@ void VNCSConnectionST::handleClipboardAnnounce(bool available)
|
|||||||
server->handleClipboardAnnounce(this, available);
|
server->handleClipboardAnnounce(this, available);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32])
|
void VNCSConnectionST::handleClipboardData(const char* data, int len)
|
||||||
{
|
{
|
||||||
if (!(accessRights & AccessCutText)) return;
|
if (!(accessRights & AccessCutText)) return;
|
||||||
if (!rfb::Server::acceptCutText) return;
|
if (!rfb::Server::acceptCutText) return;
|
||||||
server->handleClipboardAnnounceBinary(this, num, mimes);
|
if (msSince(&lastClipboardOp) < (unsigned) rfb::Server::DLP_ClipDelay) {
|
||||||
|
vlog.info("DLP: client %s: refused to receive clipboard, too soon",
|
||||||
|
sock->getPeerAddress());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const int origlen = len;
|
||||||
|
if (rfb::Server::DLP_ClipAcceptMax && len > rfb::Server::DLP_ClipAcceptMax)
|
||||||
|
len = rfb::Server::DLP_ClipAcceptMax;
|
||||||
|
cliplog(data, len, origlen, "received", sock->getPeerAddress());
|
||||||
|
|
||||||
|
gettimeofday(&lastClipboardOp, NULL);
|
||||||
|
server->handleClipboardData(this, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// supportsLocalCursor() is called whenever the status of
|
// supportsLocalCursor() is called whenever the status of
|
||||||
// cp.supportsLocalCursor has changed. If the client does now support local
|
// cp.supportsLocalCursor has changed. If the client does now support local
|
||||||
@@ -1082,8 +1089,6 @@ bool VNCSConnectionST::handleTimeout(Timer* t)
|
|||||||
writeFramebufferUpdate();
|
writeFramebufferUpdate();
|
||||||
else if (t == &kbdLogTimer)
|
else if (t == &kbdLogTimer)
|
||||||
flushKeylog(sock->getPeerAddress());
|
flushKeylog(sock->getPeerAddress());
|
||||||
else if (t == &binclipTimer)
|
|
||||||
writeBinaryClipboard();
|
|
||||||
} catch (rdr::Exception& e) {
|
} catch (rdr::Exception& e) {
|
||||||
close(e.str());
|
close(e.str());
|
||||||
}
|
}
|
||||||
@@ -1441,18 +1446,6 @@ void VNCSConnectionST::writeDataUpdate()
|
|||||||
requested.clear();
|
requested.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::writeBinaryClipboard()
|
|
||||||
{
|
|
||||||
if (msSince(&lastClipboardOp) < (unsigned) rfb::Server::DLP_ClipDelay) {
|
|
||||||
vlog.info("DLP: client %s: refused to send binary clipboard, too soon",
|
|
||||||
sock->getPeerAddress());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer()->writeBinaryClipboard(binaryClipboard);
|
|
||||||
|
|
||||||
gettimeofday(&lastClipboardOp, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
|
void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,12 +77,9 @@ namespace rfb {
|
|||||||
void bellOrClose();
|
void bellOrClose();
|
||||||
void setDesktopNameOrClose(const char *name);
|
void setDesktopNameOrClose(const char *name);
|
||||||
void setLEDStateOrClose(unsigned int state);
|
void setLEDStateOrClose(unsigned int state);
|
||||||
|
void requestClipboardOrClose();
|
||||||
void announceClipboardOrClose(bool available);
|
void announceClipboardOrClose(bool available);
|
||||||
void clearBinaryClipboardData();
|
void sendClipboardDataOrClose(const char* data);
|
||||||
void sendBinaryClipboardDataOrClose(const char* mime, const unsigned char *data,
|
|
||||||
const unsigned len);
|
|
||||||
void getBinaryClipboardData(const char* mime, const unsigned char **data,
|
|
||||||
unsigned *len);
|
|
||||||
|
|
||||||
// checkIdleTimeout() returns the number of milliseconds left until the
|
// checkIdleTimeout() returns the number of milliseconds left until the
|
||||||
// idle timeout expires. If it has expired, the connection is closed and
|
// idle timeout expires. If it has expired, the connection is closed and
|
||||||
@@ -207,7 +204,7 @@ namespace rfb {
|
|||||||
virtual void queryConnection(const char* userName);
|
virtual void queryConnection(const char* userName);
|
||||||
virtual void clientInit(bool shared);
|
virtual void clientInit(bool shared);
|
||||||
virtual void setPixelFormat(const PixelFormat& pf);
|
virtual void setPixelFormat(const PixelFormat& pf);
|
||||||
virtual void pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY);
|
virtual void pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease);
|
||||||
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
|
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
|
||||||
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
|
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
|
||||||
virtual void setDesktopSize(int fb_width, int fb_height,
|
virtual void setDesktopSize(int fb_width, int fb_height,
|
||||||
@@ -215,8 +212,9 @@ namespace rfb {
|
|||||||
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
|
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
|
||||||
virtual void enableContinuousUpdates(bool enable,
|
virtual void enableContinuousUpdates(bool enable,
|
||||||
int x, int y, int w, int h);
|
int x, int y, int w, int h);
|
||||||
|
virtual void handleClipboardRequest();
|
||||||
virtual void handleClipboardAnnounce(bool available);
|
virtual void handleClipboardAnnounce(bool available);
|
||||||
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
virtual void handleClipboardData(const char* data, int len);
|
||||||
virtual void supportsLocalCursor();
|
virtual void supportsLocalCursor();
|
||||||
virtual void supportsFence();
|
virtual void supportsFence();
|
||||||
virtual void supportsContinuousUpdates();
|
virtual void supportsContinuousUpdates();
|
||||||
@@ -262,8 +260,6 @@ namespace rfb {
|
|||||||
void writeNoDataUpdate();
|
void writeNoDataUpdate();
|
||||||
void writeDataUpdate();
|
void writeDataUpdate();
|
||||||
|
|
||||||
void writeBinaryClipboard();
|
|
||||||
|
|
||||||
void screenLayoutChange(rdr::U16 reason);
|
void screenLayoutChange(rdr::U16 reason);
|
||||||
void setCursor();
|
void setCursor();
|
||||||
void setCursorPos();
|
void setCursorPos();
|
||||||
@@ -286,7 +282,6 @@ namespace rfb {
|
|||||||
Timer congestionTimer;
|
Timer congestionTimer;
|
||||||
Timer losslessTimer;
|
Timer losslessTimer;
|
||||||
Timer kbdLogTimer;
|
Timer kbdLogTimer;
|
||||||
Timer binclipTimer;
|
|
||||||
|
|
||||||
VNCServerST* server;
|
VNCServerST* server;
|
||||||
SimpleUpdateTracker updates;
|
SimpleUpdateTracker updates;
|
||||||
|
|||||||
@@ -52,11 +52,22 @@ namespace rfb {
|
|||||||
// getPixelBuffer() returns a pointer to the PixelBuffer object.
|
// getPixelBuffer() returns a pointer to the PixelBuffer object.
|
||||||
virtual PixelBuffer* getPixelBuffer() const = 0;
|
virtual PixelBuffer* getPixelBuffer() const = 0;
|
||||||
|
|
||||||
|
// requestClipboard() will result in a request to a client to
|
||||||
|
// transfer its clipboard data. A call to
|
||||||
|
// SDesktop::handleClipboardData() will be made once the data is
|
||||||
|
// available.
|
||||||
|
virtual void requestClipboard() = 0;
|
||||||
|
|
||||||
// announceClipboard() informs all clients of changes to the
|
// announceClipboard() informs all clients of changes to the
|
||||||
// clipboard on the server. A client may later request the
|
// clipboard on the server. A client may later request the
|
||||||
// clipboard data via SDesktop::handleClipboardRequest().
|
// clipboard data via SDesktop::handleClipboardRequest().
|
||||||
virtual void announceClipboard(bool available) = 0;
|
virtual void announceClipboard(bool available) = 0;
|
||||||
|
|
||||||
|
// sendClipboardData() transfers the clipboard data to a client
|
||||||
|
// and should be called whenever a client has requested the
|
||||||
|
// clipboard via SDesktop::handleClipboardRequest().
|
||||||
|
virtual void sendClipboardData(const char* data) = 0;
|
||||||
|
|
||||||
// bell() tells the server that it should make all clients make a bell sound.
|
// bell() tells the server that it should make all clients make a bell sound.
|
||||||
virtual void bell() = 0;
|
virtual void bell() = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
#include <network/GetAPI.h>
|
#include <network/GetAPI.h>
|
||||||
|
|
||||||
#include <rfb/cpuid.h>
|
|
||||||
#include <rfb/ComparingUpdateTracker.h>
|
#include <rfb/ComparingUpdateTracker.h>
|
||||||
#include <rfb/KeyRemapper.h>
|
#include <rfb/KeyRemapper.h>
|
||||||
#include <rfb/ListConnInfo.h>
|
#include <rfb/ListConnInfo.h>
|
||||||
@@ -77,8 +76,6 @@ static LogWriter slog("VNCServerST");
|
|||||||
LogWriter VNCServerST::connectionsLog("Connections");
|
LogWriter VNCServerST::connectionsLog("Connections");
|
||||||
EncCache VNCServerST::encCache;
|
EncCache VNCServerST::encCache;
|
||||||
|
|
||||||
void SelfBench();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// -=- VNCServerST Implementation
|
// -=- VNCServerST Implementation
|
||||||
//
|
//
|
||||||
@@ -135,9 +132,6 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
|||||||
{
|
{
|
||||||
lastUserInputTime = lastDisconnectTime = time(0);
|
lastUserInputTime = lastDisconnectTime = time(0);
|
||||||
slog.debug("creating single-threaded server %s", name.buf);
|
slog.debug("creating single-threaded server %s", name.buf);
|
||||||
slog.info("CPU capability: SSE2 %s, AVX512f %s",
|
|
||||||
supportsSSE2() ? "yes" : "no",
|
|
||||||
supportsAVX512f() ? "yes" : "no");
|
|
||||||
|
|
||||||
DLPRegion.enabled = DLPRegion.percents = false;
|
DLPRegion.enabled = DLPRegion.percents = false;
|
||||||
|
|
||||||
@@ -218,9 +212,6 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
trackingClient[0] = 0;
|
trackingClient[0] = 0;
|
||||||
|
|
||||||
if (Server::selfBench)
|
|
||||||
SelfBench();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VNCServerST::~VNCServerST()
|
VNCServerST::~VNCServerST()
|
||||||
@@ -518,6 +509,14 @@ void VNCServerST::setScreenLayout(const ScreenSet& layout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCServerST::requestClipboard()
|
||||||
|
{
|
||||||
|
if (clipboardClient == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clipboardClient->requestClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
void VNCServerST::announceClipboard(bool available)
|
void VNCServerST::announceClipboard(bool available)
|
||||||
{
|
{
|
||||||
std::list<VNCSConnectionST*>::iterator ci, ci_next;
|
std::list<VNCSConnectionST*>::iterator ci, ci_next;
|
||||||
@@ -533,31 +532,20 @@ void VNCServerST::announceClipboard(bool available)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCServerST::sendBinaryClipboardData(const char* mime, const unsigned char *data,
|
void VNCServerST::sendClipboardData(const char* data)
|
||||||
const unsigned len)
|
|
||||||
{
|
{
|
||||||
std::list<VNCSConnectionST*>::iterator ci, ci_next;
|
std::list<VNCSConnectionST*>::iterator ci, ci_next;
|
||||||
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
|
|
||||||
|
if (strchr(data, '\r') != NULL)
|
||||||
|
throw Exception("Invalid carriage return in clipboard data");
|
||||||
|
|
||||||
|
for (ci = clipboardRequestors.begin();
|
||||||
|
ci != clipboardRequestors.end(); ci = ci_next) {
|
||||||
ci_next = ci; ci_next++;
|
ci_next = ci; ci_next++;
|
||||||
(*ci)->sendBinaryClipboardDataOrClose(mime, data, len);
|
(*ci)->sendClipboardDataOrClose(data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCServerST::getBinaryClipboardData(const char* mime, const unsigned char **data,
|
clipboardRequestors.clear();
|
||||||
unsigned *len)
|
|
||||||
{
|
|
||||||
if (!clipboardClient)
|
|
||||||
return;
|
|
||||||
clipboardClient->getBinaryClipboardData(mime, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VNCServerST::clearBinaryClipboardData()
|
|
||||||
{
|
|
||||||
std::list<VNCSConnectionST*>::iterator ci, ci_next;
|
|
||||||
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
|
|
||||||
ci_next = ci; ci_next++;
|
|
||||||
(*ci)->clearBinaryClipboardData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCServerST::bell()
|
void VNCServerST::bell()
|
||||||
@@ -1201,6 +1189,13 @@ bool VNCServerST::getComparerState()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCServerST::handleClipboardRequest(VNCSConnectionST* client)
|
||||||
|
{
|
||||||
|
clipboardRequestors.push_back(client);
|
||||||
|
if (clipboardRequestors.size() == 1)
|
||||||
|
desktop->handleClipboardRequest();
|
||||||
|
}
|
||||||
|
|
||||||
void VNCServerST::handleClipboardAnnounce(VNCSConnectionST* client,
|
void VNCServerST::handleClipboardAnnounce(VNCSConnectionST* client,
|
||||||
bool available)
|
bool available)
|
||||||
{
|
{
|
||||||
@@ -1214,10 +1209,11 @@ void VNCServerST::handleClipboardAnnounce(VNCSConnectionST* client,
|
|||||||
desktop->handleClipboardAnnounce(available);
|
desktop->handleClipboardAnnounce(available);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCServerST::handleClipboardAnnounceBinary(VNCSConnectionST* client,
|
void VNCServerST::handleClipboardData(VNCSConnectionST* client,
|
||||||
const unsigned num,
|
const char* data, int len)
|
||||||
const char mimes[][32])
|
|
||||||
{
|
{
|
||||||
clipboardClient = client;
|
if (client != clipboardClient)
|
||||||
desktop->handleClipboardAnnounceBinary(num, mimes);
|
return;
|
||||||
|
desktop->handleClipboardData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,12 +96,9 @@ namespace rfb {
|
|||||||
virtual void setPixelBuffer(PixelBuffer* pb);
|
virtual void setPixelBuffer(PixelBuffer* pb);
|
||||||
virtual void setScreenLayout(const ScreenSet& layout);
|
virtual void setScreenLayout(const ScreenSet& layout);
|
||||||
virtual PixelBuffer* getPixelBuffer() const { if (DLPRegion.enabled && blackedpb) return blackedpb; else return pb; }
|
virtual PixelBuffer* getPixelBuffer() const { if (DLPRegion.enabled && blackedpb) return blackedpb; else return pb; }
|
||||||
|
virtual void requestClipboard();
|
||||||
virtual void announceClipboard(bool available);
|
virtual void announceClipboard(bool available);
|
||||||
virtual void clearBinaryClipboardData();
|
virtual void sendClipboardData(const char* data);
|
||||||
virtual void sendBinaryClipboardData(const char* mime, const unsigned char *data,
|
|
||||||
const unsigned len);
|
|
||||||
virtual void getBinaryClipboardData(const char *mime, const unsigned char **ptr,
|
|
||||||
unsigned *len);
|
|
||||||
virtual void add_changed(const Region ®ion);
|
virtual void add_changed(const Region ®ion);
|
||||||
virtual void add_copied(const Region &dest, const Point &delta);
|
virtual void add_copied(const Region &dest, const Point &delta);
|
||||||
virtual void setCursor(int width, int height, const Point& hotspot,
|
virtual void setCursor(int width, int height, const Point& hotspot,
|
||||||
@@ -194,9 +191,9 @@ namespace rfb {
|
|||||||
|
|
||||||
void setAPIMessager(network::GetAPIMessager *msgr) { apimessager = msgr; }
|
void setAPIMessager(network::GetAPIMessager *msgr) { apimessager = msgr; }
|
||||||
|
|
||||||
|
void handleClipboardRequest(VNCSConnectionST* client);
|
||||||
void handleClipboardAnnounce(VNCSConnectionST* client, bool available);
|
void handleClipboardAnnounce(VNCSConnectionST* client, bool available);
|
||||||
void handleClipboardAnnounceBinary(VNCSConnectionST* client, const unsigned num,
|
void handleClipboardData(VNCSConnectionST* client, const char* data, int len);
|
||||||
const char mimes[][32]);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static uint32_t cpuid[4] = { 0 };
|
|
||||||
static uint32_t extcpuid[4] = { 0 };
|
|
||||||
|
|
||||||
static void getcpuid() {
|
|
||||||
if (cpuid[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
uint32_t eax, ecx = 0;
|
|
||||||
|
|
||||||
eax = 1; // normal feature bits
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"cpuid\n\t"
|
|
||||||
: "=a"(cpuid[0]), "=b"(cpuid[1]), "=c"(cpuid[2]), "=d"(cpuid[3])
|
|
||||||
: "0"(eax), "2"(ecx)
|
|
||||||
);
|
|
||||||
|
|
||||||
eax = 7; // ext feature bits
|
|
||||||
ecx = 0;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"cpuid\n\t"
|
|
||||||
: "=a"(extcpuid[0]), "=b"(extcpuid[1]), "=c"(extcpuid[2]), "=d"(extcpuid[3])
|
|
||||||
: "0"(eax), "2"(ecx)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
bool supportsSSE2() {
|
|
||||||
getcpuid();
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
#define bit_SSE2 (1 << 26)
|
|
||||||
return cpuid[3] & bit_SSE2;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool supportsAVX512f() {
|
|
||||||
getcpuid();
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
#define bit_AVX512f (1 << 16)
|
|
||||||
return extcpuid[1] & bit_AVX512f;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace rfb
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RFB_CPUID_H__
|
|
||||||
#define __RFB_CPUID_H__
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
bool supportsSSE2();
|
|
||||||
bool supportsAVX512f();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -31,7 +31,6 @@ namespace rfb {
|
|||||||
// kasm
|
// kasm
|
||||||
const int msgTypeStats = 178;
|
const int msgTypeStats = 178;
|
||||||
const int msgTypeRequestFrameStats = 179;
|
const int msgTypeRequestFrameStats = 179;
|
||||||
const int msgTypeBinaryClipboard = 180;
|
|
||||||
|
|
||||||
const int msgTypeServerFence = 248;
|
const int msgTypeServerFence = 248;
|
||||||
|
|
||||||
@@ -50,7 +49,6 @@ namespace rfb {
|
|||||||
// kasm
|
// kasm
|
||||||
const int msgTypeRequestStats = 178;
|
const int msgTypeRequestStats = 178;
|
||||||
const int msgTypeFrameStats = 179;
|
const int msgTypeFrameStats = 179;
|
||||||
//const int msgTypeBinaryClipboard = 180;
|
|
||||||
|
|
||||||
const int msgTypeClientFence = 248;
|
const int msgTypeClientFence = 248;
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rfb/scale_sse2.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
void SSE2_halve(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles factors between 0.5 and 1.0
|
|
||||||
void SSE2_scale(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride,
|
|
||||||
const float tgtdiff) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace rfb
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <emmintrin.h>
|
|
||||||
|
|
||||||
#include <rfb/scale_sse2.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
/*
|
|
||||||
static void print128(const char msg[], const __m128i v) {
|
|
||||||
union {
|
|
||||||
__m128i v;
|
|
||||||
uint8_t c[16];
|
|
||||||
} u;
|
|
||||||
|
|
||||||
u.v = v;
|
|
||||||
|
|
||||||
printf("%s %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n",
|
|
||||||
msg,
|
|
||||||
u.c[0],
|
|
||||||
u.c[1],
|
|
||||||
u.c[2],
|
|
||||||
u.c[3],
|
|
||||||
u.c[4],
|
|
||||||
u.c[5],
|
|
||||||
u.c[6],
|
|
||||||
u.c[7],
|
|
||||||
u.c[8],
|
|
||||||
u.c[9],
|
|
||||||
u.c[10],
|
|
||||||
u.c[11],
|
|
||||||
u.c[12],
|
|
||||||
u.c[13],
|
|
||||||
u.c[14],
|
|
||||||
u.c[15]);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void SSE2_halve(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride) {
|
|
||||||
uint16_t x, y;
|
|
||||||
const uint16_t srcw = tgtw * 2, srch = tgth * 2;
|
|
||||||
const __m128i zero = _mm_setzero_si128();
|
|
||||||
const __m128i shift = _mm_set_epi32(0, 0, 0, 2);
|
|
||||||
const __m128i low = _mm_set_epi32(0, 0, 0xffffffff, 0xffffffff);
|
|
||||||
const __m128i high = _mm_set_epi32(0xffffffff, 0xffffffff, 0, 0);
|
|
||||||
|
|
||||||
for (y = 0; y < srch; y += 2) {
|
|
||||||
const uint8_t * const row0 = oldpx + oldstride * y * 4;
|
|
||||||
const uint8_t * const row1 = oldpx + oldstride * (y + 1) * 4;
|
|
||||||
|
|
||||||
uint8_t * const dst = newpx + newstride * (y / 2) * 4;
|
|
||||||
|
|
||||||
for (x = 0; x < srcw - 3; x += 4) {
|
|
||||||
__m128i lo, hi, a, b, c, d;
|
|
||||||
lo = _mm_loadu_si128((__m128i *) &row0[x * 4]);
|
|
||||||
hi = _mm_loadu_si128((__m128i *) &row1[x * 4]);
|
|
||||||
|
|
||||||
a = _mm_unpacklo_epi8(lo, zero);
|
|
||||||
b = _mm_unpackhi_epi8(lo, zero);
|
|
||||||
c = _mm_unpacklo_epi8(hi, zero);
|
|
||||||
d = _mm_unpackhi_epi8(hi, zero);
|
|
||||||
|
|
||||||
a = _mm_add_epi16(a, c);
|
|
||||||
b = _mm_add_epi16(b, d);
|
|
||||||
|
|
||||||
c = _mm_srli_si128(a, 8);
|
|
||||||
a = _mm_and_si128(a, low);
|
|
||||||
a = _mm_add_epi16(a, c);
|
|
||||||
|
|
||||||
d = _mm_slli_si128(b, 8);
|
|
||||||
b = _mm_and_si128(b, high);
|
|
||||||
b = _mm_add_epi16(b, d);
|
|
||||||
|
|
||||||
a = _mm_add_epi16(a, b);
|
|
||||||
|
|
||||||
a = _mm_srl_epi16(a, shift);
|
|
||||||
a = _mm_packus_epi16(a, zero);
|
|
||||||
|
|
||||||
_mm_storel_epi64((__m128i *) &dst[(x / 2) * 4], a);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; x < srcw; x += 2) {
|
|
||||||
// Remainder in C
|
|
||||||
uint8_t i;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
dst[(x / 2) * 4 + i] =
|
|
||||||
(row0[x * 4 + i] +
|
|
||||||
row0[(x + 1) * 4 + i] +
|
|
||||||
row1[x * 4 + i] +
|
|
||||||
row1[(x + 1) * 4 + i]) / 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles factors between 0.5 and 1.0
|
|
||||||
void SSE2_scale(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride,
|
|
||||||
const float tgtdiff) {
|
|
||||||
|
|
||||||
uint16_t x, y;
|
|
||||||
const __m128i zero = _mm_setzero_si128();
|
|
||||||
const __m128i low = _mm_set_epi32(0, 0, 0xffffffff, 0xffffffff);
|
|
||||||
const __m128i high = _mm_set_epi32(0xffffffff, 0xffffffff, 0, 0);
|
|
||||||
const float invdiff = 1 / tgtdiff;
|
|
||||||
|
|
||||||
for (y = 0; y < tgth; y++) {
|
|
||||||
const float ny = y * invdiff;
|
|
||||||
const uint16_t lowy = ny;
|
|
||||||
const uint16_t highy = lowy + 1;
|
|
||||||
const uint16_t bot = (ny - lowy) * 256;
|
|
||||||
const uint16_t top = 256 - bot;
|
|
||||||
const uint32_t * const row0 = (uint32_t *) (oldpx + oldstride * lowy * 4);
|
|
||||||
const uint32_t * const row1 = (uint32_t *) (oldpx + oldstride * highy * 4);
|
|
||||||
const uint8_t * const brow0 = (uint8_t *) row0;
|
|
||||||
const uint8_t * const brow1 = (uint8_t *) row1;
|
|
||||||
|
|
||||||
uint8_t * const dst = newpx + newstride * y * 4;
|
|
||||||
|
|
||||||
const __m128i vertmul = _mm_set1_epi16(top);
|
|
||||||
const __m128i vertmul2 = _mm_set1_epi16(bot);
|
|
||||||
|
|
||||||
for (x = 0; x < tgtw - 1; x += 2) {
|
|
||||||
const float nx[2] = {
|
|
||||||
x * invdiff,
|
|
||||||
(x + 1) * invdiff,
|
|
||||||
};
|
|
||||||
const uint16_t lowx[2] = {
|
|
||||||
(uint16_t) nx[0],
|
|
||||||
(uint16_t) nx[1],
|
|
||||||
};
|
|
||||||
const uint16_t highx[2] = {
|
|
||||||
(uint16_t) (lowx[0] + 1),
|
|
||||||
(uint16_t) (lowx[1] + 1),
|
|
||||||
};
|
|
||||||
const uint16_t right[2] = {
|
|
||||||
(uint16_t) ((nx[0] - lowx[0]) * 256),
|
|
||||||
(uint16_t) ((nx[1] - lowx[1]) * 256),
|
|
||||||
};
|
|
||||||
const uint16_t left[2] = {
|
|
||||||
(uint16_t) (256 - right[0]),
|
|
||||||
(uint16_t) (256 - right[1]),
|
|
||||||
};
|
|
||||||
|
|
||||||
const __m128i horzmul = _mm_set_epi16(
|
|
||||||
right[0],
|
|
||||||
right[0],
|
|
||||||
right[0],
|
|
||||||
right[0],
|
|
||||||
left[0],
|
|
||||||
left[0],
|
|
||||||
left[0],
|
|
||||||
left[0]
|
|
||||||
);
|
|
||||||
const __m128i horzmul2 = _mm_set_epi16(
|
|
||||||
right[1],
|
|
||||||
right[1],
|
|
||||||
right[1],
|
|
||||||
right[1],
|
|
||||||
left[1],
|
|
||||||
left[1],
|
|
||||||
left[1],
|
|
||||||
left[1]
|
|
||||||
);
|
|
||||||
|
|
||||||
__m128i lo, hi, a, b, c, d;
|
|
||||||
lo = _mm_setr_epi32(row0[lowx[0]],
|
|
||||||
row0[highx[0]],
|
|
||||||
row0[lowx[1]],
|
|
||||||
row0[highx[1]]);
|
|
||||||
hi = _mm_setr_epi32(row1[lowx[0]],
|
|
||||||
row1[highx[0]],
|
|
||||||
row1[lowx[1]],
|
|
||||||
row1[highx[1]]);
|
|
||||||
|
|
||||||
a = _mm_unpacklo_epi8(lo, zero);
|
|
||||||
b = _mm_unpackhi_epi8(lo, zero);
|
|
||||||
c = _mm_unpacklo_epi8(hi, zero);
|
|
||||||
d = _mm_unpackhi_epi8(hi, zero);
|
|
||||||
|
|
||||||
a = _mm_mullo_epi16(a, vertmul);
|
|
||||||
b = _mm_mullo_epi16(b, vertmul);
|
|
||||||
c = _mm_mullo_epi16(c, vertmul2);
|
|
||||||
d = _mm_mullo_epi16(d, vertmul2);
|
|
||||||
|
|
||||||
a = _mm_add_epi16(a, c);
|
|
||||||
a = _mm_srli_epi16(a, 8);
|
|
||||||
b = _mm_add_epi16(b, d);
|
|
||||||
b = _mm_srli_epi16(b, 8);
|
|
||||||
|
|
||||||
a = _mm_mullo_epi16(a, horzmul);
|
|
||||||
b = _mm_mullo_epi16(b, horzmul2);
|
|
||||||
|
|
||||||
lo = _mm_srli_si128(a, 8);
|
|
||||||
a = _mm_and_si128(a, low);
|
|
||||||
a = _mm_add_epi16(a, lo);
|
|
||||||
|
|
||||||
hi = _mm_slli_si128(b, 8);
|
|
||||||
b = _mm_and_si128(b, high);
|
|
||||||
b = _mm_add_epi16(b, hi);
|
|
||||||
|
|
||||||
a = _mm_add_epi16(a, b);
|
|
||||||
a = _mm_srli_epi16(a, 8);
|
|
||||||
|
|
||||||
a = _mm_packus_epi16(a, zero);
|
|
||||||
|
|
||||||
_mm_storel_epi64((__m128i *) &dst[x * 4], a);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; x < tgtw; x++) {
|
|
||||||
// Remainder in C
|
|
||||||
const float nx = x * invdiff;
|
|
||||||
const uint16_t lowx = nx;
|
|
||||||
const uint16_t highx = lowx + 1;
|
|
||||||
const uint16_t right = (nx - lowx) * 256;
|
|
||||||
const uint16_t left = 256 - right;
|
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
uint32_t val, val2;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
val = brow0[lowx * 4 + i] * left;
|
|
||||||
val += brow0[highx * 4 + i] * right;
|
|
||||||
val >>= 8;
|
|
||||||
|
|
||||||
val2 = brow1[lowx * 4 + i] * left;
|
|
||||||
val2 += brow1[highx * 4 + i] * right;
|
|
||||||
val2 >>= 8;
|
|
||||||
|
|
||||||
dst[x * 4 + i] =
|
|
||||||
(val * top + val2 * bot) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace rfb
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* Copyright (C) 2021 Kasm Web
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this software; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RFB_SCALE_SSE2_H__
|
|
||||||
#define __RFB_SCALE_SSE2_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
namespace rfb {
|
|
||||||
|
|
||||||
void SSE2_halve(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride);
|
|
||||||
|
|
||||||
void SSE2_scale(const uint8_t *oldpx,
|
|
||||||
const uint16_t tgtw, const uint16_t tgth,
|
|
||||||
uint8_t *newpx,
|
|
||||||
const unsigned oldstride, const unsigned newstride,
|
|
||||||
const float tgtdiff);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
6
debian/Makefile.to_fakebuild_tar_package
vendored
6
debian/Makefile.to_fakebuild_tar_package
vendored
@@ -1,7 +1,7 @@
|
|||||||
TARGET_OS := $(shell lsb_release -is | tr '[:upper:]' '[:lower:]')
|
TARGET_OS := $(shell lsb_release -is | tr '[:upper:]' '[:lower:]')
|
||||||
TARGET_OS_CODENAME := $(shell lsb_release -cs | tr '[:upper:]' '[:lower:]')
|
TARGET_OS_CODENAME := $(shell lsb_release -cs | tr '[:upper:]' '[:lower:]')
|
||||||
TARBALL_DIR := builder/build
|
TARBALL_DIR := builder/build
|
||||||
TARBALL := $(TARBALL_DIR)/kasmvnc.$(TARGET_OS)_$(TARGET_OS_CODENAME)$(BUILD_TAG).tar.gz
|
TARBALL := $(TARBALL_DIR)/kasmvnc.$(TARGET_OS)_$(TARGET_OS_CODENAME).tar.gz
|
||||||
TAR_DATA := $(shell mktemp -d)
|
TAR_DATA := $(shell mktemp -d)
|
||||||
SRC := $(TAR_DATA)/usr/local
|
SRC := $(TAR_DATA)/usr/local
|
||||||
SRC_BIN := $(SRC)/bin
|
SRC_BIN := $(SRC)/bin
|
||||||
@@ -11,12 +11,12 @@ install: unpack_tarball
|
|||||||
echo "TAR_DATA: $(TAR_DATA)"
|
echo "TAR_DATA: $(TAR_DATA)"
|
||||||
echo "installing files"
|
echo "installing files"
|
||||||
mkdir -p $(DESTDIR)/usr/bin $(DESTDIR)/usr/share/man/man1 \
|
mkdir -p $(DESTDIR)/usr/bin $(DESTDIR)/usr/share/man/man1 \
|
||||||
$(DESTDIR)/usr/share/doc/kasmvncserver $(DESTDIR)/usr/lib
|
$(DESTDIR)/usr/share/doc/kasmvncserver
|
||||||
cp $(SRC_BIN)/Xvnc $(DESTDIR)/usr/bin/Xkasmvnc
|
cp $(SRC_BIN)/Xvnc $(DESTDIR)/usr/bin/Xkasmvnc
|
||||||
cp $(SRC_BIN)/vncserver $(DESTDIR)/usr/bin/kasmvncserver
|
cp $(SRC_BIN)/vncserver $(DESTDIR)/usr/bin/kasmvncserver
|
||||||
cp $(SRC_BIN)/vncconfig $(DESTDIR)/usr/bin/kasmvncconfig
|
cp $(SRC_BIN)/vncconfig $(DESTDIR)/usr/bin/kasmvncconfig
|
||||||
cp $(SRC_BIN)/kasmvncpasswd $(DESTDIR)/usr/bin/
|
cp $(SRC_BIN)/kasmvncpasswd $(DESTDIR)/usr/bin/
|
||||||
cp -r $(SRC)/lib/kasmvnc/ $(DESTDIR)/usr/lib/kasmvncserver
|
cp $(SRC_BIN)/kasmxproxy $(DESTDIR)/usr/bin/
|
||||||
cp -r $(SRC)/share/doc/kasmvnc*/* $(DESTDIR)/usr/share/doc/kasmvncserver/
|
cp -r $(SRC)/share/doc/kasmvnc*/* $(DESTDIR)/usr/share/doc/kasmvncserver/
|
||||||
rsync -r --exclude '.git*' --exclude po2js --exclude xgettext-html \
|
rsync -r --exclude '.git*' --exclude po2js --exclude xgettext-html \
|
||||||
--exclude www/utils/ --exclude .eslintrc \
|
--exclude www/utils/ --exclude .eslintrc \
|
||||||
|
|||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,9 +1,3 @@
|
|||||||
kasmvnc (0.9.3~beta-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* New upstream release.
|
|
||||||
|
|
||||||
-- Dmitry Maksyoma <ledestin@gmail.com> Fri, 29 Oct 2021 19:16:33 +1300
|
|
||||||
|
|
||||||
kasmvnc (0.9.1~beta-1) unstable; urgency=medium
|
kasmvnc (0.9.1~beta-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Initial release of the Debian package.
|
* Initial release of the Debian package.
|
||||||
|
|||||||
7
debian/control
vendored
7
debian/control
vendored
@@ -3,17 +3,16 @@ Section: x11
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Kasm Technologies LLC <info@kasmweb.com>
|
Maintainer: Kasm Technologies LLC <info@kasmweb.com>
|
||||||
Build-Depends: debhelper (>= 11), rsync, libjpeg-dev, libjpeg-dev, libpng-dev,
|
Build-Depends: debhelper (>= 11), rsync, libjpeg-dev, libjpeg-dev, libpng-dev,
|
||||||
libtiff-dev, libgif-dev, libavcodec-dev, libssl-dev, libgl1, libxfont2, libsm6, libunwind8
|
libtiff-dev, libgif-dev, libavcodec-dev, libssl-dev, libgl1, libxfont2, libsm6, libxext-dev, libxrandr-dev, libxtst-dev, libxcursor-dev
|
||||||
Standards-Version: 4.1.3
|
Standards-Version: 4.1.3
|
||||||
Homepage: https://github.com/kasmtech/KasmVNC
|
Homepage: https://github.com/kasmtech/KasmVNC
|
||||||
#Vcs-Browser: https://salsa.debian.org/debian/kasmvnc
|
#Vcs-Browser: https://salsa.debian.org/debian/kasmvnc
|
||||||
#Vcs-Git: https://salsa.debian.org/debian/kasmvnc.git
|
#Vcs-Git: https://salsa.debian.org/debian/kasmvnc.git
|
||||||
|
|
||||||
Package: kasmvncserver
|
Package: kasmvncserver
|
||||||
Architecture: amd64 arm64
|
Architecture: amd64
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, ssl-cert, xauth,
|
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, ssl-cert, xauth,
|
||||||
x11-xkb-utils, xkb-data, procps, libswitch-perl, libyaml-tiny-perl,
|
x11-xkb-utils, xkb-data, procps
|
||||||
libhash-merge-simple-perl, libscalar-list-utils-perl
|
|
||||||
Provides: vnc-server
|
Provides: vnc-server
|
||||||
Description: VNC server accessible from a web browser
|
Description: VNC server accessible from a web browser
|
||||||
VNC stands for Virtual Network Computing. It is, in essence, a remote
|
VNC stands for Virtual Network Computing. It is, in essence, a remote
|
||||||
|
|||||||
2
debian/postinst
vendored
2
debian/postinst
vendored
@@ -21,7 +21,7 @@ case "$1" in
|
|||||||
configure)
|
configure)
|
||||||
bindir=/usr/bin
|
bindir=/usr/bin
|
||||||
mandir=/usr/share/man
|
mandir=/usr/share/man
|
||||||
commands="kasmvncserver kasmvncpasswd kasmvncconfig Xkasmvnc"
|
commands="kasmvncserver kasmvncpasswd kasmvncconfig Xkasmvnc kasmxproxy"
|
||||||
|
|
||||||
for kasm_command in $commands; do
|
for kasm_command in $commands; do
|
||||||
generic_command=`echo "$kasm_command" | sed -e 's/kasm//'`;
|
generic_command=`echo "$kasm_command" | sed -e 's/kasm//'`;
|
||||||
|
|||||||
2
debian/prerm
vendored
2
debian/prerm
vendored
@@ -21,7 +21,7 @@ case "$1" in
|
|||||||
remove)
|
remove)
|
||||||
bindir=/usr/bin
|
bindir=/usr/bin
|
||||||
mandir=/usr/share/man
|
mandir=/usr/share/man
|
||||||
commands="kasmvncserver kasmvncpasswd kasmvncconfig Xkasmvnc"
|
commands="kasmvncserver kasmvncpasswd kasmvncconfig Xkasmvnc kasmxproxy"
|
||||||
|
|
||||||
for kasm_command in $commands; do
|
for kasm_command in $commands; do
|
||||||
generic_command=`echo "$kasm_command" | sed -e 's/kasm//'`;
|
generic_command=`echo "$kasm_command" | sed -e 's/kasm//'`;
|
||||||
|
|||||||
2
kasmweb
2
kasmweb
Submodule kasmweb updated: 9383783efd...ba40cacce0
@@ -45,13 +45,12 @@ mkdir -p $OUTDIR/man/man1
|
|||||||
|
|
||||||
make DESTDIR=$TMPDIR/inst install
|
make DESTDIR=$TMPDIR/inst install
|
||||||
if [ $SERVER = 1 ]; then
|
if [ $SERVER = 1 ]; then
|
||||||
|
install -m 755 ./unix/kasmxproxy/kasmxproxy $OUTDIR/bin/
|
||||||
install -m 755 ./xorg.build/bin/Xvnc $OUTDIR/bin/
|
install -m 755 ./xorg.build/bin/Xvnc $OUTDIR/bin/
|
||||||
install -m 644 ./xorg.build/man/man1/Xvnc.1 $OUTDIR/man/man1/Xvnc.1
|
install -m 644 ./xorg.build/man/man1/Xvnc.1 $OUTDIR/man/man1/Xvnc.1
|
||||||
install -m 644 ./xorg.build/man/man1/Xserver.1 $OUTDIR/man/man1/Xserver.1
|
install -m 644 ./xorg.build/man/man1/Xserver.1 $OUTDIR/man/man1/Xserver.1
|
||||||
mkdir -p $OUTDIR/lib/dri/
|
mkdir -p $OUTDIR/lib/dri/
|
||||||
install -m 755 ./xorg.build/lib/dri/swrast_dri.so $OUTDIR/lib/dri/
|
install -m 755 ./xorg.build/lib/dri/swrast_dri.so $OUTDIR/lib/dri/
|
||||||
mkdir -p $OUTDIR/lib/kasmvnc
|
|
||||||
install -m 755 $SRCDIR/builder/startup/deb/select-de.sh $OUTDIR/lib/kasmvnc
|
|
||||||
mkdir -p $OUTDIR/share/kasmvnc
|
mkdir -p $OUTDIR/share/kasmvnc
|
||||||
cp -r $SRCDIR/builder/www $OUTDIR/share/kasmvnc/www
|
cp -r $SRCDIR/builder/www $OUTDIR/share/kasmvnc/www
|
||||||
fi
|
fi
|
||||||
|
|||||||
12
run-specs
12
run-specs
@@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
export PYTHONPATH=${PWD}/spec
|
|
||||||
|
|
||||||
RUN_CMD="pipenv run mamba"
|
|
||||||
|
|
||||||
if [[ -n "$1" ]]; then
|
|
||||||
$RUN_CMD "$1"
|
|
||||||
else
|
|
||||||
$RUN_CMD spec/*_spec.py
|
|
||||||
fi
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
import os
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import pexpect
|
|
||||||
from path import Path
|
|
||||||
from expects import expect, equal
|
|
||||||
|
|
||||||
vncserver_cmd = 'vncserver :1 -cert /etc/ssl/certs/ssl-cert-snakeoil.pem -key /etc/ssl/private/ssl-cert-snakeoil.key -sslOnly -FrameRate=24 -interface 0.0.0.0 -httpd /usr/share/kasmvnc/www -depth 24 -geometry 1280x1050 -log *:stderr:100'
|
|
||||||
running_xvnc = False
|
|
||||||
|
|
||||||
|
|
||||||
def clean_env():
|
|
||||||
clean_kasm_users()
|
|
||||||
|
|
||||||
home_dir = os.environ['HOME']
|
|
||||||
vnc_dir = os.path.join(home_dir, ".vnc")
|
|
||||||
Path(vnc_dir).rmtree(ignore_errors=True)
|
|
||||||
|
|
||||||
|
|
||||||
def clean_kasm_users():
|
|
||||||
home_dir = os.environ['HOME']
|
|
||||||
password_file = os.path.join(home_dir, ".kasmpasswd")
|
|
||||||
Path(password_file).remove_p()
|
|
||||||
|
|
||||||
|
|
||||||
def start_xvnc_pexpect(extra_args="", **kwargs):
|
|
||||||
global running_xvnc
|
|
||||||
|
|
||||||
# ":;" is a hack. Without it, Xvnc doesn't run. No idea what happens, but
|
|
||||||
# when I run top, Xvnc just isn't there. I suspect a race.
|
|
||||||
child = pexpect.spawn('/bin/bash',
|
|
||||||
['-ic', f':;{vncserver_cmd} {extra_args}'],
|
|
||||||
timeout=5, encoding='utf-8', **kwargs)
|
|
||||||
running_xvnc = True
|
|
||||||
|
|
||||||
return child
|
|
||||||
|
|
||||||
|
|
||||||
def start_xvnc(extra_args="", **kwargs):
|
|
||||||
global running_xvnc
|
|
||||||
completed_process = run_cmd(f'{vncserver_cmd} {extra_args}', **kwargs)
|
|
||||||
if completed_process.returncode == 0:
|
|
||||||
running_xvnc = True
|
|
||||||
|
|
||||||
return completed_process
|
|
||||||
|
|
||||||
|
|
||||||
def run_cmd(cmd, **kwargs):
|
|
||||||
completed_process = subprocess.run(cmd, shell=True, text=True,
|
|
||||||
capture_output=True,
|
|
||||||
executable='/bin/bash', **kwargs)
|
|
||||||
if completed_process.returncode != 0:
|
|
||||||
print(completed_process.stdout)
|
|
||||||
print(completed_process.stderr)
|
|
||||||
|
|
||||||
return completed_process
|
|
||||||
|
|
||||||
|
|
||||||
def add_kasmvnc_user_docker():
|
|
||||||
completed_process = run_cmd('echo -e "password\\npassword\\n" | vncpasswd -u docker')
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
|
|
||||||
def kill_xvnc():
|
|
||||||
global running_xvnc
|
|
||||||
if not running_xvnc:
|
|
||||||
return
|
|
||||||
|
|
||||||
run_cmd('vncserver -kill :1')
|
|
||||||
running_xvnc = False
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
import pexpect
|
|
||||||
from mamba import description, context, it, fit, before, after
|
|
||||||
from expects import expect, equal
|
|
||||||
|
|
||||||
from helper.spec_helper import start_xvnc, kill_xvnc, run_cmd, clean_env, \
|
|
||||||
add_kasmvnc_user_docker, clean_kasm_users, start_xvnc_pexpect
|
|
||||||
|
|
||||||
# WIP. Plan to move to start_xvnc_pexpect(), because pexpect provides a way to
|
|
||||||
# wait for vncserver output. start_xvnc() just blindly prints input to vncserver
|
|
||||||
# without knowing what it prints back.
|
|
||||||
|
|
||||||
|
|
||||||
def select_de(de_name):
|
|
||||||
try:
|
|
||||||
extra_args = f'-select-de {de_name}'
|
|
||||||
completed_process = start_xvnc(extra_args)
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
finally:
|
|
||||||
kill_xvnc()
|
|
||||||
|
|
||||||
|
|
||||||
def check_de_was_setup_to_run(de_name):
|
|
||||||
completed_process = run_cmd(f'grep -q {de_name} ~/.vnc/xstartup')
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
|
|
||||||
with description('vncserver') as self:
|
|
||||||
with before.each:
|
|
||||||
clean_env()
|
|
||||||
with after.each:
|
|
||||||
kill_xvnc()
|
|
||||||
|
|
||||||
with context('on the first run'):
|
|
||||||
with before.each:
|
|
||||||
add_kasmvnc_user_docker()
|
|
||||||
|
|
||||||
with it('asks user to select a DE'):
|
|
||||||
choose_cinnamon = "1\n"
|
|
||||||
completed_process = start_xvnc(input=choose_cinnamon)
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
check_de_was_setup_to_run('cinnamon')
|
|
||||||
|
|
||||||
with it('asks to select a DE, when ran with -select-de'):
|
|
||||||
choose_cinnamon = "1\n"
|
|
||||||
completed_process = start_xvnc('-select-de', input=choose_cinnamon)
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
check_de_was_setup_to_run('cinnamon')
|
|
||||||
|
|
||||||
with it('selects passed DE with -s'):
|
|
||||||
select_de('mate')
|
|
||||||
check_de_was_setup_to_run('mate')
|
|
||||||
|
|
||||||
with context('after DE was selected'):
|
|
||||||
with before.each:
|
|
||||||
add_kasmvnc_user_docker()
|
|
||||||
|
|
||||||
with it("don't ask to choose DE by default"):
|
|
||||||
select_de('mate')
|
|
||||||
|
|
||||||
completed_process = start_xvnc()
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
check_de_was_setup_to_run('mate')
|
|
||||||
|
|
||||||
with it('asks to select a DE, when ran with -select-de'):
|
|
||||||
select_de('mate')
|
|
||||||
|
|
||||||
choose_cinnamon_and_answer_yes = "1\ny\n"
|
|
||||||
completed_process = start_xvnc('-select-de',
|
|
||||||
input=choose_cinnamon_and_answer_yes)
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
check_de_was_setup_to_run('cinnamon')
|
|
||||||
|
|
||||||
with it('selects passed DE with -s'):
|
|
||||||
select_de('mate')
|
|
||||||
|
|
||||||
completed_process = start_xvnc('-select-de cinnamon')
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
check_de_was_setup_to_run('cinnamon')
|
|
||||||
|
|
||||||
with context('guided user creation'):
|
|
||||||
with fit('asks to create a user if none exist'):
|
|
||||||
clean_kasm_users()
|
|
||||||
|
|
||||||
child = start_xvnc_pexpect('-select-de cinnamon')
|
|
||||||
child.expect('Enter username')
|
|
||||||
child.sendline()
|
|
||||||
child.expect('Password:')
|
|
||||||
child.sendline('password')
|
|
||||||
child.expect('Verify:')
|
|
||||||
child.sendline('password')
|
|
||||||
child.expect(pexpect.EOF)
|
|
||||||
child.close()
|
|
||||||
expect(child.exitstatus).to(equal(0))
|
|
||||||
|
|
||||||
home_dir = os.environ['HOME']
|
|
||||||
user = os.environ['USER']
|
|
||||||
completed_process = run_cmd(f'grep -qw {user} {home_dir}/.kasmpasswd')
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
with fit('specify custom username'):
|
|
||||||
custom_username = 'custom_username'
|
|
||||||
child = start_xvnc_pexpect('-select-de cinnamon')
|
|
||||||
child.logfile_read = sys.stderr
|
|
||||||
child.expect('Enter username')
|
|
||||||
child.sendline(custom_username)
|
|
||||||
child.expect('Password:')
|
|
||||||
child.sendline('password')
|
|
||||||
child.expect('Verify:')
|
|
||||||
child.sendline('password')
|
|
||||||
child.expect(pexpect.EOF)
|
|
||||||
child.wait()
|
|
||||||
# expect(child.exitstatus).to(equal(0))
|
|
||||||
|
|
||||||
home_dir = os.environ['HOME']
|
|
||||||
completed_process = run_cmd(f'grep -qw {custom_username} {home_dir}/.kasmpasswd')
|
|
||||||
expect(completed_process.returncode).to(equal(0))
|
|
||||||
|
|
||||||
# os.system(f'pgrep Xvnc >/dev/null || cat {home_dir}/.vnc/*.log')
|
|
||||||
@@ -3,6 +3,7 @@ add_subdirectory(common)
|
|||||||
add_subdirectory(vncconfig)
|
add_subdirectory(vncconfig)
|
||||||
add_subdirectory(vncpasswd)
|
add_subdirectory(vncpasswd)
|
||||||
add_subdirectory(kasmvncpasswd)
|
add_subdirectory(kasmvncpasswd)
|
||||||
|
add_subdirectory(kasmxproxy)
|
||||||
|
|
||||||
install(PROGRAMS vncserver DESTINATION ${BIN_DIR})
|
install(PROGRAMS vncserver DESTINATION ${BIN_DIR})
|
||||||
install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1)
|
install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1)
|
||||||
|
|||||||
1
unix/kasmxproxy/.gitignore
vendored
Normal file
1
unix/kasmxproxy/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
kasmxproxy
|
||||||
11
unix/kasmxproxy/CMakeLists.txt
Normal file
11
unix/kasmxproxy/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
include_directories(${X11_INCLUDE_DIR})
|
||||||
|
|
||||||
|
add_executable(kasmxproxy
|
||||||
|
xxhash.c
|
||||||
|
kasmxproxy.c)
|
||||||
|
|
||||||
|
target_link_libraries(kasmxproxy ${X11_LIBRARIES} ${X11_XTest_LIB} ${X11_Xrandr_LIB}
|
||||||
|
${X11_Xcursor_LIB} ${X11_Xfixes_LIB})
|
||||||
|
|
||||||
|
install(TARGETS kasmxproxy DESTINATION ${BIN_DIR})
|
||||||
|
install(FILES kasmxproxy.man DESTINATION ${MAN_DIR}/man1 RENAME kasmxproxy.1)
|
||||||
530
unix/kasmxproxy/kasmxproxy.c
Normal file
530
unix/kasmxproxy/kasmxproxy.c
Normal file
@@ -0,0 +1,530 @@
|
|||||||
|
/* Copyright (C) 2021 Kasm. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this software; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||||
|
* USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#include <X11/extensions/XShm.h>
|
||||||
|
#include <X11/extensions/XTest.h>
|
||||||
|
|
||||||
|
#include "xxhash.h"
|
||||||
|
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
static void help(const char name[]) {
|
||||||
|
printf("Usage: %s [opts]\n\n"
|
||||||
|
"-a --app-display disp App display, default :0\n"
|
||||||
|
"-v --vnc-display disp VNC display, default :1\n"
|
||||||
|
"\n"
|
||||||
|
"-f --fps fps FPS, default 30\n"
|
||||||
|
"-r --resize Enable resize, default disabled.\n"
|
||||||
|
" Do not enable this if there's a physical screen\n"
|
||||||
|
" connected to the app display.\n",
|
||||||
|
name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CUT_MAX (16 * 1024)
|
||||||
|
static uint8_t cutbuf[CUT_MAX];
|
||||||
|
|
||||||
|
static void supplyselection(Display *disp, const XEvent * const ev, const Atom xa_targets) {
|
||||||
|
XSelectionEvent sev;
|
||||||
|
|
||||||
|
sev.type = SelectionNotify;
|
||||||
|
sev.display = disp;
|
||||||
|
sev.requestor = ev->xselectionrequest.requestor;
|
||||||
|
sev.selection = ev->xselectionrequest.selection;
|
||||||
|
sev.target = ev->xselectionrequest.target;
|
||||||
|
sev.time = ev->xselectionrequest.time;
|
||||||
|
/*printf("someone wants our clipboard, sel %lu, tgt %lu, prop %lu\n",
|
||||||
|
sev.selection, sev.target,
|
||||||
|
ev.xselectionrequest.property);*/
|
||||||
|
|
||||||
|
if (ev->xselectionrequest.property == None)
|
||||||
|
sev.property = sev.target;
|
||||||
|
else
|
||||||
|
sev.property = ev->xselectionrequest.property;
|
||||||
|
|
||||||
|
const uint32_t len = strlen((char *) cutbuf);
|
||||||
|
|
||||||
|
if (xa_targets != None &&
|
||||||
|
sev.target == xa_targets) {
|
||||||
|
// Which formats can we do
|
||||||
|
Atom tgt[2] = {
|
||||||
|
xa_targets,
|
||||||
|
XA_STRING
|
||||||
|
};
|
||||||
|
|
||||||
|
XChangeProperty(disp, sev.requestor,
|
||||||
|
ev->xselectionrequest.property,
|
||||||
|
XA_ATOM, 32,
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char *) tgt,
|
||||||
|
2);
|
||||||
|
//puts("sent targets");
|
||||||
|
} else {
|
||||||
|
// Data
|
||||||
|
XChangeProperty(disp, sev.requestor,
|
||||||
|
ev->xselectionrequest.property,
|
||||||
|
sev.target, 8,
|
||||||
|
PropModeReplace,
|
||||||
|
cutbuf, len);
|
||||||
|
//printf("sent data, of len %u\n", len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the notify event
|
||||||
|
XSendEvent(disp, sev.requestor, False, 0,
|
||||||
|
(XEvent *) &sev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
const char *appstr = ":0";
|
||||||
|
const char *vncstr = ":1";
|
||||||
|
uint8_t resize = 0;
|
||||||
|
uint8_t fps = 30;
|
||||||
|
|
||||||
|
const struct option longargs[] = {
|
||||||
|
{"app-display", 1, NULL, 'a'},
|
||||||
|
{"vnc-display", 1, NULL, 'v'},
|
||||||
|
{"resize", 0, NULL, 'r'},
|
||||||
|
{"fps", 1, NULL, 'f'},
|
||||||
|
|
||||||
|
{NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int c = getopt_long(argc, argv, "a:v:rf:", longargs, NULL);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
appstr = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
vncstr = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
resize = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
fps = atoi(optarg);
|
||||||
|
if (fps < 1 || fps > 120) {
|
||||||
|
printf("Invalid fps\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
help(argv[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Display *appdisp = XOpenDisplay(appstr);
|
||||||
|
if (!appdisp) {
|
||||||
|
printf("Cannot open display %s\n", appstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!XShmQueryExtension(appdisp)) {
|
||||||
|
printf("Display %s lacks SHM extension\n", appstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Display *vncdisp = XOpenDisplay(vncstr);
|
||||||
|
if (!vncdisp) {
|
||||||
|
printf("Cannot open display %s\n", vncstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!XShmQueryExtension(vncdisp)) {
|
||||||
|
printf("Display %s lacks SHM extension\n", vncstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int appscreen = DefaultScreen(appdisp);
|
||||||
|
const int vncscreen = DefaultScreen(vncdisp);
|
||||||
|
Visual *appvis = DefaultVisual(appdisp, appscreen);
|
||||||
|
//Visual *vncvis = DefaultVisual(vncdisp, vncscreen);
|
||||||
|
const int appdepth = DefaultDepth(appdisp, appscreen);
|
||||||
|
const int vncdepth = DefaultDepth(vncdisp, vncscreen);
|
||||||
|
if (appdepth != vncdepth) {
|
||||||
|
printf("Depths don't match, app %u vnc %u\n", appdepth, vncdepth);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window approot = DefaultRootWindow(appdisp);
|
||||||
|
Window vncroot = DefaultRootWindow(vncdisp);
|
||||||
|
XWindowAttributes appattr, vncattr;
|
||||||
|
|
||||||
|
XGCValues gcval;
|
||||||
|
gcval.plane_mask = AllPlanes;
|
||||||
|
gcval.function = GXcopy;
|
||||||
|
GC gc = XCreateGC(vncdisp, vncroot, GCFunction | GCPlaneMask, &gcval);
|
||||||
|
|
||||||
|
XImage *img = NULL;
|
||||||
|
XShmSegmentInfo shminfo;
|
||||||
|
unsigned imgw = 0, imgh = 0;
|
||||||
|
|
||||||
|
if (XGrabPointer(vncdisp, vncroot, False,
|
||||||
|
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||||
|
GrabModeAsync, GrabModeAsync, None, None,
|
||||||
|
CurrentTime) != Success)
|
||||||
|
return 1;
|
||||||
|
if (XGrabKeyboard(vncdisp, vncroot, False, GrabModeAsync, GrabModeAsync,
|
||||||
|
CurrentTime) != Success)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int xfixesbase, xfixeserrbase;
|
||||||
|
XFixesQueryExtension(appdisp, &xfixesbase, &xfixeserrbase);
|
||||||
|
XFixesSelectSelectionInput(appdisp, approot, XA_PRIMARY,
|
||||||
|
XFixesSetSelectionOwnerNotifyMask);
|
||||||
|
|
||||||
|
int xfixesbasevnc, xfixeserrbasevnc;
|
||||||
|
XFixesQueryExtension(vncdisp, &xfixesbasevnc, &xfixeserrbasevnc);
|
||||||
|
XFixesSelectSelectionInput(vncdisp, vncroot, XA_PRIMARY,
|
||||||
|
XFixesSetSelectionOwnerNotifyMask);
|
||||||
|
|
||||||
|
Atom xa_targets_vnc = XInternAtom(vncdisp, "TARGETS", False);
|
||||||
|
Atom xa_targets_app = XInternAtom(appdisp, "TARGETS", False);
|
||||||
|
Window selwin = XCreateSimpleWindow(appdisp, approot, 3, 2, 1, 1, 0, 0, 0);
|
||||||
|
Window vncselwin = XCreateSimpleWindow(vncdisp, vncroot, 3, 2, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
XFixesCursorImage *cursor = NULL;
|
||||||
|
uint64_t cursorhash = 0;
|
||||||
|
Cursor xcursor = None;
|
||||||
|
|
||||||
|
const unsigned sleeptime = 1000 * 1000 / fps;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (!XGetWindowAttributes(appdisp, approot, &appattr))
|
||||||
|
break;
|
||||||
|
if (!XGetWindowAttributes(vncdisp, vncroot, &vncattr))
|
||||||
|
break;
|
||||||
|
if (resize && (appattr.width != vncattr.width ||
|
||||||
|
appattr.height != vncattr.height)) {
|
||||||
|
// resize app display to VNC display size
|
||||||
|
XRRScreenConfiguration *config = XRRGetScreenInfo(appdisp, approot);
|
||||||
|
|
||||||
|
int nsizes, i, match = -1;
|
||||||
|
XRRScreenSize *sizes = XRRConfigSizes(config, &nsizes);
|
||||||
|
//printf("%u sizes\n", nsizes);
|
||||||
|
for (i = 0; i < nsizes; i++) {
|
||||||
|
if (sizes[i].width == vncattr.width &&
|
||||||
|
sizes[i].height == vncattr.height) {
|
||||||
|
//printf("match %u\n", i);
|
||||||
|
match = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match >= 0) {
|
||||||
|
XRRSetScreenConfig(appdisp, config, approot, match,
|
||||||
|
RR_Rotate_0, CurrentTime);
|
||||||
|
} else {
|
||||||
|
/*XRRSetScreenSize(appdisp, approot,
|
||||||
|
vncattr.width, vncattr.height,
|
||||||
|
sizes[0].mwidth, sizes[0].mheight);*/
|
||||||
|
XRRScreenResources *res = XRRGetScreenResources(appdisp, approot);
|
||||||
|
//printf("%u outputs, %u crtcs\n", res->noutput, res->ncrtc);
|
||||||
|
// Nvidia crap uses a *different* list for 1.0 and 1.2!
|
||||||
|
unsigned oldmode = 0xffff;
|
||||||
|
//printf("1.2 modes %u\n", res->nmode);
|
||||||
|
for (i = 0; i < res->nmode; i++) {
|
||||||
|
if (res->modes[i].width == vncattr.width &&
|
||||||
|
res->modes[i].height == vncattr.height) {
|
||||||
|
oldmode = i;
|
||||||
|
//printf("old mode %u matched\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned tgt = 0;
|
||||||
|
if (res->noutput > 1) {
|
||||||
|
for (i = 0; i < res->noutput; i++) {
|
||||||
|
XRROutputInfo *info = XRRGetOutputInfo(appdisp, res, res->outputs[i]);
|
||||||
|
if (info->connection == RR_Connected)
|
||||||
|
tgt = i;
|
||||||
|
//printf("%u %s %u\n", i, info->name, info->connection);
|
||||||
|
XRRFreeOutputInfo(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldmode < 0xffff) {
|
||||||
|
Status s;
|
||||||
|
// nvidia needs this weird dance
|
||||||
|
s = XRRSetCrtcConfig(appdisp, res, res->crtcs[tgt],
|
||||||
|
CurrentTime,
|
||||||
|
0, 0,
|
||||||
|
None, RR_Rotate_0,
|
||||||
|
NULL, 0);
|
||||||
|
//printf("disable %u\n", s);
|
||||||
|
XRRSetScreenSize(appdisp, approot,
|
||||||
|
vncattr.width, vncattr.height,
|
||||||
|
sizes[0].mwidth, sizes[0].mheight);
|
||||||
|
s = XRRSetCrtcConfig(appdisp, res, res->crtcs[tgt],
|
||||||
|
CurrentTime,
|
||||||
|
0, 0,
|
||||||
|
res->modes[oldmode].id, RR_Rotate_0,
|
||||||
|
&res->outputs[tgt], 1);
|
||||||
|
//printf("set %u\n", s);
|
||||||
|
} else {
|
||||||
|
char name[32];
|
||||||
|
sprintf(name, "%ux%u_60", vncattr.width, vncattr.height);
|
||||||
|
printf("Creating new Mode %s\n", name);
|
||||||
|
XRRModeInfo *mode = XRRAllocModeInfo(name, strlen(name));
|
||||||
|
|
||||||
|
mode->width = vncattr.width;
|
||||||
|
mode->height = vncattr.height;
|
||||||
|
|
||||||
|
RRMode rmode = XRRCreateMode(appdisp, approot, mode);
|
||||||
|
XRRAddOutputMode(appdisp,
|
||||||
|
res->outputs[tgt],
|
||||||
|
rmode);
|
||||||
|
XRRFreeModeInfo(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenConfigInfo(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned w = min(appattr.width, vncattr.width);
|
||||||
|
const unsigned h = min(appattr.height, vncattr.height);
|
||||||
|
|
||||||
|
if (w != imgw || h != imgh) {
|
||||||
|
if (img) {
|
||||||
|
XShmDetach(appdisp, &shminfo);
|
||||||
|
XDestroyImage(img);
|
||||||
|
shmdt(shminfo.shmaddr);
|
||||||
|
shmctl(shminfo.shmid, IPC_RMID, NULL);
|
||||||
|
}
|
||||||
|
img = XShmCreateImage(appdisp, appvis, appdepth, ZPixmap,
|
||||||
|
NULL, &shminfo, w, h);
|
||||||
|
if (!img)
|
||||||
|
break;
|
||||||
|
|
||||||
|
shminfo.shmid = shmget(IPC_PRIVATE,
|
||||||
|
img->bytes_per_line * img->height,
|
||||||
|
IPC_CREAT | 0666);
|
||||||
|
if (shminfo.shmid == -1)
|
||||||
|
break;
|
||||||
|
shminfo.shmaddr = img->data = shmat(shminfo.shmid, 0, 0);
|
||||||
|
shminfo.readOnly = False;
|
||||||
|
if (!XShmAttach(appdisp, &shminfo))
|
||||||
|
break;
|
||||||
|
|
||||||
|
imgw = w;
|
||||||
|
imgh = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
XShmGetImage(appdisp, approot, img, 0, 0, 0xffffffff);
|
||||||
|
XPutImage(vncdisp, vncroot, gc, img, 0, 0, 0, 0, w, h);
|
||||||
|
|
||||||
|
// Handle events
|
||||||
|
while (XPending(vncdisp)) {
|
||||||
|
XEvent ev;
|
||||||
|
XNextEvent(vncdisp, &ev);
|
||||||
|
|
||||||
|
if (ev.type == xfixesbasevnc + XFixesSelectionNotify) {
|
||||||
|
XFixesSelectionNotifyEvent *xfe =
|
||||||
|
(XFixesSelectionNotifyEvent *) &ev;
|
||||||
|
// printf("vnc disp did a copy, owner %lu, root %lu\n",
|
||||||
|
// xfe->owner, vncroot);
|
||||||
|
if (xfe->owner == None || xfe->owner == vncroot)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
XConvertSelection(vncdisp, XA_PRIMARY, XA_STRING, XA_STRING,
|
||||||
|
vncselwin, CurrentTime);
|
||||||
|
} else switch (ev.type) {
|
||||||
|
case KeyPress:
|
||||||
|
case KeyRelease:
|
||||||
|
XTestFakeKeyEvent(appdisp, ev.xkey.keycode,
|
||||||
|
ev.type == KeyPress,
|
||||||
|
CurrentTime);
|
||||||
|
break;
|
||||||
|
case ButtonPress:
|
||||||
|
case ButtonRelease:
|
||||||
|
XTestFakeButtonEvent(appdisp, ev.xbutton.button,
|
||||||
|
ev.type == ButtonPress,
|
||||||
|
CurrentTime);
|
||||||
|
break;
|
||||||
|
case MotionNotify:
|
||||||
|
XTestFakeMotionEvent(appdisp, appscreen,
|
||||||
|
ev.xmotion.x,
|
||||||
|
ev.xmotion.y,
|
||||||
|
CurrentTime);
|
||||||
|
break;
|
||||||
|
case SelectionRequest:
|
||||||
|
supplyselection(vncdisp, &ev, xa_targets_vnc);
|
||||||
|
break;
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
Atom realtype;
|
||||||
|
int fmt;
|
||||||
|
unsigned long nitems, bytes_rem;
|
||||||
|
unsigned char *data;
|
||||||
|
if (XGetWindowProperty(vncdisp, vncselwin,
|
||||||
|
XA_STRING,
|
||||||
|
0, CUT_MAX / 4,
|
||||||
|
False, AnyPropertyType,
|
||||||
|
&realtype, &fmt,
|
||||||
|
&nitems, &bytes_rem,
|
||||||
|
&data) == Success) {
|
||||||
|
|
||||||
|
if (bytes_rem) {
|
||||||
|
printf("Clipboard too large, ignoring\n");
|
||||||
|
} else {
|
||||||
|
const uint32_t len = nitems * (fmt / 8);
|
||||||
|
//printf("realtype %lu, fmt %u, nitems %lu\n",
|
||||||
|
// realtype, fmt, nitems);
|
||||||
|
memcpy(cutbuf, data, len);
|
||||||
|
if (len < CUT_MAX)
|
||||||
|
cutbuf[len] = 0;
|
||||||
|
else
|
||||||
|
cutbuf[CUT_MAX - 1] = 0;
|
||||||
|
|
||||||
|
// Send it to the app screen
|
||||||
|
XSetSelectionOwner(appdisp, XA_PRIMARY,
|
||||||
|
approot,
|
||||||
|
CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(data);
|
||||||
|
} else {
|
||||||
|
printf("Failed to fetch vnc clipboard\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SelectionClear:
|
||||||
|
cutbuf[0] = '\0';
|
||||||
|
XSetSelectionOwner(appdisp, XA_PRIMARY, None,
|
||||||
|
CurrentTime);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unexpected event type %u\n", ev.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// App-side events
|
||||||
|
while (XPending(appdisp)) {
|
||||||
|
XEvent ev;
|
||||||
|
XNextEvent(appdisp, &ev);
|
||||||
|
|
||||||
|
if (ev.type == xfixesbase + XFixesSelectionNotify) {
|
||||||
|
XFixesSelectionNotifyEvent *xfe =
|
||||||
|
(XFixesSelectionNotifyEvent *) &ev;
|
||||||
|
//printf("app disp did a copy, owner %lu\n", xfe->owner);
|
||||||
|
if (xfe->owner == None || xfe->owner == approot)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
XConvertSelection(appdisp, XA_PRIMARY, XA_STRING, XA_STRING,
|
||||||
|
selwin, CurrentTime);
|
||||||
|
} else switch (ev.type) {
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
Atom realtype;
|
||||||
|
int fmt;
|
||||||
|
unsigned long nitems, bytes_rem;
|
||||||
|
unsigned char *data;
|
||||||
|
if (XGetWindowProperty(appdisp, selwin,
|
||||||
|
XA_STRING,
|
||||||
|
0, CUT_MAX / 4,
|
||||||
|
False, AnyPropertyType,
|
||||||
|
&realtype, &fmt,
|
||||||
|
&nitems, &bytes_rem,
|
||||||
|
&data) == Success) {
|
||||||
|
|
||||||
|
if (bytes_rem) {
|
||||||
|
printf("Clipboard too large, ignoring\n");
|
||||||
|
} else {
|
||||||
|
const uint32_t len = nitems * (fmt / 8);
|
||||||
|
//printf("realtype %lu, fmt %u, nitems %lu\n",
|
||||||
|
// realtype, fmt, nitems);
|
||||||
|
memcpy(cutbuf, data, len);
|
||||||
|
if (len < CUT_MAX)
|
||||||
|
cutbuf[len] = 0;
|
||||||
|
else
|
||||||
|
cutbuf[CUT_MAX - 1] = 0;
|
||||||
|
|
||||||
|
// Send it to the VNC screen
|
||||||
|
XSetSelectionOwner(vncdisp, XA_PRIMARY,
|
||||||
|
vncroot,
|
||||||
|
CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(data);
|
||||||
|
} else {
|
||||||
|
printf("Failed to fetch app clipboard\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SelectionRequest:
|
||||||
|
supplyselection(appdisp, &ev, xa_targets_app);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unexpected app event type %u\n", ev.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cursors
|
||||||
|
cursor = XFixesGetCursorImage(appdisp);
|
||||||
|
uint64_t newhash = XXH64(cursor->pixels,
|
||||||
|
cursor->width * cursor->height * sizeof(unsigned long),
|
||||||
|
0);
|
||||||
|
if (cursorhash != newhash) {
|
||||||
|
if (cursorhash)
|
||||||
|
XFreeCursor(vncdisp, xcursor);
|
||||||
|
|
||||||
|
XcursorImage *converted = XcursorImageCreate(cursor->width, cursor->height);
|
||||||
|
|
||||||
|
converted->xhot = cursor->xhot;
|
||||||
|
converted->yhot = cursor->yhot;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < cursor->width * cursor->height; i++) {
|
||||||
|
converted->pixels[i] = cursor->pixels[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
xcursor = XcursorImageLoadCursor(vncdisp, converted);
|
||||||
|
XDefineCursor(vncdisp, vncroot, xcursor);
|
||||||
|
|
||||||
|
XcursorImageDestroy(converted);
|
||||||
|
|
||||||
|
cursorhash = newhash;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(sleeptime);
|
||||||
|
}
|
||||||
|
|
||||||
|
XCloseDisplay(appdisp);
|
||||||
|
XCloseDisplay(vncdisp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
unix/kasmxproxy/kasmxproxy.man
Normal file
18
unix/kasmxproxy/kasmxproxy.man
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.TH kasmxproxy 1 "" "KasmVNC" "Virtual Network Computing"
|
||||||
|
.SH NAME
|
||||||
|
kasmxproxy \- proxy an existing X11 display to a KasmVNC display
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B kasmxproxy
|
||||||
|
.RB [ \-a \-\-app\-display
|
||||||
|
.IR source display, default :0 ]
|
||||||
|
.RB [ \-v \-\-vnc\-display
|
||||||
|
.IR destination display, default :1 ]
|
||||||
|
.RB [ \-f \-\-fps
|
||||||
|
.IR FPS, default 30 ]
|
||||||
|
.RB [ \-r \-\-resize
|
||||||
|
.IR Enable resizing, default disabled. WARNING: DO NOT ENABLE IF PHYSICAL DISPLAY IS ATTACHED ]
|
||||||
|
.br
|
||||||
|
.BI "kasmxproxy -a :1 -v :10 -r"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B kasmxproxy
|
||||||
|
is used to proxy an x display, usually attached to a physical GPU, to KasmVNC display. This is usually used in the context of providing GPU acceleration to a KasmVNC session.
|
||||||
1
unix/kasmxproxy/xxhash.c
Symbolic link
1
unix/kasmxproxy/xxhash.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../common/rfb/xxhash.c
|
||||||
1
unix/kasmxproxy/xxhash.h
Symbolic link
1
unix/kasmxproxy/xxhash.h
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../common/rfb/xxhash.h
|
||||||
1349
unix/vncserver
Executable file → Normal file
1349
unix/vncserver
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
network:
|
|
||||||
ssl:
|
|
||||||
pem_certificate: lol
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user