diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8584fb..771a4ae 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ stages: build_ubuntu_bionic: stage: build + allow_failure: true before_script: - *prepare_build after_script: @@ -36,6 +37,7 @@ build_ubuntu_bionic: build_ubuntu_bionic_libjpeg_turbo: stage: build + allow_failure: false before_script: - *prepare_build after_script: @@ -48,6 +50,7 @@ build_ubuntu_bionic_libjpeg_turbo: build_ubuntu_focal: stage: build + allow_failure: true before_script: - *prepare_build after_script: @@ -60,6 +63,7 @@ build_ubuntu_focal: build_debian_buster: stage: build + allow_failure: true before_script: - *prepare_build after_script: @@ -72,6 +76,7 @@ build_debian_buster: build_debian_bullseye: stage: build + allow_failure: true before_script: - *prepare_build after_script: @@ -84,6 +89,7 @@ build_debian_bullseye: build_kali_rolling: stage: build + allow_failure: true before_script: - *prepare_build after_script: @@ -96,6 +102,7 @@ build_kali_rolling: build_centos7: stage: build + allow_failure: true before_script: - *prepare_build after_script: diff --git a/README.md b/README.md index 4356ecb..6d13c51 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ Future Goals: #### Debian-based ```sh -wget -qO- https://github.com/kasmtech/KasmVNC/releases/download/v0.9.1-beta/kasmvncserver_0.9.1~beta-1_amd64.deb +wget -qO- https://github.com/kasmtech/KasmVNC/releases/download/v0.9.2-beta/kasmvncserver_ubuntu_bionic_0.9.2_amd64.deb -sudo dpkg -i kasmvncserver_0.9.1~beta-1_amd64.deb +sudo dpkg -i kasmvncserver_*.deb sudo apt-get -f install # We provide an example script to run KasmVNC at # diff --git a/builder/dockerfile.centos_core.build b/builder/dockerfile.centos_core.build index 574fe2f..c277e1a 100644 --- a/builder/dockerfile.centos_core.build +++ b/builder/dockerfile.centos_core.build @@ -3,7 +3,7 @@ FROM centos:centos7 ENV KASMVNC_BUILD_OS centos ENV KASMVNC_BUILD_OS_CODENAME core -RUN yum install -y ca-certificates +RUN yum update -y ca-certificates 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 libjpeg-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev openssl-devel diff --git a/common/rfb/InputHandler.h b/common/rfb/InputHandler.h index 961e3d7..e16a810 100644 --- a/common/rfb/InputHandler.h +++ b/common/rfb/InputHandler.h @@ -38,7 +38,11 @@ namespace rfb { virtual void pointerEvent(const Point& __unused_attr pos, int __unused_attr buttonMask, 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, + int __unused_attr len) { } }; } diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx index b256996..3719756 100644 --- a/common/rfb/SMsgReader.cxx +++ b/common/rfb/SMsgReader.cxx @@ -224,7 +224,9 @@ void SMsgReader::readPointerEvent() int mask = is->readU8(); int x = is->readU16(); int y = is->readU16(); - handler->pointerEvent(Point(x, y), mask, false, false); + int scrollX = is->readS16(); + int scrollY = is->readS16(); + handler->pointerEvent(Point(x, y), mask, false, false, scrollX, scrollY); } diff --git a/common/rfb/TightWEBPEncoder.cxx b/common/rfb/TightWEBPEncoder.cxx index 4953ff4..74c109c 100644 --- a/common/rfb/TightWEBPEncoder.cxx +++ b/common/rfb/TightWEBPEncoder.cxx @@ -71,12 +71,12 @@ static const struct TightWEBPConfiguration conf[10] = { { 24, 0 }, // 1 { 30, 0 }, // 2 { 37, 0 }, // 3 - { 42, 1 }, // 4 - { 65, 1 }, // 5 - { 78, 1 }, // 6 - { 85, 2 }, // 7 - { 88, 3 }, // 8 - { 100, 4 } // 9 + { 42, 0 }, // 4 + { 65, 0 }, // 5 + { 78, 0 }, // 6 + { 85, 0 }, // 7 + { 88, 0 }, // 8 + { 100, 0 } // 9 }; @@ -143,7 +143,7 @@ void TightWEBPEncoder::compressOnly(const PixelBuffer* pb, const uint8_t quality method = conf[qualityIn].method; } else { quality = 8; - method = 4; + method = 0; } WebPConfigInit(&cfg); @@ -214,7 +214,7 @@ void TightWEBPEncoder::writeRect(const PixelBuffer* pb, const Palette& palette) method = conf[qualityLevel].method; } else { quality = 8; - method = 4; + method = 0; } WebPConfigInit(&cfg); @@ -265,7 +265,7 @@ rdr::U32 TightWEBPEncoder::benchmark() const rdr::U8* buffer; struct timeval start; int stride, i; - const uint8_t quality = 8, method = 4; + const uint8_t quality = 8, method = 2; WebPConfig cfg; WebPPicture pic; WebPMemoryWriter wrt; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index debd767..fa85a70 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -703,7 +703,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf) setCursor(); } -void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease) +void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY) { pointerEventTime = lastEventTime = time(0); server->lastUserInputTime = lastEventTime; @@ -731,7 +731,7 @@ void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool } } - server->desktop->pointerEvent(pointerEventPos, buttonMask, skipclick, skiprelease); + server->desktop->pointerEvent(pointerEventPos, buttonMask, skipclick, skiprelease, scrollX, scrollY); } } diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index eb9861a..63ce49c 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -207,7 +207,7 @@ namespace rfb { virtual void queryConnection(const char* userName); virtual void clientInit(bool shared); virtual void setPixelFormat(const PixelFormat& pf); - virtual void pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease); + virtual void pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY); virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); virtual void framebufferUpdateRequest(const Rect& r, bool incremental); virtual void setDesktopSize(int fb_width, int fb_height, diff --git a/kasmweb b/kasmweb index f8fde81..0bd7bf8 160000 --- a/kasmweb +++ b/kasmweb @@ -1 +1 @@ -Subproject commit f8fde81dfb9cc95f275642690954636865e648bf +Subproject commit 0bd7bf8b3eb1bcfe7fc27f1e159fd8e619ab6092 diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c index f8ac3fd..e8f9170 100644 --- a/unix/xserver/hw/vnc/Input.c +++ b/unix/xserver/hw/vnc/Input.c @@ -234,6 +234,14 @@ void vncPointerMove(int x, int y) cursorPosY = y; } +void vncScroll(int x, int y) { + ValuatorMask mask; + valuator_mask_zero(&mask); + valuator_mask_set(&mask, 2, x); + valuator_mask_set(&mask, 3, y); + QueuePointerEvents(vncPointerDev, MotionNotify, 0, POINTER_RELATIVE, &mask); +} + void vncGetPointerPos(int *x, int *y) { if (vncPointerDev != NULL) { @@ -261,7 +269,7 @@ static int vncPointerProc(DeviceIntPtr pDevice, int onoff) * is not a bug. */ Atom btn_labels[BUTTONS]; - Atom axes_labels[2]; + Atom axes_labels[4]; switch (onoff) { case DEVICE_INIT: @@ -278,11 +286,29 @@ static int vncPointerProc(DeviceIntPtr pDevice, int onoff) axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); + axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); + InitPointerDeviceStruct(pDev, map, BUTTONS, btn_labels, (PtrCtrlProcPtr)NoopDDA, GetMotionHistorySize(), - 2, axes_labels); + 4, axes_labels); + + InitValuatorAxisStruct(pDevice, 2, axes_labels[2], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative); + InitValuatorAxisStruct(pDevice, 3, axes_labels[3], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative); + + char* envScrollFactorH = getenv("SCROLL_FACTOR_H"); + char* envScrollFactorV = getenv("SCROLL_FACTOR_V"); + + float scrollFactorH = envScrollFactorH ? atof(envScrollFactorH) : 50.0; + float scrollFactorV = envScrollFactorV ? atof(envScrollFactorV) : 50.0; + + LOG_INFO("Mouse horizonatl scroll factor: %f", scrollFactorH); + LOG_INFO("Mouse vertical scroll factor: %f", scrollFactorV); + + SetScrollValuator(pDevice, 2, SCROLL_TYPE_HORIZONTAL, scrollFactorH, SCROLL_FLAG_NONE); + SetScrollValuator(pDevice, 3, SCROLL_TYPE_VERTICAL, scrollFactorV, SCROLL_FLAG_PREFERRED); break; case DEVICE_ON: pDev->on = TRUE; diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index 76680c0..ddc4e06 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -35,6 +35,7 @@ void vncInitInputDevice(void); void vncPointerButtonAction(int buttonMask, const unsigned char skipclick, const unsigned char skiprelease); void vncPointerMove(int x, int y); +void vncScroll(int x, int y); void vncGetPointerPos(int *x, int *y); void vncKeyboardEvent(KeySym keysym, unsigned xtcode, int down); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 60ea4d3..26a9bfd 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -459,11 +459,14 @@ void XserverDesktop::approveConnection(uint32_t opaqueId, bool accept, void XserverDesktop::pointerEvent(const Point& pos, int buttonMask, - const bool skipClick, const bool skipRelease) + const bool skipClick, const bool skipRelease, int scrollX, int scrollY) { - vncPointerMove(pos.x + vncGetScreenX(screenIndex), - pos.y + vncGetScreenY(screenIndex)); - vncPointerButtonAction(buttonMask, skipClick, skipRelease); + if (scrollX == 0 && scrollY == 0) { + vncPointerMove(pos.x + vncGetScreenX(screenIndex), pos.y + vncGetScreenY(screenIndex)); + vncPointerButtonAction(buttonMask, skipClick, skipRelease); + } else { + vncScroll(scrollX, scrollY); + } } unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index c8fc19a..fb9b365 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -94,7 +94,7 @@ public: // rfb::SDesktop callbacks virtual void pointerEvent(const rfb::Point& pos, int buttonMask, - const bool skipClick, const bool skipRelease); + const bool skipClick, const bool skipRelease, int scrollX = 0, int scrollY = 0); virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); virtual unsigned int setScreenLayout(int fb_width, int fb_height, const rfb::ScreenSet& layout);