├── .github
└── workflows
│ ├── sonarcloud-build.yml
│ └── test-build.yml
├── AUTHORS
├── CMakeLists.txt
├── LICENSE
├── README.md
├── README_ru.md
├── doc
├── astylerc
└── ltsm_channels.txt
├── etc
├── dbus-1
│ ├── ltsm.manager.service.conf
│ ├── ltsm.session.audio.conf
│ ├── ltsm.session.audio.service
│ ├── ltsm.session.fuse.conf
│ ├── ltsm.session.fuse.service
│ ├── ltsm.session.pcsc.conf
│ ├── ltsm.session.pcsc.service
│ ├── org.freedesktop.Notifications.conf
│ └── org.freedesktop.Notifications.service
├── logrotate.d
│ └── ltsm
├── ltsm
│ ├── config.json
│ ├── keymap_rdp.json
│ ├── keymap_vnc.json
│ └── xclients
├── pam
│ ├── ltsm
│ └── xserver
├── rsyslog
│ └── ltsm.conf
├── systemd
│ ├── ltsm_connector_rdp.socket
│ ├── ltsm_connector_rdp@.service
│ ├── ltsm_connector_vnc.socket
│ ├── ltsm_connector_vnc@.service
│ └── ltsm_service.service
├── xinet
│ ├── jetdirect
│ └── ltsm_connector
└── xorg
│ └── ltsm.conf
├── sonar-project.properties
└── src
├── channels
├── channel_system.cpp
├── channel_system.h
└── ltsm_channels.h
├── common
├── CMakeLists.txt
├── flat_hash_map
│ ├── flat_hash_map.hpp
│ └── unordered_map.hpp
├── jsmn
│ └── jsmn.h
├── libxcb-errors
│ ├── errors.h
│ ├── extensions.c
│ ├── xcb_errors.c
│ └── xcb_errors.h
├── ltsm_application.cpp
├── ltsm_application.h
├── ltsm_font_psf.h
├── ltsm_framebuffer.cpp
├── ltsm_framebuffer.h
├── ltsm_global.h
├── ltsm_gsslayer.cpp
├── ltsm_gsslayer.h
├── ltsm_json_wrapper.cpp
├── ltsm_json_wrapper.h
├── ltsm_sockets.cpp
├── ltsm_sockets.h
├── ltsm_streambuf.cpp
├── ltsm_streambuf.h
├── ltsm_tools.cpp
├── ltsm_tools.h
├── ltsm_xcb_types.cpp
├── ltsm_xcb_types.h
├── ltsm_xcb_wrapper.cpp
├── ltsm_xcb_wrapper.h
└── mingw
│ └── gnutls
│ └── gnutlsxx.h
├── connector
├── COPYING.AGPLv3
├── ltsm_connector.cpp
├── ltsm_connector.h
├── ltsm_connector_rdp.cpp
├── ltsm_connector_rdp.h
├── ltsm_connector_vnc.cpp
└── ltsm_connector_vnc.h
├── cups_backend
└── main.cpp
├── dbus
├── ltsm_audio.xml
├── ltsm_fuse.xml
├── ltsm_pcsc.xml
└── ltsm_service.xml
├── librfb
├── COPYING.AGPLv3
├── ffmpeg_tools.cpp
├── ffmpeg_tools.h
├── librfb_client.cpp
├── librfb_client.h
├── librfb_decodings.cpp
├── librfb_decodings.h
├── librfb_encodings.cpp
├── librfb_encodings.h
├── librfb_extclip.cpp
├── librfb_extclip.h
├── librfb_ffmpeg.cpp
├── librfb_ffmpeg.h
├── librfb_server.cpp
├── librfb_server.h
├── librfb_winclient.cpp
├── librfb_winclient.h
├── librfb_x11client.cpp
├── librfb_x11client.h
├── librfb_x11server.cpp
├── librfb_x11server.h
├── ltsm_librfb.cpp
└── ltsm_librfb.h
├── qt_helper
├── ltsm_helper.qrc
├── ltsm_helper_ru.qm
├── ltsm_helper_ru.ts
├── ltsm_helperwindow.cpp
├── ltsm_helperwindow.h
├── ltsm_helperwindow.ui
├── ltsm_ldap_wrapper.cpp
├── ltsm_ldap_wrapper.h
├── ltsm_logo.png
└── main.cpp
├── qt_sessions
├── ltsm_offline.png
├── ltsm_online.png
├── ltsm_sessions.cpp
├── ltsm_sessions.h
├── ltsm_sessions.qrc
├── ltsm_sessions.ui
├── ltsm_sessions_ru.qm
├── ltsm_sessions_ru.ts
└── main.cpp
├── sane_backend
├── unix.c
├── unix.conf.in
└── unix.h
├── sdl2x11
├── ltsm_sdl2x11.cpp
├── ltsm_sdl_wrapper.cpp
└── ltsm_sdl_wrapper.h
├── service
├── ltsm_service.cpp
└── ltsm_service.h
├── session_audio
├── ltsm_audio.h
├── ltsm_audio_client.cpp
├── ltsm_audio_decoder.cpp
├── ltsm_audio_decoder.h
├── ltsm_audio_encoder.cpp
├── ltsm_audio_encoder.h
├── ltsm_audio_openal.cpp
├── ltsm_audio_openal.h
├── ltsm_audio_pulse.cpp
├── ltsm_audio_pulse.h
├── ltsm_audio_session.cpp
└── ltsm_audio_session.h
├── session_fuse
├── ltsm_fuse.h
├── ltsm_fuse_client.cpp
├── ltsm_fuse_session.cpp
└── ltsm_fuse_session.h
├── session_pcsc
├── ltsm_pcsc.h
├── ltsm_pcsc_client.cpp
├── ltsm_pcsc_session.cpp
└── ltsm_pcsc_session.h
├── session_pkcs11
├── ltsm_pkcs11.h
├── ltsm_pkcs11_client.cpp
├── ltsm_pkcs11_session.cpp
├── ltsm_pkcs11_session.h
├── ltsm_pkcs11_wrapper.cpp
└── ltsm_pkcs11_wrapper.h
├── tests
├── CMakeLists.txt
├── encodings
│ ├── images
│ │ ├── 001.png
│ │ ├── 002.png
│ │ ├── 003.png
│ │ └── 004.png
│ ├── librfb_server2.cpp
│ ├── librfb_server2.h
│ └── main.cpp
├── framebuf
│ └── main.cpp
├── json
│ ├── main.cpp
│ └── test.json
├── streambuf
│ └── main.cpp
├── unixsocket
│ └── main.cpp
├── x11clip
│ └── main.cpp
├── x11enc
│ └── main.cpp
├── xcb
│ └── main.cpp
└── xrandr
│ └── main.cpp
├── vnc2image
├── ltsm_vnc2image.cpp
└── ltsm_vnc2image.h
├── vnc2sdl
├── ltsm_vnc2sdl.cpp
└── ltsm_vnc2sdl.h
└── x11vnc
├── ltsm_connector_x11vnc.cpp
├── ltsm_connector_x11vnc.h
├── ltsm_x11vnc.cpp
└── ltsm_x11vnc.h
/.github/workflows/test-build.yml:
--------------------------------------------------------------------------------
1 | name: CMake
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | env:
10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
11 | BUILD_TYPE: Release
12 |
13 | jobs:
14 | build:
15 | # The CMake configure and build commands are platform agnostic and should work equally
16 | # well on Windows or Mac. You can convert this to a matrix build if you need
17 | # cross-platform coverage.
18 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
19 | runs-on: ubuntu-latest
20 |
21 | steps:
22 | - uses: actions/checkout@v4
23 |
24 | - name: Update packages
25 | run: |
26 | sudo apt update
27 | sudo apt -y upgrade
28 |
29 | - name: Install dependencies
30 | run: |
31 | sudo apt install -y cmake wget g++ git libexpat1 libpam0g-dev \
32 | libsdbus-c++-dev gnutls-dev freerdp2-dev libxcb1-dev libxcb-xtest0-dev libxcb-xfixes0-dev \
33 | libxcb-shm0-dev libxcb-randr0-dev libxcb-damage0-dev libxcb-keysyms1-dev libsdl2-image-dev qtbase5-dev \
34 | libxcb-xkb-dev libxkbcommon-x11-dev \
35 | libsdl2-image-dev qtbase5-dev libsdbus-c++-bin libsdbus-c++-dev \
36 | libldap-dev libcups2-dev libfuse3-dev libsystemd-dev libopus-dev libpcsclite-dev libp11-kit-dev \
37 | liblz4-dev libturbojpeg-dev libxkbfile-dev libopenal-dev \
38 | libavdevice-dev libavformat-dev libavcodec-dev libswscale-dev libswresample-dev libavutil-dev
39 |
40 | - name: Configure CMake
41 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
42 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
43 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
44 | -DLTSM_BUILD_SERVER=on \
45 | -DLTSM_BUILD_CLIENT=on \
46 | -DLTSM_FFMPEG=on \
47 | -DLTSM_WITH_RDP=on \
48 | -DLTSM_FUSE2SESSION=on \
49 | -DLTSM_AUDIO2SESSION=on \
50 | -DLTSM_PCSC2SESSION=on \
51 | -DLTSM_PKCS11_AUTH=on \
52 | -DLTSM_BUILD_X11VNC=on -DLTSM_BUILD_VNC2IMAGE=on \
53 | -DLTSM_CUPS_BACKEND=on
54 |
55 | - name: Build
56 | # Build your program with the given configuration
57 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
58 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | LTSM owner and contributor
2 | Andrey Afletdinov (https://github.com/AndreyBarmaley)
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # linux-terminal-service-manager
2 | Linux Terminal Service Manager (LTSM) is a set of service programs that allows remote computers to connect to a Linux operating system computer using a remote terminal session (over VNC or RDP)
3 |
4 | # Linux Only!
5 | main dependencies:
6 | - systemd, sd-bus
7 | - [sdbus-cpp](https://github.com/Kistler-Group/sdbus-cpp)
8 | - [json parser](https://github.com/zserge/jsmn)
9 | - [freerdp](https://github.com/FreeRDP/FreeRDP)
10 | - system libs: gnutls, xcb, zlib
11 |
12 | ## Developer indicators
13 | [](https://github.com/AndreyBarmaley/linux-terminal-service-manager/actions)
14 | [](https://sonarcloud.io/summary/new_code?id=AndreyBarmaley_linux-terminal-service-manager)
15 | [](https://sonarcloud.io/summary/new_code?id=AndreyBarmaley_linux-terminal-service-manager)
16 | [](https://sonarcloud.io/summary/new_code?id=AndreyBarmaley_linux-terminal-service-manager)
17 | [](https://sonarcloud.io/summary/new_code?id=AndreyBarmaley_linux-terminal-service-manager)
18 | [](https://openhub.net/p/linux-terminal-service-manager)
19 |
20 | # Demo access
21 | ```
22 | --- vnc
23 | vncviewer 62.109.12.152
24 | --- rdp
25 | xfreerdp /v:62.109.12.152
26 |
27 | logins: demo1, demo2, demo3, demo4
28 | pass: demo
29 | ```
30 |
31 | # Docker demonstration
32 | ```
33 | docker pull docker.io/ltsm/devel
34 | docker run -i -t docker.io/ltsm/devel
35 | ```
36 |
37 | # The scheme of interaction of components
38 | 
39 | The following components are implemented:
40 |
41 | # LTSM_service
42 | The main service, dbus owner *ltsm.service.manager*, receives commands from LTSM_connector, and starts login and users sessions based on Xvfb (GPLv3 license)
43 | see also: [wiki: LTSM service](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-service)
44 |
45 | # LTSM_connector
46 | It is just a graphics protocol handler, and the main network part is handled by the service xinetd/(systemd sockets), and it is also a dbus client *ltsm.manager.service*, it connects to Xvfb via the shared memory mechanism (Affero GPLv3 license)
47 | see also: [wiki: LTSM connector](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-connector)
48 |
49 | # LTSM_helper
50 | 
51 | 
52 | GUI login utility, and it is a dbus client *ltsm.manager.service* (GPLv3 license)
53 | see also: [wiki: LTSM config](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-config-(full-description))
54 |
55 | # LTSM_sessions
56 | 
57 | GUI users sessions management utility, and it is a dbus client *ltsm.manager.service* (GPLv3 license)
58 | 
59 | see also: [wiki: LTSM administrator](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-administrator)
60 |
61 | # LTSM_vnc2sdl
62 | This is an experimental graphical client that implements the mechanism of multiple data channels, up to a maximum of 253.
63 |
64 | **Main improvements implemented:**
65 | * Works utf8 clipboard in both directions (problem for most VNC clients)
66 | * Automatic keyboard layout, client-side layout always takes precedence (nothing needs to be configured on the server-side)
67 | * File transfer via drag & drop (client side to remote virtual session)
68 | * Implemented file printing (using an additional [backend for CUPS](https://github.com/AndreyBarmaley/linux-terminal-service-manager/tree/main/src/cups_backend))
69 | * Implemented audio redirect via **PulseAudio**
70 | * Implemented smartcard redirect via **PCSC**
71 | * Implemented scanning redirect (using an additional [backend for SANE](https://github.com/AndreyBarmaley/linux-terminal-service-manager/tree/main/src/sane_backend))
72 | * Directory redirection via **FUSE** has been implemented (so far only in read only mode)
73 | * Implemented authentication to a virtual session via **PKCS11** with certificate storage in **LDAP**
74 | * Implemented SSO authentication via **GSSAPI** (kerberos5)
75 | * Implemented **x264** encoding/decoding via **ffmpeg**
76 |
77 | The mechanism of pipes is implemented through the abstract schemes ```unix://, file://, socket://```, and the access mode ```ReadOnly, WriteOnly, ReadWrite```.
78 | For example, for a normal file transfer, a typical channel is created (client-server): ```file:///src_file1 (ReadOnly)``` and ```file:///dst_file2 (WriteOnly)```, then in the user session, informational GUI dialogs are launched about the transfer and selection of the destination folder, after which the file automatically saved in the remote session.
79 | Also, using this mechanism, it is possible to transfer any data stream in both directions, but the initiator of creating a channel is always the server.
80 |
81 | So printing from the server side (in a remote user session) is implemented in this way - on the server, cups adds its own backend to configure the printer, which knows which unix socket to print in the user session, from the client side, the stream can be sent to the ```socket://``` network printer ```127.0.0.1:9100```, also to local cups or ```file:///dev/usb/lp0```. In this scheme, the system administrator configures the printer only once per server. The audio redirect, scanning and pcscd redirect works according to a similar scheme.
82 |
83 | You can test all implemented features in the **docker** version.
84 |
85 | **ROADMAP**
86 | * add video recordings of all working sessions (video recording)
87 | * add [**VirtualGL**](https://virtualgl.org) support
88 | * add a video redirect via **PipeWire**
89 | * work with graphics accelerated via **Cuda GPU** (there are no technical capabilities yet)
90 | * build client for MacOs/Windows
91 |
--------------------------------------------------------------------------------
/README_ru.md:
--------------------------------------------------------------------------------
1 | # linux-terminal-service-manager
2 | Linux Terminal Service Manager (LTSM) это набор программ для организации доступа к рабочему столу (сервер Linux) на основе терминальных сессий (с использованием протокола VNC или RDP)
3 |
4 | # Основные зависимости:
5 | - systemd, sd-bus
6 | - [sdbus-cpp](https://github.com/Kistler-Group/sdbus-cpp)
7 | - [json parser](https://github.com/zserge/jsmn)
8 | - [freerdp](https://github.com/FreeRDP/FreeRDP)
9 | - system libs: gnutls, xcb, zlib
10 |
11 | # Демо доступ
12 | ```
13 | vncviewer 62.109.12.152
14 | logins: demo1, demo2, demo3, demo4
15 | pass: demo
16 | ```
17 |
18 | # Docker демонстрация
19 | ```
20 | docker pull docker.io/ltsm/devel
21 | docker run -i -t docker.io/ltsm/devel
22 | ```
23 |
24 | # Схема взаимодействия компонентов
25 | 
26 | реализованы следующие компоненты:
27 |
28 | # LTSM_service
29 | основная служба, менеджер dbus ltsm.service.manager, получает команды от LTSM_connector, запускает login и users сессии на базе Xvfb (Лицензия GPLv3)
30 | см дополнительно: [wiki: LTSM service](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-service)
31 |
32 | # LTSM_connector
33 | является только обработчиком сетевого протокола VNC и RDP, а основной сетевой частью занимается служебный xinetd/(systemd sockets), также он является клиентом dbus ltsm.manager.service, подключается к Xvfb через механизм shared memory (Лицензия на коннектор Affero GPLv3)
34 | см дополнительно: [wiki: LTSM connector](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-connector)
35 |
36 | # LTSM_helper
37 | 
38 | 
39 | графическая утилита входа в систему, является клиентом dbus ltsm.manager.service (Лицензия GPLv3)
40 | см дополнительно: [wiki: LTSM config](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-config-(full-description))
41 |
42 | # LTSM_sessions
43 | 
44 | графическая утилита управления сессиями пользователей, является клиентом dbus ltsm.manager.service (Лицензия GPLv3)
45 | см дополнительно: [wiki: LTSM administrator](https://github.com/AndreyBarmaley/linux-terminal-service-manager/wiki/LTSM-administrator)
46 |
47 | # LTSM_vnc2sdl
48 | Это экспериментальный графический клиент, в котором реализован механизм множественных каналов данных, максимально до 253.
49 |
50 | **Основные реализованные улучшения:**
51 | * Работает буфер обмена **utf8** в обе стороны (проблема для большинства клиентов VNC)
52 | * шифрование трафика через gnutls
53 | * Автоматическая раскладка клавиатуры, в приоритете всегда раскладка со стороны клиента (на стороне сервера ничего не нужно настраивать)
54 | * Передача файлов через **drag & drop** (со стороны клиента на удаленную виртуальную сессию)
55 | * Реализована печать файлов (с помощью дополнительного [backend для CUPS](https://github.com/AndreyBarmaley/linux-terminal-service-manager/tree/main/src/cups_backend))
56 | * Реализован редирект звука через **PulseAudio**
57 | * Реализован редирект смарткарт через **PCSC**
58 | * Реализовано сканирование документов (с помощью дополнительного [backend для SANE](https://github.com/AndreyBarmaley/linux-terminal-service-manager/tree/main/src/sane_backend))
59 | * Реализован редирект директорий через **FUSE** (пока только в режиме read only)
60 | * Реализована аутентификация в виртуальную сессию через **PKCS11** (модуль **rutoken** или другой) с хранилищем сертификатов в **LDAP**
61 | * Реализована SSO аутентификация через **GSSAPI** (kerberos5)
62 | * Реализовано кодирование **x264** через **ffmpeg**
63 |
64 | Механизм каналов реализован через абстрактные схемы ```unix://, file://, socket://```, и режим доступа ```ReadOnly, WriteOnly, ReadWrite```.
65 | Например для обычной передачи файла создается типовой канал (клиент сервер): ```file:///src_file1 (ReadOnly)``` и ```file:///dst_file2 (WriteOnly)```, далее в сессии пользователя запускаются информационные GUI диалоги о передаче и выборе папки назначения, после которых файл автоматически сохранится в удаленной сессии (дополнительно реализованы уведомления через dbus desktop notify).
66 | C помощью данной схемы каналов возможна передача любого потока данных в обе стороны, но инициатором создания канала всегда является сервер.
67 |
68 | Печать со стороны сервера (в удаленной сессии пользователя) реализуется таким образом - на сервере в **cups** добавляется собственный **backend** для печати, который знает в какой **unix сокет** печатать в сессии пользователя, со стороны клиента поток можно отправлять в сетевой принтер ```socket://127.0.0.1:9100```, также в локальный **cups** или в ```file:///dev/usb/lp0```. В этой схеме системный администратор настраивает принтер только один раз для сервера, например командой ```lpadmin -p ltsm -D "LTSM virtual printer" -E -v ltsm:///var/run/ltsm/cups/username -m raw```. Модуль для **cups** автоматически получает сокет из этой схемы, меняет **username** на реального и отправляет в него задание печати. Этот же формат сокета на стороне LTSM сервиса назначается в конфигурационном файле. Сокеты на стороне сервера работают в **listen** режиме поэтому допускаются множественные подключения от клиента. Каждое подключение занимает один канал (253 макс). Как только с одной из сторон освободится дескриптор считается что передача данных завершена и канал можно использовать повторно. Редирект звука, сканирования и pcscd работает по **аналогичной схеме**.
69 |
70 | Все эти реализованные возможности вы можете протестировать в версии **docker**.
71 |
72 | Программное обеспечение зарегистрировано в реестре российского ПО, Номер заявления: 246869, Дата регистрации: 01.11.2021.
73 |
74 | **Roadmap**
75 | * добавить записи видео всех рабочих сессий (видеофикация)
76 | * добавить поддержку [**VirtualGL**](https://virtualgl.org/)
77 | * добавить редирект video через **PipeWire**
78 | * поработать с графикой через **Cuda GPU** (пока нет технических возможностей)
79 | * добавить клиента для MacOs/Windows
80 |
--------------------------------------------------------------------------------
/doc/astylerc:
--------------------------------------------------------------------------------
1 | -A1
2 | -S
3 | -N
4 | -Y
5 | -f
6 | --pad-negation
7 | --unpad-brackets
8 | --align-pointer=type
9 | --align-reference=middle
10 | --add-braces
11 | --keep-one-line-blocks
12 | --convert-tabs
13 | --squeeze-ws
14 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.manager.service.conf:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.audio.conf:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.audio.service:
--------------------------------------------------------------------------------
1 | [D-BUS Service]
2 | Name=ltsm.session.audio
3 | Exec=/usr/libexec/ltsm/LTSM_audio2session
4 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.fuse.conf:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.fuse.service:
--------------------------------------------------------------------------------
1 | [D-BUS Service]
2 | Name=ltsm.session.fuse
3 | Exec=/usr/libexec/ltsm/LTSM_fuse2session
4 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.pcsc.conf:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/etc/dbus-1/ltsm.session.pcsc.service:
--------------------------------------------------------------------------------
1 | [D-BUS Service]
2 | Name=ltsm.session.pcsc
3 | Exec=/usr/libexec/ltsm/LTSM_pcsc2session
4 |
--------------------------------------------------------------------------------
/etc/dbus-1/org.freedesktop.Notifications.conf:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/etc/dbus-1/org.freedesktop.Notifications.service:
--------------------------------------------------------------------------------
1 | [D-BUS Service]
2 | Name=org.freedesktop.Notifications
3 | Exec=/usr/libexec/notification-daemon
4 |
--------------------------------------------------------------------------------
/etc/logrotate.d/ltsm:
--------------------------------------------------------------------------------
1 | /var/log/ltsm.log
2 | /var/log/ltsm_connector.log {
3 | missingok
4 | notifempty
5 | rotate 14
6 | daily
7 | compress
8 | nocreate
9 | }
10 |
--------------------------------------------------------------------------------
/etc/ltsm/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "service:debug:level": "debug",
3 | "#service:debug:types": [ "all" ],
4 |
5 | "connector:debug:level": "info",
6 | "#connector:debug:types": [ "all" ],
7 |
8 | "logging:facility": "local6",
9 |
10 | "vnc:encoding:debug": 0,
11 | "vnc:encoding:threads": 4,
12 | "vnc:encoding:blacklist": [ "zlib" ],
13 | "vnc:gnutls:disable": false,
14 | "vnc:gnutls:debug": 3,
15 | "vnc:gnutls:anonmode": true,
16 | "vnc:gnutls:priority": "NORMAL:+ANON-ECDH:+ANON-DH",
17 | "vnc:gnutls:cafile": "/etc/ltsm/cacerts.pem",
18 | "vnc:gnutls:crlfile": "/etc/ltsm/server.crl",
19 | "vnc:gnutls:certfile": "/etc/ltsm/server.crt",
20 | "vnc:gnutls:keyfile": "/etc/ltsm/server.key",
21 | "#vnc:keymap:file": "/etc/ltsm/keymap_vnc.json",
22 | "#vnc:xcb:nodamage": false,
23 | "vnc:clipboard": true,
24 |
25 | "vnc:kerberos:disable": false,
26 | "vnc:kerberos:service": "TERMSRV",
27 | "vnc:kerberos:keytab": "/etc/ltsm/termsrv.keytab",
28 | "#vnc:kerberos:trace": "/var/tmp/ltsm_krb5.trace",
29 |
30 | "rdp:wlog:level": "error",
31 | "rdp:security:rdp": true,
32 | "rdp:security:tls": true,
33 | "rdp:security:nla": false,
34 | "rdp:tls:level": 1,
35 | "rdp:encryption:level": "compatible",
36 | "rdp:server:certfile": "/etc/ltsm/server.crt",
37 | "rdp:server:keyfile": "/etc/ltsm/server.key",
38 | "#rdp:keymap:file": "/etc/ltsm/keymap_rdp.json",
39 |
40 | "transfer:file:disabled": false,
41 | "transfer:file:max": 100000000,
42 | "#transfer:group:only": "transfer-allow",
43 |
44 | "channel:printer:disabled": false,
45 | "channel:printer:format": "/var/run/ltsm/cups/printer_%{user}",
46 | "channel:audio:disabled": false,
47 | "channel:audio:format": "/var/run/ltsm/audio/%{user}",
48 | "channel:pcsc:disabled": false,
49 | "channel:pcsc:format": "/var/run/ltsm/pcsc/%{user}",
50 | "channel:fuse:disabled": false,
51 | "channel:fuse:format": "/var/run/ltsm/fuse/%{user}",
52 | "channel:sane:disabled": false,
53 |
54 | "#idle:timeout:xvfb": 10,
55 | "#idle:timeout:login": 70,
56 | "#idle:timeout:logout": 0,
57 |
58 | "#idle:action:timeout": 0,
59 | "#idle:action:path": "/usr/bin/xlock",
60 | "#idle:action:args": [],
61 |
62 | "group:shm": "ltsm-shm",
63 | "group:auth": "ltsm-auth",
64 | "user:xvfb": "ltsm-xvfb",
65 | "pam:service": "ltsm",
66 |
67 | "#access:groups": [ "ts-users", "ts-admins" ],
68 | "access:uid:min": 100,
69 | "access:uid:max": 9999,
70 | "#access:users": [ "demo1", "demo2", "demo3", "demoadm" ],
71 |
72 | "helper:autocomplete": true,
73 | "helper:path": "/usr/libexec/ltsm/LTSM_helper",
74 | "helper:args": "",
75 | "helper:dateformat": "dddd dd MMMM, hh:mm:ss",
76 | "helper:title": "X11 Remote Desktop Service (%{version})",
77 |
78 | "login:failures_count": 3,
79 | "session:kill:stop": false,
80 | "session:policy": "authlock",
81 | "session:path": "/etc/ltsm/xclients",
82 |
83 | "zenity:path": "/usr/bin/zenity",
84 |
85 | "default:width": 1024,
86 | "default:height": 768,
87 |
88 | "display:min": 55,
89 | "display:max": 99,
90 | "display:solid": "0x4e7db7",
91 | "display:cursor": "left_ptr",
92 |
93 | "xauth:file": "/var/run/ltsm/auth_%{display}",
94 |
95 | "xvfb:path": "/usr/bin/Xvfb",
96 | "xvfb:args": ":%{display} -nolisten tcp -screen 0 %{width}x%{height}x24 -auth %{authfile} +extension DAMAGE +extension MIT-SHM +extension RANDR +extension XFIXES +extension XTEST",
97 | "xvfb:socket": "/tmp/.X11-unix/X%{display}",
98 |
99 | "#session:connect": "/path/script",
100 | "#session:disconnect": "/path/script",
101 |
102 | "#system:connect": "",
103 | "#system:disconnect": "",
104 |
105 | "#system:logon": "/usr/bin/sessreg -a -l :%{display} %{user}",
106 | "#system:logoff": "/usr/bin/sessreg -d -l :%{display} %{user}"
107 | }
108 |
--------------------------------------------------------------------------------
/etc/ltsm/keymap_rdp.json:
--------------------------------------------------------------------------------
1 | {
2 | "keyname_hex8": "value integer or [array]",
3 |
4 | "keysym:left": 0,
5 | "0x4100004b": 100,
6 | "0x8100004b": 100,
7 | "key:right": 0,
8 | "0x4100004d": 102,
9 | "0x8100004d": 102,
10 | "key:up": 0,
11 | "0x41000048": 98,
12 | "0x81000048": 98,
13 | "key:down": 0,
14 | "0x41000050": 104,
15 | "0x81000050": 104,
16 | "key:rctrl": 0,
17 | "0x4100001d": 109,
18 | "0x8100001d": 109,
19 | "key:lalt": 0,
20 | "0x41000040": 125,
21 | "0x81000040": 125,
22 | "key:ralt": 0,
23 | "0x41000038": 113,
24 | "0x81000038": 113,
25 | "key:context":0,
26 | "0x4100005d": 117,
27 | "0x8100005d": 117,
28 | "key:insert": 0,
29 | "0x41000052": 106,
30 | "0x81000052": 106,
31 | "key:delete": 0,
32 | "0x41000053": 107,
33 | "0x81000053": 107,
34 | "key:pageup": 0,
35 | "0x41000049": 99,
36 | "0x81000049": 99,
37 | "key:pagedw": 0,
38 | "0x41000051": 105,
39 | "0x81000051": 105,
40 | "key:home": 0,
41 | "0x41000047": 97,
42 | "0x81000047": 97,
43 | "key:end": 0,
44 | "0x4100004f": 103,
45 | "0x8100004f": 103
46 | }
47 |
--------------------------------------------------------------------------------
/etc/ltsm/keymap_vnc.json:
--------------------------------------------------------------------------------
1 | {
2 | "keyname_hex8": "value integer or [array]"
3 | }
4 |
--------------------------------------------------------------------------------
/etc/ltsm/xclients:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Xclients
4 | #
5 |
6 | errfile="${HOME}/.xsession-errors"
7 | if ( umask 077 && cp /dev/null "${errfile}" 2> /dev/null ); then
8 | chmod 600 "${errfile}"
9 | exec > "${errfile}" 2>&1
10 | fi
11 |
12 | UID=`id --user`
13 | export XDG_CONFIG_DIRS="/etc/xdg"
14 | export XDG_DATA_DIRS="/usr/share"
15 | export XDG_RUNTIME_DIR=/run/user/$UID
16 | export XDG_SESSION_TYPE="x11"
17 |
18 | mkdir $XDG_RUNTIME_DIR
19 | chmod 700 $XDG_RUNTIME_DIR
20 |
21 | if [ -d /etc/X11/xinit/xinitrc.d ]; then
22 | for SCRIPT in /etc/X11/xinit/xinitrc.d/*.sh; do
23 | if [ -f ${SCRIPT} ]; then
24 | . ${SCRIPT} > /dev/null 2>&1
25 | fi
26 | done
27 | fi
28 |
29 | if [ -f /etc/X11/Xresources ]; then
30 | xrdb -load /etc/X11/Xresources
31 | fi
32 |
33 | if [ -f ${HOME}/.Xresources ]; then
34 | xrdb -merge ${HOME}/.Xresources
35 | fi
36 |
37 | # model:
38 | # setxkbmap -model pc105 -layout us -option ''
39 | #
40 | # change layout:
41 | # setxkbmap -option ""
42 | # setxkbmap -layout "us,ru" -variant ",winkeys" -option "grp:ctrl_shift_toggle"
43 | #
44 | # change symbol:
45 | # setxkbmap -symbols "+kpdl(dotoss)+kpdl(dotoss):2"
46 |
47 | if [ -f /etc/X11/Xmodmap ]; then
48 | xmodmap /etc/X11/Xmodmap
49 | fi
50 |
51 | if [ -f ${HOME}/.Xmodmap ]; then
52 | xmodmap ${HOME}/.Xmodmap
53 | fi
54 |
55 | if [ -z "$XSESSION" ]; then
56 | if [ -x /usr/bin/icewm-session ]; then
57 | XSESSION=/usr/bin/icewm-session
58 | else
59 | XSESSION=/usr/bin/xterm
60 | fi
61 | fi
62 |
63 | exec ${XSESSION}
64 |
--------------------------------------------------------------------------------
/etc/pam/ltsm:
--------------------------------------------------------------------------------
1 | #%PAM-1.0
2 | auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
3 | auth substack system-auth
4 | auth include postlogin
5 | account required pam_nologin.so
6 | account include system-auth
7 | password include system-auth
8 |
9 | # pam_selinux.so close should be the first session rule
10 | session required pam_selinux.so close
11 | session required pam_loginuid.so
12 | session optional pam_console.so
13 |
14 | # pam_selinux.so open should only be followed by sessions to be executed in the user context
15 | session required pam_selinux.so open
16 | session required pam_namespace.so
17 | session include system-auth
18 | session include postlogin
19 |
--------------------------------------------------------------------------------
/etc/pam/xserver:
--------------------------------------------------------------------------------
1 | #%PAM-1.0
2 | auth sufficient pam_rootok.so
3 | auth required pam_permit.so
4 | account required pam_permit.so
5 | session optional pam_keyinit.so force revoke
6 |
--------------------------------------------------------------------------------
/etc/rsyslog/ltsm.conf:
--------------------------------------------------------------------------------
1 | template(name="ltsm_format" type="string"
2 | string="%$DAY%.%$MONTH%.%$YEAR% %TIMESTAMP:12:19:date-rfc3339% %syslogtag% %msg:::drop-last-lf%\n")
3 |
4 | template(name="connector_format" type="string"
5 | string="%$DAY%.%$MONTH%.%$YEAR% %TIMESTAMP:12:19:date-rfc3339% [%$!_PID%]: %msg:::drop-last-lf%\n")
6 |
7 | if $programname == "ltsm_connector" then {
8 |
9 | action(type="omfile" template="connector_format"
10 | flushOnTXEnd="off" asyncWriting="on" flushInterval="1" ioBufferSize="1k" file="/var/log/ltsm_connector.log")
11 |
12 | stop
13 | }
14 |
15 | if $programname contains "ltsm_" then {
16 |
17 | action(type="omfile" template="ltsm_format"
18 | flushOnTXEnd="off" asyncWriting="on" flushInterval="1" ioBufferSize="1k" file="/var/log/ltsm_service.log")
19 |
20 | stop
21 | }
22 |
--------------------------------------------------------------------------------
/etc/systemd/ltsm_connector_rdp.socket:
--------------------------------------------------------------------------------
1 | [Socket]
2 | ListenStream=3389
3 | Accept=yes
4 |
5 | [Install]
6 | WantedBy=sockets.target
7 |
--------------------------------------------------------------------------------
/etc/systemd/ltsm_connector_rdp@.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LTSM connector
3 | After=network.target
4 | #ltsm_service.service
5 |
6 | [Service]
7 | Type=simple
8 | ExecStart=-/usr/local/sbin/LTSM_connector --type rdp
9 | User=ltsm-xvfb
10 | Group=ltsm-shm
11 | StandardInput=socket
12 | StandardOutput=socket
13 | LimitCORE=infinity
14 |
15 | [Install]
16 | WantedBy=multi-user.target
17 |
--------------------------------------------------------------------------------
/etc/systemd/ltsm_connector_vnc.socket:
--------------------------------------------------------------------------------
1 | [Socket]
2 | ListenStream=5900
3 | Accept=yes
4 |
5 | [Install]
6 | WantedBy=sockets.target
7 |
--------------------------------------------------------------------------------
/etc/systemd/ltsm_connector_vnc@.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LTSM connector
3 | After=network.target ltsm_service.service
4 |
5 | [Service]
6 | Type=simple
7 | ExecStart=-/usr/local/sbin/LTSM_connector --type vnc
8 | User=ltsm-xvfb
9 | Group=ltsm-shm
10 | StandardInput=socket
11 | StandardOutput=socket
12 |
13 | [Install]
14 | WantedBy=multi-user.target
15 |
--------------------------------------------------------------------------------
/etc/systemd/ltsm_service.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=LTSM service
3 |
4 | [Service]
5 | ExecStart=/usr/local/sbin/LTSM_service
6 |
7 | [Install]
8 | WantedBy=multi-user.target
9 |
--------------------------------------------------------------------------------
/etc/xinet/jetdirect:
--------------------------------------------------------------------------------
1 | service jetdirect
2 | {
3 | disable = no
4 | flags = IPv4
5 | type = UNLISTED
6 | socket_type = stream
7 | protocol = tcp
8 | bind = 127.0.0.1
9 | port = 9100
10 | wait = no
11 | user = lp
12 | server = /usr/lib/cups/daemon/cups-lpd
13 | server_args = -o document-format=application/octet-stream -o job-sheets=none
14 | }
15 |
--------------------------------------------------------------------------------
/etc/xinet/ltsm_connector:
--------------------------------------------------------------------------------
1 | service rfb
2 | {
3 | port = 5900
4 | disable = no
5 | flags = REUSE
6 | socket_type = stream
7 | wait = no
8 | user = ltsm-xvfb
9 | server = /usr/local/sbin/LTSM_connector
10 | server_args = --type vnc
11 | }
12 |
13 | service ms-wbt-server
14 | {
15 | port = 3389
16 | disable = no
17 | flags = REUSE
18 | socket_type = stream
19 | wait = no
20 | user = ltsm-xvfb
21 | server = /usr/local/sbin/LTSM_connector
22 | server_args = --type rdp
23 | }
24 |
--------------------------------------------------------------------------------
/etc/xorg/ltsm.conf:
--------------------------------------------------------------------------------
1 | # This xorg configuration file is meant to be used by xpra
2 | # to start a dummy X11 server.
3 | # For details, please see:
4 | # https://xpra.org/Xdummy.html
5 |
6 | Section "ServerFlags"
7 | Option "DontVTSwitch" "true"
8 | Option "AllowMouseOpenFail" "true"
9 | Option "PciForceNone" "true"
10 | Option "AutoEnableDevices" "false"
11 | Option "AutoAddDevices" "false"
12 | EndSection
13 |
14 | Section "InputDevice"
15 | Identifier "dummy_mouse"
16 | Option "CorePointer" "true"
17 | Driver "void"
18 | EndSection
19 |
20 | Section "InputDevice"
21 | Identifier "dummy_keyboard"
22 | Option "CoreKeyboard" "true"
23 | Driver "void"
24 | EndSection
25 |
26 | Section "Device"
27 | Identifier "dummy_videocard"
28 | Driver "dummy"
29 | Option "ConstantDPI" "true"
30 | VideoRam 64000
31 | EndSection
32 |
33 | Section "Monitor"
34 | Identifier "dummy_monitor"
35 | HorizSync 5.0 - 300.0
36 | VertRefresh 5.0 - 200.0
37 | #NOTE: the highest modes will not work without increasing the VideoRam
38 | # for the dummy video card.
39 | Modeline "1920x1440" 69.47 1920 1960 2152 2384 1440 1441 1444 1457
40 | Modeline "1920x1200" 26.28 1920 1952 2048 2080 1200 1229 1231 1261
41 | Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135
42 | Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103
43 | Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261
44 | Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946
45 | Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946
46 | ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803
47 | Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076
48 | Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841
49 | Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807
50 | Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807
51 | Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807
52 | EndSection
53 |
54 | Section "Screen"
55 | Identifier "dummy_screen"
56 | Device "dummy_videocard"
57 | Monitor "dummy_monitor"
58 | DefaultDepth 24
59 | SubSection "Display"
60 | Viewport 0 0
61 | Depth 24
62 | Modes "1920x1440" "1920x1200" "1920x1080" "1600x1200" "1680x1050" "1600x900" "1400x1050" "1440x900" "1280x1024" "1366x768" "1280x800" "1024x768"
63 | Virtual 1920 1440
64 | EndSubSection
65 | EndSection
66 |
67 | Section "ServerLayout"
68 | Identifier "dummy_layout"
69 | Screen "dummy_screen"
70 | InputDevice "dummy_mouse"
71 | InputDevice "dummy_keyboard"
72 | EndSection
73 |
--------------------------------------------------------------------------------
/sonar-project.properties:
--------------------------------------------------------------------------------
1 | sonar.projectName=linux-terminal-service-manager
2 | sonar.projectVersion=20250522
3 | sonar.projectKey=AndreyBarmaley_linux-terminal-service-manager
4 | sonar.organization=andreybarmaley
5 |
6 | sonar.sources=src
7 | sonar.exclusions=src/common/flat_hash_map/**,src/common/jsmn/**,src/common/libxcb-errors/**,src/service/alexab_safe_ptr.h,src/tests/**
8 | sonar.cfamily.cache.enabled=false
9 |
10 | # Encoding of the source code. Default is default system encoding
11 | sonar.sourceEncoding=UTF-8
12 |
--------------------------------------------------------------------------------
/src/channels/ltsm_channels.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2022 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_CHANNELS_
25 | #define _LTSM_CHANNELS_
26 |
27 | #include "channel_system.h"
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/common/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.13)
2 |
3 | target_sources(LTSM_common PUBLIC ltsm_application.cpp)
4 | target_sources(LTSM_common PUBLIC ltsm_json_wrapper.cpp)
5 | target_sources(LTSM_common PUBLIC ltsm_tools.cpp)
6 | target_sources(LTSM_common PUBLIC ltsm_streambuf.cpp)
7 | target_sources(LTSM_common PUBLIC ltsm_sockets.cpp)
8 | target_sources(LTSM_common PUBLIC ltsm_framebuffer.cpp)
9 | target_sources(LTSM_common PUBLIC ltsm_xcb_types.cpp)
10 |
11 | if(UNIX)
12 | target_sources(LTSM_common PUBLIC ltsm_xcb_wrapper.cpp)
13 |
14 | if(LTSM_BUILD_XCB_ERRORS)
15 | target_sources(LTSM_common PUBLIC libxcb-errors/xcb_errors.c libxcb-errors/extensions.c)
16 | endif()
17 | endif()
18 |
--------------------------------------------------------------------------------
/src/common/libxcb-errors/errors.h:
--------------------------------------------------------------------------------
1 | #ifndef __ERRORS_H__
2 | #define __ERRORS_H__
3 |
4 | /* Copyright © 2015 Uli Schlachter
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a
7 | * copy of this software and associated documentation files (the "Software"),
8 | * to deal in the Software without restriction, including without limitation
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | * Except as contained in this notice, the names of the authors or their
24 | * institutions shall not be used in advertising or otherwise to promote the
25 | * sale, use or other dealings in this Software without prior written
26 | * authorization from the authors.
27 | */
28 |
29 | #include "xcb_errors.h"
30 |
31 | struct static_extension_info_t {
32 | uint16_t num_minor;
33 | uint16_t num_xge_events;
34 | uint8_t num_events;
35 | uint8_t num_errors;
36 | const char *strings_minor;
37 | const char *strings_xge_events;
38 | const char *strings_events;
39 | const char *strings_errors;
40 | const char *name;
41 | };
42 |
43 | extern const struct static_extension_info_t xproto_info;
44 |
45 | int register_extensions(xcb_errors_context_t *ctx, xcb_connection_t *conn);
46 | int register_extension(xcb_errors_context_t *ctx, xcb_connection_t *conn,
47 | xcb_query_extension_cookie_t cookie,
48 | const struct static_extension_info_t *static_info);
49 |
50 | #endif /* __ERRORS_H__ */
51 |
--------------------------------------------------------------------------------
/src/common/ltsm_application.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _LTSM_APPLICATION_
24 | #define _LTSM_APPLICATION_
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #ifdef WITH_JSON
33 | #include "ltsm_json_wrapper.h"
34 | #endif
35 |
36 | namespace LTSM
37 | {
38 | enum class DebugTarget { Quiet, Console, Syslog };
39 | enum class DebugLevel { None, Info, Debug, Trace };
40 |
41 | enum DebugType
42 | {
43 | All = 0xFFFFFFFF,
44 | Xcb = 1 << 31,
45 | Rfb = 1 << 30,
46 | Clip = 1 << 29,
47 | Socket = 1 << 28,
48 | Tls = 1 << 27,
49 | Channels = 1 << 26,
50 | Conn = 1 << 25,
51 | Enc = 1 << 24,
52 | X11Srv = 1 << 23,
53 | X11Cli = 1 << 22,
54 | WinCli = X11Cli,
55 | Audio = 1 << 21,
56 | Fuse = 1 << 20,
57 | Pcsc = 1 << 19,
58 | Pkcs11 = 1 << 18,
59 | Sdl = 1 << 17,
60 | App = 1 << 16,
61 | Mgr = 1 << 15,
62 | Ldap = 1 << 14,
63 | Gss = 1 << 13
64 | };
65 |
66 | class Application
67 | {
68 | public:
69 | explicit Application(std::string_view ident);
70 | virtual ~Application();
71 |
72 | Application(Application &) = delete;
73 | Application & operator= (const Application &) = delete;
74 |
75 | static void info(const char* format, ...);
76 | static void notice(const char* format, ...);
77 | static void warning(const char* format, ...);
78 | static void error(const char* format, ...);
79 | static void vdebug(uint32_t subsys, const char* format, va_list args);
80 | static void debug(uint32_t subsys, const char* format, ...);
81 | static void vtrace(uint32_t subsys, const char* format, va_list args);
82 | static void trace(uint32_t subsys, const char* format, ...);
83 |
84 | static void redirectSyslogFile(const char* file = nullptr);
85 | static void setDebug(const DebugTarget &, const DebugLevel &);
86 |
87 | static void setDebugTarget(const DebugTarget &);
88 | static void setDebugTarget(std::string_view target);
89 | static void setDebugTargetFile(const std::filesystem::path & file);
90 | static bool isDebugTarget(const DebugTarget &);
91 |
92 | static void setDebugLevel(const DebugLevel &);
93 | static void setDebugLevel(std::string_view level);
94 | static bool isDebugLevel(const DebugLevel &);
95 |
96 | static void setDebugTypes(uint32_t);
97 | static bool isDebugTypes(uint32_t vals);
98 |
99 | virtual int start(void) = 0;
100 | };
101 |
102 | #ifdef WITH_JSON
103 | class ApplicationJsonConfig : public Application
104 | {
105 | JsonObject json;
106 |
107 | protected:
108 | void configSet(JsonObject &&) noexcept;
109 |
110 | public:
111 | ApplicationJsonConfig(std::string_view ident, const char* fconf = nullptr);
112 |
113 | void readConfig(const std::filesystem::path &);
114 |
115 | void configSetInteger(const std::string &, int);
116 | void configSetBoolean(const std::string &, bool);
117 | void configSetString(const std::string &, std::string_view);
118 | void configSetDouble(const std::string &, double);
119 |
120 | int configGetInteger(std::string_view, int = 0) const;
121 | bool configGetBoolean(std::string_view, bool = false) const;
122 | std::string configGetString(std::string_view, std::string_view = "") const;
123 | double configGetDouble(std::string_view, double = 0) const;
124 |
125 | const JsonObject & config(void) const;
126 | };
127 |
128 | #endif
129 | }
130 |
131 | #endif // _LTSM_APPLICATION_
132 |
--------------------------------------------------------------------------------
/src/common/ltsm_global.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _LTSM_GLOBALS_
24 | #define _LTSM_GLOBALS_
25 |
26 | namespace LTSM
27 | {
28 | inline static const char* dbus_manager_service_name = "ltsm.manager.service";
29 | inline static const char* dbus_manager_service_path = "/ltsm/manager/service";
30 |
31 | inline static const char* dbus_session_fuse_name = "ltsm.session.fuse";
32 | inline static const char* dbus_session_fuse_path = "/ltsm/session/fuse";
33 |
34 | inline static const char* dbus_session_audio_name = "ltsm.session.audio";
35 | inline static const char* dbus_session_audio_path = "/ltsm/session/audio";
36 |
37 | inline static const char* dbus_session_pcsc_name = "ltsm.session.pcsc";
38 | inline static const char* dbus_session_pcsc_path = "/ltsm/session/pcsc";
39 |
40 | inline static const int service_version = 20250601;
41 |
42 | inline bool platformBigEndian(void)
43 | {
44 | #if (__BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
45 | return true;
46 | #else
47 | return false;
48 | #endif
49 | }
50 |
51 | namespace NotifyParams
52 | {
53 | enum IconType { Information, Warning, Error, Question };
54 | enum UrgencyLevel { Low = 0, Normal = 1, Critical = 2 };
55 | };
56 | }
57 |
58 | #if defined(LTSM_BUILD_STD_MAP) || defined(__MINGW32__)
59 | #include
60 | #include
61 | #define INTMAP std::unordered_map
62 | #define INTSET std::unordered_set
63 | #else
64 | #include "flat_hash_map/unordered_map.hpp"
65 | #define INTMAP ska::unordered_map
66 | #define INTSET ska::unordered_set
67 | #endif
68 |
69 | #endif // _LTSM_GLOBALS_
70 |
--------------------------------------------------------------------------------
/src/common/ltsm_xcb_types.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _LTSM_XCB_TYPES_
24 | #define _LTSM_XCB_TYPES_
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | namespace LTSM
32 | {
33 | struct xcb_error : public std::runtime_error
34 | {
35 | explicit xcb_error(std::string_view what) : std::runtime_error(what.data()) {}
36 | };
37 |
38 | namespace XCB
39 | {
40 | struct Point
41 | {
42 | int16_t x, y;
43 |
44 | Point() : x(-1), y(-1) {}
45 |
46 | Point(int16_t px, int16_t py) : x(px), y(py) {}
47 |
48 | virtual ~Point() = default;
49 |
50 | virtual bool isValid(void) const { return 0 <= x && 0 <= y; }
51 |
52 | Point operator+(const Point & pt) const { return Point(x + pt.x, y + pt.y); }
53 |
54 | Point operator-(const Point & pt) const { return Point(x - pt.x, y - pt.y); }
55 |
56 | bool operator==(const Point & pt) const { return pt.x == x && pt.y == y; }
57 |
58 | bool operator!=(const Point & pt) const { return pt.x != x || pt.y != y; }
59 | };
60 |
61 | struct Size
62 | {
63 | uint16_t width, height;
64 |
65 | Size() : width(0), height(0) {}
66 |
67 | Size(uint16_t sw, uint16_t sh) : width(sw), height(sh) {}
68 |
69 | virtual ~Size() = default;
70 |
71 | bool isEmpty(void) const { return width == 0 || height == 0; }
72 |
73 | void reset(void) { width = 0; height = 0; }
74 |
75 | bool operator==(const Size & sz) const { return sz.width == width && sz.height == height; }
76 |
77 | bool operator!=(const Size & sz) const { return sz.width != width || sz.height != height; }
78 | };
79 |
80 | struct PointIterator : Point
81 | {
82 | const Size limit;
83 | PointIterator(int16_t px, int16_t py, const Size & sz) : Point(px, py), limit(sz) {}
84 |
85 | PointIterator & operator++(void);
86 | PointIterator & operator--(void);
87 |
88 | bool isValid(void) const override { return Point::isValid() && x < limit.width && y < limit.height; }
89 |
90 | bool isBeginLine(void) const;
91 | bool isEndLine(void) const;
92 | virtual void lineChanged(void) { /* default empty */ }
93 | };
94 |
95 | struct Region : public Point, public Size
96 | {
97 | Region() = default;
98 |
99 | Region(const Point & pt, const Size & sz) : Point(pt), Size(sz) {}
100 |
101 | Region(int16_t rx, int16_t ry, uint16_t rw, uint16_t rh) : Point(rx, ry), Size(rw, rh) {}
102 |
103 | const Point & topLeft(void) const { return *this; }
104 |
105 | const Size & toSize(void) const { return *this; }
106 |
107 | PointIterator coordBegin(void) const { return PointIterator(0, 0, toSize()); }
108 |
109 | bool operator== (const Region & rt) const { return rt.x == x && rt.y == y && rt.width == width && rt.height == height; }
110 |
111 | bool operator!= (const Region & rt) const { return rt.x != x || rt.y != y || rt.width != width || rt.height != height; }
112 |
113 | void reset(void);
114 |
115 | void assign(int16_t rx, int16_t ry, uint16_t rw, uint16_t rh);
116 | void assign(const Region &);
117 |
118 | void join(int16_t rx, int16_t ry, uint16_t rw, uint16_t rh);
119 | void join(const Region &);
120 |
121 | bool empty(void) const;
122 | bool invalid(void) const;
123 |
124 | Region intersected(const Region &) const;
125 | Region align(size_t) const;
126 |
127 | static bool intersects(const Region &, const Region &);
128 | static bool intersection(const Region &, const Region &, Region* res);
129 |
130 | std::list divideBlocks(const Size &) const;
131 | std::list divideCounts(uint16_t cols, uint16_t rows) const;
132 | };
133 |
134 | Region operator- (const Region &, const Point &);
135 | Region operator+ (const Region &, const Point &);
136 |
137 | struct HasherRegion
138 | {
139 | size_t operator()(const Region & reg) const
140 | {
141 | return std::hash()((static_cast(reg.x) << 48) | (static_cast(reg.y) << 32) |
142 | (static_cast(reg.width) << 16) | static_cast(reg.height));
143 | }
144 | };
145 |
146 | struct RegionPixel : std::pair
147 | {
148 | RegionPixel(const Region & reg, uint32_t pixel) : std::pair(reg, pixel) {}
149 |
150 | RegionPixel() = default;
151 |
152 | const uint32_t & pixel(void) const { return second; }
153 |
154 | const Region & region(void) const { return first; }
155 | };
156 | }
157 | }
158 |
159 | #endif // _LTSM_XCB_TYPES_
160 |
--------------------------------------------------------------------------------
/src/connector/ltsm_connector_rdp.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_CONNECTOR_RDP_
25 | #define _LTSM_CONNECTOR_RDP_
26 |
27 | #include
28 |
29 | #include "ltsm_sockets.h"
30 | #include "ltsm_connector.h"
31 |
32 | #include "freerdp/freerdp.h"
33 | #include "freerdp/listener.h"
34 |
35 | namespace LTSM
36 | {
37 | struct FreeRdpCallback;
38 |
39 | struct rdp_error : public std::runtime_error
40 | {
41 | explicit rdp_error(std::string_view what) : std::runtime_error(what.data()) {}
42 | };
43 |
44 | namespace Connector
45 | {
46 | /* Connector::RDP */
47 | class RDP : public SignalProxy, public XCB::RootDisplay, protected ProxySocket
48 | {
49 | std::atomic helperStartedFlag{false};
50 | std::atomic loopShutdownFlag{false};
51 | std::atomic updatePartFlag{true};
52 | std::unique_ptr freeRdp;
53 | PixelFormat serverFormat;
54 | XCB::Region damageRegion;
55 |
56 | protected:
57 | // dbus virtual signals
58 | void onLoginSuccess(const int32_t & display, const std::string & userName,
59 | const uint32_t & userUid) override;
60 | void onSendBellSignal(const int32_t & display) override;
61 | void onShutdownConnector(const int32_t & display) override;
62 | void onHelperWidgetStarted(const int32_t & display) override;
63 |
64 | // connector
65 | void serverScreenUpdateRequest(const XCB::Region &) override;
66 |
67 | // root display
68 | void xcbDamageNotifyEvent(const xcb_rectangle_t &) override;
69 | void xcbRandrScreenChangedEvent(const XCB::Size &, const xcb_randr_notify_event_t &) override;
70 | void xcbXkbGroupChangedEvent(int) override;
71 |
72 | bool updateEvent(const XCB::Region &);
73 | bool updateBitmapPlanar(const XCB::Region &, const XCB::PixmapInfoReply &);
74 | bool updateBitmapInterleaved(const XCB::Region &, const XCB::PixmapInfoReply &);
75 | void desktopResizeEvent(freerdp_peer &, uint16_t, uint16_t);
76 | void disconnectedEvent(void);
77 |
78 | bool xcbEventLoopAsync(bool nodamage);
79 |
80 | bool channelsInit(void);
81 | void channelsFree(void);
82 |
83 | public:
84 | RDP(const JsonObject &);
85 | ~RDP();
86 |
87 | int communication(void) override;
88 | bool createX11Session(uint8_t depth);
89 | void setEncryptionInfo(const std::string &);
90 | void setAutoLogin(const std::string &, const std::string &);
91 |
92 | // freerdp callback func
93 | static BOOL cbServerPostConnect(freerdp_peer* client);
94 | static BOOL cbServerActivate(freerdp_peer* client);
95 | static BOOL cbServerAuthenticate(freerdp_peer* client, const char** user, const char** domain,
96 | const char** password);
97 | static BOOL cbServerSynchronizeEvent(rdpInput* input, UINT32 flags);
98 | static BOOL cbServerKeyboardEvent(rdpInput* input, UINT16 flags, UINT16 code);
99 | static BOOL cbServerMouseEvent(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
100 | static BOOL cbServerRefreshRect(rdpContext* context, BYTE count, const RECTANGLE_16* areas);
101 | static BOOL cbServerSuppressOutput(rdpContext* context, BYTE allow, const RECTANGLE_16* area);
102 | static BOOL cbServerRefreshRequest(freerdp_peer* client);
103 |
104 | static BOOL cbServerClose(freerdp_peer* client);
105 | static void cbServerDisconnect(freerdp_peer* client);
106 | static BOOL cbServerCapabilities(freerdp_peer* client);
107 | static BOOL cbServerAdjustMonitorsLayout(freerdp_peer* client);
108 | static BOOL cbServerClientCapabilities(freerdp_peer* client);
109 | };
110 | }
111 | }
112 |
113 | #endif // _LTSM_CONNECTOR_RDP_
114 |
--------------------------------------------------------------------------------
/src/connector/ltsm_connector_vnc.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_CONNECTOR_VNC_
25 | #define _LTSM_CONNECTOR_VNC_
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include "librfb_x11server.h"
35 | #include "ltsm_connector.h"
36 |
37 | namespace LTSM
38 | {
39 | struct vnc_error : public std::runtime_error
40 | {
41 | explicit vnc_error(std::string_view what) : std::runtime_error(what.data()) {}
42 | };
43 |
44 | namespace Connector
45 | {
46 | /* Connector::VNC */
47 | class VNC : public SignalProxy, protected RFB::X11Server
48 | {
49 | PixelFormat serverPf;
50 |
51 | std::unordered_mapkeymap;
52 |
53 | std::list> transfer;
54 | std::mutex lockTransfer;
55 |
56 | std::chrono::time_point
57 | idleSession;
58 | size_t idleTimeoutSec = 0;
59 |
60 | std::atomic frameRate{16};
61 | std::atomic loginWidgetStarted{false};
62 | std::atomic userSession{false};
63 | std::atomic x11NoDamage{false};
64 | uid_t shmUid = 0;
65 |
66 | protected:
67 | // rfb server encoding
68 | const PixelFormat & serverFormat(void) const override;
69 | void serverFrameBufferModifyEvent(FrameBuffer &) const override;
70 | std::forward_list serverDisabledEncodings(void) const override;
71 |
72 | // x11server
73 | bool xcbNoDamageOption(void) const override;
74 | void xcbDisableMessages(bool) override;
75 | bool xcbAllowMessages(void) const override;
76 | size_t frameRateOption(void) const override;
77 |
78 | bool rfbClipboardEnable(void) const override;
79 | bool rfbDesktopResizeEnabled(void) const override;
80 | RFB::SecurityInfo rfbSecurityInfo(void) const override;
81 | int rfbUserKeycode(uint32_t) const override;
82 |
83 | void serverRecvKeyEvent(bool pressed, uint32_t keysym) override;
84 | void serverRecvPointerEvent(uint8_t mask, uint16_t posx, uint16_t posy) override;
85 |
86 | // dbus virtual signals
87 | void onLoginSuccess(const int32_t & display, const std::string & userName,
88 | const uint32_t & userUid) override;
89 | void onShutdownConnector(const int32_t & display) override;
90 | void onHelperWidgetStarted(const int32_t & display) override;
91 | void onSendBellSignal(const int32_t & display) override;
92 |
93 | // connector
94 | void serverScreenUpdateRequest(const XCB::Region &) override;
95 |
96 | void onLoginFailure(const int32_t & display, const std::string & msg) override;
97 | void onCreateChannel(const int32_t & display, const std::string & client, const std::string & cmode,
98 | const std::string & server, const std::string & smode, const std::string & speed) override;
99 | void onDestroyChannel(const int32_t & display, const uint8_t & channel) override;
100 | void onTransferAllow(const int32_t & display, const std::string & filepath, const std::string & tmpfile,
101 | const std::string & dstdir) override;
102 | void onCreateListener(const int32_t & display, const std::string & client, const std::string & cmode,
103 | const std::string & server, const std::string & smode, const std::string & speed, const uint8_t & limit,
104 | const uint32_t & flags) override;
105 | void onDestroyListener(const int32_t & display, const std::string & client,
106 | const std::string & server) override;
107 | void onDebugChannel(const int32_t & display, const uint8_t & channel, const bool & debug) override;
108 |
109 | void serverHandshakeVersionEvent(void) override;
110 | void serverEncodingSelectedEvent(void) override;
111 | void serverSecurityInitEvent(void) override;
112 | void serverConnectedEvent(void) override;
113 | void serverMainLoopEvent(void) override;
114 | void serverDisplayResizedEvent(const XCB::Size &) override;
115 | void serverEncodingsEvent(void) override;
116 |
117 | // rfb channel client
118 | bool isUserSession(void) const override;
119 | void systemChannelError(const JsonObject &) override;
120 | void systemTransferFiles(const JsonObject &) override;
121 | void systemClientVariables(const JsonObject &) override;
122 | void systemKeyboardChange(const JsonObject &) override;
123 |
124 | public:
125 | VNC(const JsonObject & jo) : SignalProxy(jo, "vnc") {}
126 |
127 | ~VNC();
128 |
129 | int communication(void) override;
130 | };
131 | }
132 | }
133 |
134 | #endif // _LTSM_CONNECTOR_VNC_
135 |
--------------------------------------------------------------------------------
/src/dbus/ltsm_audio.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/dbus/ltsm_fuse.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/dbus/ltsm_pcsc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/librfb/ffmpeg_tools.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _FFMPEG_TOOLS_
24 | #define _FFMPEG_TOOLS_
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 | #include "libavformat/avformat.h"
31 |
32 | #ifdef __cplusplus
33 | }
34 |
35 | #endif
36 |
37 | namespace LTSM
38 | {
39 | namespace Tools
40 | {
41 | bool AV_PixelFormatEnumToMasks(AVPixelFormat format, int* bpp, uint32_t* rmask, uint32_t* gmask, uint32_t* bmask, uint32_t* amask, bool debug);
42 | AVPixelFormat AV_PixelFormatEnumFromMasks(int bpp, uint32_t rmask, uint32_t gmask, uint32_t bmask, uint32_t amask, bool debug);
43 | }
44 | }
45 |
46 | #endif // _FFMPEG_TOOLS_
47 |
--------------------------------------------------------------------------------
/src/librfb/librfb_extclip.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LIBRFB_EXTCLIP_
25 | #define _LIBRFB_EXTCLIP_
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include "ltsm_sockets.h"
33 |
34 | #ifdef __UNIX__
35 | #include "ltsm_xcb_wrapper.h"
36 | #endif
37 |
38 | namespace LTSM
39 | {
40 | enum ExtClipCaps
41 | {
42 | TypeText = 1 << 0,
43 | TypeRtf = 1 << 1,
44 | TypeHtml = 1 << 2,
45 | TypeDib = 1 << 3,
46 | TypeFiles= 1 << 4,
47 | Type5 = 1 << 5,
48 | Type6 = 1 << 6,
49 | Type7 = 1 << 7,
50 | Type8 = 1 << 8,
51 | Type9 = 1 << 9,
52 | Type10 = 1 << 10,
53 | Type11 = 1 << 11,
54 | Type12 = 1 << 12,
55 | Type13 = 1 << 13,
56 | Type14 = 1 << 14,
57 | Type15 = 1 << 15,
58 | OpCaps = 1 << 24,
59 | OpRequest= 1 << 25,
60 | OpPeek = 1 << 26,
61 | OpNotify = 1 << 27,
62 | OpProvide= 1 << 28
63 | };
64 |
65 | struct ExtClipTypes
66 | {
67 | int flags = 0;
68 | uint32_t textSize = 0;
69 | uint32_t rtfSize = 0;
70 | uint32_t htmlSize = 0;
71 | uint32_t dibSize = 0;
72 | uint32_t fileSize = 0;
73 | };
74 |
75 | namespace RFB
76 | {
77 | class ServerEncoder;
78 |
79 | /// ExtClip
80 | class ExtClip
81 | {
82 | protected:
83 | int remoteExtClipboardFlags = 0;
84 | uint32_t remoteExtClipTypeTextSz = 0;
85 | uint32_t remoteExtClipTypeRtfSz = 0;
86 | uint32_t remoteExtClipTypeHtmlSz = 0;
87 | uint32_t remoteExtClipTypeDibSz = 0;
88 | uint32_t remoteExtClipTypeFilesSz= 0;
89 |
90 | int localExtClipboardFlags = 0;
91 | uint32_t localExtClipTypeTextSz = 0;
92 | uint32_t localExtClipTypeRtfSz = 0;
93 | uint32_t localExtClipTypeHtmlSz = 0;
94 | uint32_t localExtClipTypeDibSz = 0;
95 | uint32_t localExtClipTypeFilesSz= 0;
96 |
97 | std::mutex localProvide;
98 | uint32_t localProvideTypes = 0;
99 |
100 | protected:
101 | void recvExtClipboardCapsContinue(uint32_t flags, StreamBuf && sb);
102 | void recvExtClipboardRequest(uint32_t flags);
103 | void recvExtClipboardPeek(void);
104 | void recvExtClipboardNotify(uint32_t flags);
105 | void recvExtClipboardProvide(StreamBuf && sb);
106 |
107 | void sendExtClipboardRequest(uint16_t types);
108 | void sendExtClipboardPeek(void);
109 | void sendExtClipboardNotify(uint16_t types);
110 | void sendExtClipboardProvide(uint16_t types);
111 |
112 | virtual uint16_t extClipboardLocalTypes(void) const = 0;
113 | virtual std::vector extClipboardLocalData(uint16_t type) const = 0;
114 | virtual void extClipboardRemoteTypesEvent(uint16_t type) = 0;
115 | virtual void extClipboardRemoteDataEvent(uint16_t type, std::vector &&) = 0;
116 | virtual void extClipboardSendEvent(const std::vector & buf) = 0;
117 |
118 | public:
119 | ExtClip() = default;
120 | virtual ~ExtClip() = default;
121 |
122 | void sendExtClipboardCaps(void);
123 | void recvExtClipboardCaps(StreamBuf &&);
124 |
125 | void setExtClipboardRemoteCaps(int);
126 | int extClipboardRemoteCaps(void) const;
127 |
128 | void setExtClipboardLocalCaps(int);
129 | int extClipboardLocalCaps(void) const;
130 |
131 | #ifdef __UNIX__
132 | static std::vector typesToX11Atoms(uint16_t types, const XCB::Connector &);
133 | static uint16_t x11AtomToType(xcb_atom_t);
134 | static void x11AtomsUpdate(const XCB::Connector &);
135 | #endif
136 | };
137 | }
138 | }
139 |
140 | #endif // _LIBRFB_EXTCLIP_
141 |
--------------------------------------------------------------------------------
/src/librfb/librfb_ffmpeg.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2022 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LIBRFB_FFMPEG_
25 | #define _LIBRFB_FFMPEG_
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #ifdef __cplusplus
33 | extern "C" {
34 | #endif
35 |
36 | #include "libavdevice/avdevice.h"
37 | #include "libavcodec/avcodec.h"
38 | #include "libavformat/avformat.h"
39 | #include "libavformat/avio.h"
40 | #include "libavutil/timestamp.h"
41 | #include "libswscale/swscale.h"
42 | #include "libswresample/swresample.h"
43 | #include "libavutil/imgutils.h"
44 |
45 | #ifdef __cplusplus
46 | }
47 |
48 | #endif
49 |
50 | #include "librfb_encodings.h"
51 | #include "librfb_decodings.h"
52 |
53 | namespace LTSM
54 | {
55 | struct ffmpeg_error : public std::runtime_error
56 | {
57 | explicit ffmpeg_error(std::string_view what) : std::runtime_error(what.data()) {}
58 | };
59 |
60 | struct AVCodecContextDeleter
61 | {
62 | void operator()(AVCodecContext* ctx)
63 | {
64 | #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(61, 19, 100)
65 | avcodec_close(ctx); // deprecated
66 | #endif
67 | #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100)
68 | avcodec_free_context(& ctx);
69 | #else
70 | avcodec_free(ctx);
71 | #endif
72 | }
73 | };
74 |
75 | struct SwsContextDeleter
76 | {
77 | void operator()(SwsContext* ctx)
78 | {
79 | sws_freeContext(ctx);
80 | }
81 | };
82 |
83 | struct SwrContextDeleter
84 | {
85 | void operator()(SwrContext* ctx)
86 | {
87 | swr_free(& ctx);
88 | }
89 | };
90 |
91 | struct AVFrameDeleter
92 | {
93 | void operator()(AVFrame* ptr)
94 | {
95 | av_frame_free(& ptr);
96 | }
97 | };
98 |
99 | struct AVPacketDeleter
100 | {
101 | void operator()(AVPacket* ptr)
102 | {
103 | av_packet_free(& ptr);
104 | }
105 | };
106 |
107 | namespace RFB
108 | {
109 | #ifdef LTSM_ENCODING_FFMPEG
110 | /// EncodingFFmpeg
111 | class EncodingFFmpeg : public EncodingBase
112 | {
113 | std::unique_ptr avcctx;
114 | std::unique_ptr swsctx;
115 | std::unique_ptr frame;
116 | std::unique_ptr packet;
117 |
118 | #if LIBAVFORMAT_VERSION_MAJOR < 59
119 | AVCodec* codec = nullptr;
120 | #else
121 | const AVCodec* codec = nullptr;
122 | #endif
123 |
124 | std::mutex lockUpdate;
125 | std::chrono::steady_clock::time_point updatePoint;
126 |
127 | //int bitrate = 1024;
128 | int fps = 25;
129 | int pts = 0;
130 |
131 | protected:
132 | void initContext(const XCB::Size &);
133 |
134 | public:
135 | void resizedEvent(const XCB::Size &) override;
136 | void sendFrameBuffer(EncoderStream*, const FrameBuffer &) override;
137 |
138 | EncodingFFmpeg(int type);
139 | ~EncodingFFmpeg() = default;
140 |
141 | const char* getTypeName(void) const override;
142 | };
143 |
144 | #endif // ENCODING_FFMPEG
145 |
146 | #ifdef LTSM_DECODING_FFMPEG
147 | /// DecodingFFmpeg
148 | class DecodingFFmpeg : public DecodingBase
149 | {
150 | PixelFormat pf;
151 |
152 | std::unique_ptr avcctx;
153 | std::unique_ptr swsctx;
154 | std::unique_ptr frame;
155 | std::unique_ptr packet;
156 | std::unique_ptr rgb;
157 | std::unique_ptr rgbdata{nullptr, av_free};
158 |
159 | #if LIBAVFORMAT_VERSION_MAJOR < 59
160 | AVCodec* codec = nullptr;
161 | #else
162 | const AVCodec* codec = nullptr;
163 | #endif
164 |
165 | std::mutex lockUpdate;
166 |
167 | protected:
168 | void initContext(const XCB::Size &);
169 |
170 | public:
171 | void resizedEvent(const XCB::Size &) override;
172 | void updateRegion(DecoderStream &, const XCB::Region &) override;
173 |
174 | DecodingFFmpeg(int type);
175 | ~DecodingFFmpeg() = default;
176 | };
177 |
178 | #endif // DECODING_FFMPEG
179 | }
180 | }
181 |
182 | #endif // _LIBRFB_FFMPEG_
183 |
--------------------------------------------------------------------------------
/src/librfb/librfb_winclient.cpp:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #include
25 | #include
26 |
27 | #include "ltsm_application.h"
28 | #include "ltsm_tools.h"
29 |
30 | #include "ltsm_librfb.h"
31 | #include "librfb_winclient.h"
32 |
33 | using namespace std::chrono_literals;
34 |
35 | namespace LTSM
36 | {
37 | RFB::WinClient::WinClient()
38 | {
39 | }
40 |
41 | void RFB::WinClient::extClipboardSendEvent(const std::vector & buf)
42 | {
43 | Application::debug(DebugType::WinCli, "%s, length: %" PRIu32, __FUNCTION__, buf.size());
44 | sendCutTextEvent(buf.data(), buf.size(), true);
45 | }
46 |
47 | uint16_t RFB::WinClient::extClipboardLocalTypes(void) const
48 | {
49 | return clipLocalTypes;
50 | }
51 |
52 | std::vector RFB::WinClient::extClipboardLocalData(uint16_t type) const
53 | {
54 | if(0 == extClipboardLocalCaps())
55 | {
56 | Application::error("%s: unsupported encoding: %s", __FUNCTION__, encodingName(ENCODING_EXT_CLIPBOARD));
57 | throw rfb_error(NS_FuncName);
58 | }
59 |
60 | Application::debug(DebugType::WinCli, "%s", __FUNCTION__);
61 |
62 | /*
63 | auto ptr = const_cast(this);
64 | if(auto copy = static_cast(ptr->getExtension(XCB::Module::SELECTION_COPY)))
65 | {
66 | for(const auto & atom: ExtClip::typesToX11Atoms(type, *this))
67 | {
68 | ptr->clientClipboard.clear();
69 | copy->convertSelection(atom, *this);
70 |
71 | // wait data from selectionReceiveData
72 | Tools::Timeout waitCb(100ms);
73 |
74 | while(true)
75 | {
76 | std::this_thread::sleep_for(3ms);
77 |
78 | if(waitCb.check())
79 | break;
80 |
81 | const std::scoped_lock guard{ clientLock };
82 |
83 | if(clientClipboard.size())
84 | return clientClipboard;
85 | }
86 | }
87 | }
88 | */
89 | return {};
90 | }
91 |
92 | void RFB::WinClient::extClipboardRemoteTypesEvent(uint16_t types)
93 | {
94 | Application::debug(DebugType::WinCli, "%s, types: 0x%04" PRIx16, __FUNCTION__, types);
95 | if(extClipboardRemoteCaps())
96 | {
97 | clipRemoteTypes = types;
98 |
99 | //if(auto paste = static_cast(getExtension(XCB::Module::SELECTION_PASTE)))
100 | // paste->setSelectionOwner(*this);
101 | }
102 | else
103 | {
104 | Application::error("%s: unsupported encoding: %s", __FUNCTION__, encodingName(ENCODING_EXT_CLIPBOARD));
105 | throw rfb_error(NS_FuncName);
106 | }
107 | }
108 |
109 | void RFB::WinClient::extClipboardRemoteDataEvent(uint16_t type, std::vector && buf)
110 | {
111 | Application::debug(DebugType::WinCli, "%s, type: 0x%04" PRIx16 ", length: %" PRIu32, __FUNCTION__, type, buf.size());
112 | if(extClipboardRemoteCaps())
113 | {
114 | const std::scoped_lock guard{ clientLock };
115 | clientClipboard.swap(buf);
116 | }
117 | else
118 | {
119 | Application::error("%s: unsupported encoding: %s", __FUNCTION__, encodingName(ENCODING_EXT_CLIPBOARD));
120 | throw rfb_error(NS_FuncName);
121 | }
122 | }
123 |
124 | void RFB::WinClient::clientRecvCutTextEvent(std::vector && buf)
125 | {
126 | Application::debug(DebugType::WinCli, "%s: data length: %" PRIu32, __FUNCTION__, buf.size());
127 |
128 | const std::scoped_lock guard{ clientLock };
129 | clientClipboard.swap(buf);
130 |
131 | //if(auto paste = static_cast(getExtension(XCB::Module::SELECTION_PASTE)))
132 | // paste->setSelectionOwner(*this);
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/librfb/librfb_winclient.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LIBRFB_WINCLI_
25 | #define _LIBRFB_WINCLI_
26 |
27 | #include
28 | #include
29 |
30 | #include "librfb_client.h"
31 |
32 | namespace LTSM
33 | {
34 | namespace RFB
35 | {
36 | class WinClient : public ClientDecoder
37 | {
38 | std::vector clientClipboard;
39 |
40 | mutable std::mutex clientLock;
41 |
42 | mutable uint16_t clipLocalTypes = 0;
43 | uint16_t clipRemoteTypes = 0;
44 |
45 | protected:
46 |
47 | // ext clipboard
48 | uint16_t extClipboardLocalTypes(void) const override;
49 | std::vector extClipboardLocalData(uint16_t type) const override;
50 | void extClipboardRemoteTypesEvent(uint16_t type) override;
51 | void extClipboardRemoteDataEvent(uint16_t type, std::vector &&) override;
52 | void extClipboardSendEvent(const std::vector &) override;
53 |
54 | void clientRecvCutTextEvent(std::vector &&) override;
55 |
56 | public:
57 | WinClient();
58 | };
59 | }
60 | }
61 |
62 | #endif // _LIBRFB_WINCLI_
63 |
--------------------------------------------------------------------------------
/src/librfb/librfb_x11client.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LIBRFB_X11CLI_
25 | #define _LIBRFB_X11CLI_
26 |
27 | #include
28 | #include
29 |
30 | #include "librfb_client.h"
31 | #include "ltsm_xcb_wrapper.h"
32 |
33 | namespace LTSM
34 | {
35 | namespace RFB
36 | {
37 | class X11Client : public XCB::RootDisplay, public ClientDecoder, public XCB::SelectionSource, public XCB::SelectionRecipient
38 | {
39 | std::vector clientClipboard;
40 |
41 | mutable std::mutex clientLock;
42 |
43 | mutable uint16_t clipLocalTypes = 0;
44 | uint16_t clipRemoteTypes = 0;
45 |
46 | protected:
47 |
48 | // selection source
49 | std::vector selectionSourceTargets(void) const override;
50 | bool selectionSourceReady(xcb_atom_t) const override;
51 | size_t selectionSourceSize(xcb_atom_t) const override;
52 | std::vector selectionSourceData(xcb_atom_t, size_t offset, uint32_t length) const override;
53 |
54 | // selection recipient
55 | void selectionReceiveData(xcb_atom_t, const uint8_t* ptr, uint32_t len) const override;
56 | void selectionReceiveTargets(const xcb_atom_t* beg, const xcb_atom_t* end) const override;
57 | void selectionChangedEvent(void) const override;
58 |
59 | // ext clipboard
60 | uint16_t extClipboardLocalTypes(void) const override;
61 | std::vector extClipboardLocalData(uint16_t type) const override;
62 | void extClipboardRemoteTypesEvent(uint16_t type) override;
63 | void extClipboardRemoteDataEvent(uint16_t type, std::vector &&) override;
64 | void extClipboardSendEvent(const std::vector &) override;
65 |
66 | void clientRecvCutTextEvent(std::vector &&) override;
67 |
68 | // x11 event
69 | void xcbDisplayConnectedEvent(void) override;
70 |
71 | public:
72 | X11Client();
73 | };
74 | }
75 | }
76 |
77 | #endif // _LIBRFB_X11CLI_
78 |
--------------------------------------------------------------------------------
/src/qt_helper/ltsm_helper.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ltsm_logo.png
4 |
5 |
6 | ltsm_helper_ru.qm
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/qt_helper/ltsm_helper_ru.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/qt_helper/ltsm_helper_ru.qm
--------------------------------------------------------------------------------
/src/qt_helper/ltsm_helper_ru.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LTSM_HelperWindow
6 |
7 |
8 | LTSM_HelperWindow
9 |
10 |
11 |
12 |
13 |
14 | X11 Remote Desktop
15 |
16 |
17 |
18 |
19 | username:
20 | пользователь:
21 |
22 |
23 |
24 | password:
25 | пароль:
26 |
27 |
28 |
29 | encryption:
30 | шифрование:
31 |
32 |
33 |
34 | none
35 | отсутсвует
36 |
37 |
38 |
39 | login
40 | вход в систему
41 |
42 |
43 |
44 | default
45 |
46 |
47 |
48 |
49 | dbus init failed
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/qt_helper/ltsm_ldap_wrapper.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2022 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _LTSM_LDAP_WRAPPER_H_
24 | #define _LTSM_LDAP_WRAPPER_H_
25 |
26 | #include
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | namespace LTSM
33 | {
34 | struct ldap_error : public std::runtime_error
35 | {
36 | explicit ldap_error(std::string_view what) : std::runtime_error(what.data()) {}
37 | };
38 |
39 | class LdapWrapper
40 | {
41 | LDAP* ldap = nullptr;
42 |
43 | public:
44 | LdapWrapper();
45 | ~LdapWrapper();
46 |
47 | std::string findLoginFromDn(const std::string & dn);
48 | std::string findDnFromCertificate(const uint8_t*, size_t);
49 | };
50 | }
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/src/qt_helper/ltsm_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/qt_helper/ltsm_logo.png
--------------------------------------------------------------------------------
/src/qt_helper/main.cpp:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #include
24 | #include
25 |
26 | #include "ltsm_application.h"
27 | #include "ltsm_helperwindow.h"
28 |
29 | class LtsmHelper : public LTSM::Application, public QApplication
30 | {
31 |
32 | public:
33 | LtsmHelper(int & argc, char** argv) : LTSM::Application("ltsm_helper"), QApplication(argc, argv)
34 | {
35 | LTSM::Application::setDebug(LTSM::DebugTarget::Syslog, LTSM::DebugLevel::Info);
36 | }
37 |
38 | int start(void) override
39 | {
40 | QTranslator tr;
41 | tr.load(QLocale(), QLatin1String("ltsm_helper"), QLatin1String("_"), QLatin1String(":/i18n"));
42 | installTranslator(& tr);
43 | LTSM_HelperSDBus win;
44 | win.show();
45 | return exec();
46 | }
47 | };
48 |
49 | int main(int argc, char* argv[])
50 | {
51 | int res = 0;
52 |
53 | try
54 | {
55 | LtsmHelper app(argc, argv);
56 | res = app.start();
57 | }
58 | catch(const sdbus::Error & err)
59 | {
60 | LTSM::Application::error("sdbus exception: [%s] %s", err.getName().c_str(), err.getMessage().c_str());
61 | }
62 | catch(const std::exception & err)
63 | {
64 | LTSM::Application::error("%s: exception: %s", NS_FuncName.c_str(), err.what());
65 | }
66 |
67 | return res;
68 | }
69 |
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/qt_sessions/ltsm_offline.png
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/qt_sessions/ltsm_online.png
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_sessions.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef LTSM_SESSIONS_H
24 | #define LTSM_SESSIONS_H
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 | struct XvfbInfo
37 | {
38 | int display = -1;
39 | int pid1 = 0;
40 | int pid2 = 0;
41 | int width = 0;
42 | int height = 0;
43 | int uid = 0;
44 | int gid = 0;
45 | int durationLimit = 0;
46 | int mode = 0;
47 | int policy = 0;
48 | QString user;
49 | QString authfile;
50 | QString remoteaddr;
51 | QString conntype;
52 | QString encryption;
53 | };
54 |
55 | Q_DECLARE_METATYPE(XvfbInfo);
56 |
57 | struct RowItem : QTableWidgetItem
58 | {
59 | RowItem(const XvfbInfo &, const QString &);
60 | RowItem(const XvfbInfo &, const QIcon &, const QString &);
61 |
62 | XvfbInfo xvfbInfo(void) const;
63 | int display(void) const;
64 | };
65 |
66 | namespace Ui
67 | {
68 | class LTSM_Sessions;
69 | }
70 |
71 | class LTSM_Sessions : public QDialog
72 | {
73 | Q_OBJECT
74 |
75 | protected slots:
76 | void tableReload(void);
77 | void disconnectClicked(void);
78 | void logoffClicked(void);
79 | void showClicked(void);
80 | void showInformation(void);
81 | void sendmsgClicked(void);
82 | void itemSelectionChanged(void);
83 | void itemDoubleClicked(QTableWidgetItem*);
84 | void displayRemovedCallback(int);
85 | void sessionChangedCallback(int);
86 | void customContextMenu(QPoint);
87 | void changeSessionPolicy(void);
88 | void changeSessionDuration(void);
89 |
90 | public:
91 | explicit LTSM_Sessions(QWidget* parent = 0);
92 | ~LTSM_Sessions();
93 |
94 | private:
95 | Ui::LTSM_Sessions* ui;
96 | QScopedPointer dbusInterfacePtr;
97 | const RowItem* selectedRow;
98 | QFileInfo sdl2x11;
99 | QProcess process;
100 | };
101 |
102 | #endif // LTSM_SESSIONS_H
103 |
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_sessions.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ltsm_offline.png
4 | ltsm_online.png
5 |
6 |
7 | ltsm_sessions_ru.qm
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_sessions.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | LTSM_Sessions
4 |
5 |
6 |
7 | 0
8 | 0
9 | 515
10 | 339
11 |
12 |
13 |
14 | LTSM sessions
15 |
16 |
17 | -
18 |
19 |
20 | QAbstractItemView::NoEditTriggers
21 |
22 |
23 | QAbstractItemView::SelectRows
24 |
25 |
26 | 0
27 |
28 |
29 | true
30 |
31 |
32 |
33 | -
34 |
35 |
36 | Qt::Horizontal
37 |
38 |
39 |
40 | -
41 |
42 |
-
43 |
44 |
45 | Qt::Horizontal
46 |
47 |
48 |
49 | 40
50 | 20
51 |
52 |
53 |
54 |
55 | -
56 |
57 |
58 | false
59 |
60 |
61 | show display
62 |
63 |
64 | Show
65 |
66 |
67 |
68 | -
69 |
70 |
71 | false
72 |
73 |
74 | disconnect session
75 |
76 |
77 | Disconnect
78 |
79 |
80 |
81 | -
82 |
83 |
84 | false
85 |
86 |
87 | logout session
88 |
89 |
90 | Logout
91 |
92 |
93 |
94 | -
95 |
96 |
97 | false
98 |
99 |
100 | send message
101 |
102 |
103 | Send Message...
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | disconnectClicked()
118 | logoffClicked()
119 | sendmsgClicked()
120 | itemClicked(QTableWidgetItem*)
121 | showClicked()
122 | showMenu(QPoint)
123 |
124 |
125 |
--------------------------------------------------------------------------------
/src/qt_sessions/ltsm_sessions_ru.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/qt_sessions/ltsm_sessions_ru.qm
--------------------------------------------------------------------------------
/src/qt_sessions/main.cpp:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #include "ltsm_sessions.h"
24 | #include
25 | #include
26 |
27 | int main(int argc, char* argv[])
28 | {
29 | int res = 0;
30 |
31 | try
32 | {
33 | QApplication a(argc, argv);
34 | QTranslator t;
35 | t.load(QLocale(), QLatin1String("ltsm_sessions"), QLatin1String("_"), QLatin1String(":/i18n"));
36 | a.installTranslator(& t);
37 | LTSM_Sessions w;
38 | w.show();
39 | res = a.exec();
40 | }
41 | catch(int e)
42 | {
43 | res = e;
44 | }
45 |
46 | return res;
47 | }
48 |
--------------------------------------------------------------------------------
/src/sane_backend/unix.conf.in:
--------------------------------------------------------------------------------
1 | # This is the unix backend config file.
2 |
3 | ## env: SANE_UNIX_PATH
4 |
5 | ## saned socket path
6 | /var/run/ltsm/sane/path
7 |
--------------------------------------------------------------------------------
/src/sane_backend/unix.h:
--------------------------------------------------------------------------------
1 | /* sane - Scanner Access Now Easy.
2 | Copyright (C) 1997 David Mosberger-Tang
3 | Copyright (C) 2003 Julien BLACHE
4 | Copyright (C) 2022 Andrey Afletdinov
5 |
6 | This file is part of the LTSM sane_backend package.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License as
10 | published by the Free Software Foundation; either version 2 of the
11 | License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program. If not, see .
20 | */
21 | #ifndef unix_h
22 | #define unix_h
23 |
24 | #include
25 | #include
26 |
27 | #include "../include/sane/sanei_wire.h"
28 | #include "../include/sane/config.h"
29 |
30 | typedef struct Unix_Device
31 | {
32 | struct Unix_Device *next;
33 | const char *name;
34 | struct sockaddr addr;
35 | int ctl; /* socket descriptor (or -1) */
36 | Wire wire;
37 | int auth_active;
38 | }
39 |
40 | Unix_Device;
41 |
42 | typedef struct Unix_Scanner
43 | {
44 | /* all the state needed to define a scan request: */
45 | struct Unix_Scanner *next;
46 |
47 | int options_valid; /* are the options current? */
48 | SANE_Option_Descriptor_Array opt, local_opt;
49 |
50 | SANE_Word handle; /* remote handle (it's a word, not a ptr!) */
51 |
52 | int data; /* data socket descriptor */
53 | int reclen_buf_offset;
54 | u_char reclen_buf[4];
55 | size_t bytes_remaining; /* how many bytes left in this record? */
56 |
57 | /* device (host) info: */
58 | Unix_Device *hw;
59 | }
60 |
61 | Unix_Scanner;
62 |
63 | #endif /* unix_h */
64 |
--------------------------------------------------------------------------------
/src/sdl2x11/ltsm_sdl_wrapper.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2021 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef _SDL_WRAPPER_
24 | #define _SDL_WRAPPER_
25 |
26 | #include
27 | #include
28 |
29 | #include "SDL.h"
30 |
31 | namespace LTSM
32 | {
33 | #if SDL_BYTEORDER == SDL_BIG_ENDIAN
34 | inline static const int TEXTURE_FMT = SDL_PIXELFORMAT_ARGB32;
35 | #else
36 | inline static const int TEXTURE_FMT = SDL_PIXELFORMAT_BGRA32;
37 | #endif
38 |
39 | struct sdl_error : public std::runtime_error
40 | {
41 | explicit sdl_error(std::string_view what) : std::runtime_error(what.data()) {}
42 | };
43 |
44 | namespace SDL
45 | {
46 | struct Texture : std::shared_ptr
47 | {
48 | Texture(SDL_Texture* ptr = nullptr)
49 | : std::shared_ptr(ptr, SDL_DestroyTexture) {}
50 |
51 | bool isValid(void) const;
52 |
53 | int width(void) const;
54 | int height(void) const;
55 |
56 | void updateRect(const SDL_Rect*, const void* pixels, int pitch);
57 | };
58 |
59 | struct Surface : std::shared_ptr
60 | {
61 | Surface(SDL_Surface* ptr = nullptr)
62 | : std::shared_ptr(ptr, SDL_FreeSurface) {}
63 |
64 | bool isValid(void) const;
65 | int width(void) const;
66 | int height(void) const;
67 | };
68 |
69 | struct GenericEvent
70 | {
71 | const SDL_Event* ptr;
72 |
73 | GenericEvent(const SDL_Event* ev) : ptr(ev) {}
74 |
75 | bool isValid(void) const
76 | {
77 | return ptr;
78 | }
79 |
80 | int type(void) const
81 | {
82 | return ptr ? ptr->type : 0;
83 | }
84 |
85 | const SDL_KeyboardEvent* key(void) const
86 | {
87 | return ptr ? & ptr->key : nullptr;
88 | }
89 |
90 | const SDL_MouseMotionEvent* motion(void) const
91 | {
92 | return ptr ? & ptr->motion : nullptr;
93 | }
94 |
95 | const SDL_MouseButtonEvent* button(void) const
96 | {
97 | return ptr ? & ptr->button : nullptr;
98 | }
99 |
100 | const SDL_MouseWheelEvent* wheel(void) const
101 | {
102 | return ptr ? & ptr->wheel : nullptr;
103 | }
104 |
105 | const SDL_WindowEvent* window(void) const
106 | {
107 | return ptr ? & ptr->window : nullptr;
108 | }
109 |
110 | const SDL_DropEvent* drop(void) const
111 | {
112 | return ptr ? & ptr->drop : nullptr;
113 | }
114 |
115 | const SDL_UserEvent* user(void) const
116 | {
117 | return ptr ? & ptr->user : nullptr;
118 | }
119 | };
120 |
121 | class Window
122 | {
123 | std::unique_ptr _window{ nullptr, SDL_DestroyWindow };
124 | std::unique_ptr _renderer{ nullptr, SDL_DestroyRenderer };
125 | std::unique_ptr _display{ nullptr, SDL_DestroyTexture };
126 | SDL_Event _event;
127 | bool _accel = false;
128 |
129 | protected:
130 |
131 | public:
132 | Window(const std::string & title, int rendsz_w, int rendsz_h, int winsz_w = 0, int winsz_h = 0, int flags = 0,
133 | bool accel = true);
134 | ~Window();
135 |
136 | bool isValid(void) const;
137 | bool resize(int newsz_w, int newsz_h);
138 |
139 | uint32_t pixelFormat(void) const;
140 | std::pair geometry(void) const;
141 |
142 | SDL_Texture* display(void)
143 | {
144 | return _display.get();
145 | }
146 |
147 | SDL_Renderer* render(void)
148 | {
149 | return _renderer.get();
150 | }
151 |
152 | SDL_Window* get(void)
153 | {
154 | return _window.get();
155 | }
156 |
157 | void renderClear(const SDL_Color*, SDL_Texture* target = nullptr);
158 | void renderColor(const SDL_Color*, const SDL_Rect*, SDL_Texture* target = nullptr);
159 | void renderTexture(SDL_Texture* source, const SDL_Rect* srcrt = nullptr, SDL_Texture* target = nullptr,
160 | const SDL_Rect* dstrt = nullptr);
161 |
162 | void renderReset(SDL_Texture* target = nullptr);
163 | void renderPresent(void);
164 |
165 | Texture createTexture(int width, int height, uint32_t format = TEXTURE_FMT) const;
166 |
167 | GenericEvent pollEvent(void);
168 | static int convertScanCodeToKeySym(SDL_Scancode);
169 |
170 | std::pair scaleCoord(int posx, int posy) const;
171 | };
172 | }
173 | }
174 |
175 | #endif // LTSM_SDL_WRAPPER_
176 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_AUDIO_
25 | #define _LTSM_AUDIO_
26 |
27 | #define LTSM_AUDIO2SESSION_VERSION 20240304
28 |
29 | #include
30 | #include
31 |
32 | namespace LTSM
33 | {
34 | namespace AudioOp
35 | {
36 | enum
37 | {
38 | Init = 0xFE01,
39 | Data = 0xFE02,
40 | Silent = 0xFE03
41 | };
42 | }
43 |
44 | namespace AudioEncoding
45 | {
46 | enum
47 | {
48 | PCM = 0,
49 | OPUS = 1,
50 | AAC = 2
51 | };
52 | }
53 |
54 | struct AudioFormat
55 | {
56 | uint16_t type = 0;
57 | uint16_t channels = 0;
58 | uint32_t samplePerSec = 0;
59 | uint16_t bitsPerSample = 0;
60 | };
61 |
62 | class AudioPlayer
63 | {
64 | public:
65 | AudioPlayer() = default;
66 | virtual ~AudioPlayer() = default;
67 |
68 | virtual bool streamWrite(const uint8_t*, size_t) const = 0;
69 | };
70 |
71 | struct audio_error : public std::runtime_error
72 | {
73 | explicit audio_error(std::string_view what) : std::runtime_error(what.data()) {}
74 | };
75 | }
76 |
77 | #endif // _LTSM_AUDIO_
78 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_decoder.cpp:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #include "ltsm_tools.h"
25 | #include "ltsm_audio.h"
26 | #include "ltsm_application.h"
27 | #include "ltsm_audio_decoder.h"
28 |
29 | namespace LTSM
30 | {
31 | #ifdef LTSM_WITH_OPUS
32 | AudioDecoder::Opus::Opus(uint32_t samplesPerSec, uint16_t audioChannels, uint16_t bitsPerSample)
33 | : sampleLength(audioChannels * (bitsPerSample >> 3))
34 | {
35 | if(bitsPerSample != sizeof(opus_int16) * 8)
36 | {
37 | Application::error("%s: %s failed", __FUNCTION__, "bitsPerSample");
38 | throw audio_error(NS_FuncName);
39 | }
40 |
41 | int error = OPUS_OK;
42 | ctx.reset(opus_decoder_create(samplesPerSec, audioChannels, & error));
43 |
44 | if(! ctx || error != OPUS_OK)
45 | {
46 | Application::error("%s: %s failed, error: %d, sampleRate: %" PRIu32 ", audioChannels: %" PRIu16, __FUNCTION__,
47 | "opus_decoder_create", error, samplesPerSec, audioChannels);
48 | throw audio_error(NS_FuncName);
49 | }
50 | }
51 |
52 | bool AudioDecoder::Opus::decode(const uint8_t* ptr, size_t len)
53 | {
54 | int frames = opus_decoder_get_nb_samples(ctx.get(), ptr, len);
55 |
56 | if(0 > frames)
57 | {
58 | Application::error("%s: %s failed, error: %d, data size: %u", __FUNCTION__, "opus_decoder_get_nb_samples", frames, len);
59 | throw audio_error(NS_FuncName);
60 | }
61 |
62 | if(0 == frames)
63 | {
64 | return false;
65 | }
66 |
67 | tmp.resize(frames* sampleLength);
68 | int nSamples = opus_decode(ctx.get(), ptr, len, (opus_int16*) tmp.data(), frames, 0);
69 |
70 | if(nSamples < 0)
71 | {
72 | Application::error("%: %s failed, error: %d", __FUNCTION__, "opus_decode", nSamples);
73 | return false;
74 | }
75 |
76 | decodeSize = nSamples * sampleLength;
77 | return true;
78 | }
79 |
80 | const uint8_t* AudioDecoder::Opus::data(void) const
81 | {
82 | return tmp.data();
83 | }
84 |
85 | size_t AudioDecoder::Opus::size(void) const
86 | {
87 | if(decodeSize > tmp.size())
88 | {
89 | Application::error("%s: out of range, size: %u, buf: %u", __FUNCTION__, decodeSize, tmp.size());
90 | throw audio_error(NS_FuncName);
91 | }
92 |
93 | return decodeSize;
94 | }
95 |
96 | #endif
97 | }
98 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_decoder.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_AUDIO_DECODER_
25 | #define _LTSM_AUDIO_DECODER_
26 |
27 | #include
28 | #include
29 | #include
30 |
31 | #ifdef LTSM_WITH_OPUS
32 | #include "opus/opus.h"
33 | #endif
34 |
35 | namespace LTSM
36 | {
37 | namespace AudioDecoder
38 | {
39 | class BaseDecoder
40 | {
41 | public:
42 | BaseDecoder() = default;
43 | virtual ~BaseDecoder() = default;
44 |
45 | virtual bool decode(const uint8_t* ptr, size_t len) = 0;
46 |
47 | virtual const uint8_t* data(void) const = 0;
48 | virtual size_t size(void) const = 0;
49 | };
50 |
51 | #ifdef LTSM_WITH_OPUS
52 | struct OpusDeleter
53 | {
54 | void operator()(OpusDecoder* st)
55 | {
56 | opus_decoder_destroy(st);
57 | }
58 | };
59 |
60 | class Opus : public BaseDecoder
61 | {
62 | std::unique_ptr ctx;
63 |
64 | std::vector tmp;
65 | size_t decodeSize = 0;
66 |
67 | const size_t sampleLength;
68 |
69 | public:
70 | Opus(uint32_t samplesPerSec, uint16_t audioChannels, uint16_t bitsPerSample);
71 |
72 | bool decode(const uint8_t* ptr, size_t len) override;
73 | const uint8_t* data(void) const override;
74 | size_t size(void) const override;
75 | };
76 |
77 | #endif
78 | }
79 | }
80 |
81 | #endif // _LTSM_AUDIO_DECODER_
82 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_encoder.cpp:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #include "ltsm_tools.h"
25 | #include "ltsm_audio.h"
26 | #include "ltsm_application.h"
27 | #include "ltsm_audio_encoder.h"
28 |
29 | namespace LTSM
30 | {
31 | #ifdef LTSM_WITH_OPUS
32 | AudioEncoder::Opus::Opus(uint32_t samplesPerSec, uint16_t audioChannels, uint16_t bitsPerSample, uint16_t frames)
33 | : framesCount(frames), sampleLength(audioChannels * (bitsPerSample >> 3))
34 | {
35 | const size_t reserveSize = 256 * 1024;
36 | last.reserve(reserveSize);
37 | int error = OPUS_OK;
38 | ctx.reset(opus_encoder_create(samplesPerSec, audioChannels,
39 | OPUS_APPLICATION_AUDIO /* OPUS_APPLICATION_RESTRICTED_LOWDELAY OPUS_APPLICATION_VOIP OPUS_APPLICATION_AUDIO */,
40 | & error));
41 |
42 | if(! ctx || error != OPUS_OK)
43 | {
44 | Application::error("%s: %s failed, error: %d, sampleRate: %" PRIu32 ", audioChannels: %" PRIu16, __FUNCTION__,
45 | "opus_encoder_create", error, samplesPerSec, audioChannels);
46 | throw audio_error(NS_FuncName);
47 | }
48 |
49 | /*
50 | error = opus_encoder_ctl(ctx.get(), OPUS_SET_BITRATE(bitRate));
51 | if(error != OPUS_OK)
52 | {
53 | Application::error("%s: %s failed, error: %d", __FUNCTION__, "opus_encoder_ctl", error);
54 | throw audio_error(NS_FuncName);
55 | }
56 | */
57 | }
58 |
59 | bool AudioEncoder::Opus::encode(const uint8_t* ptr, size_t len)
60 | {
61 | if(len)
62 | {
63 | last.insert(last.end(), ptr, ptr + len);
64 | }
65 |
66 | const size_t samplesCount = last.size() / sampleLength;
67 |
68 | if(framesCount > samplesCount)
69 | {
70 | return false;
71 | }
72 |
73 | auto src = (const opus_int16*) last.data();
74 | int nBytes = opus_encode(ctx.get(), src, framesCount, tmp.data(), tmp.size());
75 |
76 | if(nBytes < 0)
77 | {
78 | Application::error("%s: %s failed, error: %d", __FUNCTION__, "opus_encode", nBytes);
79 | return false;
80 | }
81 |
82 | last.erase(last.begin(), Tools::nextToEnd(last.begin(), framesCount * sampleLength, last.end()));
83 | encodeSize = nBytes;
84 | return 0 < encodeSize;
85 | }
86 |
87 | const uint8_t* AudioEncoder::Opus::data(void) const
88 | {
89 | return tmp.data();
90 | }
91 |
92 | size_t AudioEncoder::Opus::size(void) const
93 | {
94 | if(encodeSize > tmp.size())
95 | {
96 | Application::error("%s: out of range, size: %u, buf: %u", __FUNCTION__, encodeSize, tmp.size());
97 | throw audio_error(NS_FuncName);
98 | }
99 |
100 | return encodeSize;
101 | }
102 |
103 | #endif
104 | }
105 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_encoder.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_AUDIO_ENCODER_
25 | #define _LTSM_AUDIO_ENCODER_
26 |
27 | #include
28 | #include
29 | #include
30 |
31 | #ifdef LTSM_WITH_OPUS
32 | #include "opus/opus.h"
33 | #endif
34 |
35 | namespace LTSM
36 | {
37 | namespace AudioEncoder
38 | {
39 | class BaseEncoder
40 | {
41 | public:
42 | BaseEncoder() = default;
43 | virtual ~BaseEncoder() = default;
44 |
45 | virtual bool encode(const uint8_t* ptr, size_t len) = 0;
46 |
47 | virtual const uint8_t* data(void) const = 0;
48 | virtual size_t size(void) const = 0;
49 | };
50 |
51 | #ifdef LTSM_WITH_OPUS
52 | struct OpusDeleter
53 | {
54 | void operator()(OpusEncoder* st)
55 | {
56 | opus_encoder_destroy(st);
57 | }
58 | };
59 |
60 | class Opus : public BaseEncoder
61 | {
62 | std::unique_ptr ctx;
63 |
64 | // ref: https://www.opus-codec.org/docs/html_api/group__opusencoder.html
65 | // max_packet is the maximum number of bytes that can be written in the packet (1276 bytes is recommended)
66 | std::array tmp;
67 | size_t encodeSize = 0;
68 |
69 | // Opus: frame size - at 48kHz the permitted values are 120, 240, 480, or 960, the remainder will be stored here.
70 | std::vector last;
71 |
72 | const size_t framesCount;
73 | const size_t sampleLength;
74 |
75 | public:
76 | Opus(uint32_t samplesPerSec, uint16_t audioChannels, uint16_t bitsPerSample, uint16_t frames = 480);
77 |
78 | bool encode(const uint8_t* ptr, size_t len) override;
79 |
80 | const uint8_t* data(void) const override;
81 | size_t size(void) const override;
82 | };
83 |
84 | #endif
85 | }
86 | }
87 |
88 | #endif // _LTSM_AUDIO_ENCODER_
89 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_openal.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2025 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_AUDIO_OPENAL_
25 | #define _LTSM_AUDIO_OPENAL_
26 |
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | namespace LTSM
33 | {
34 | namespace OpenAL
35 | {
36 | const char* alcErrorName(ALCenum);
37 |
38 | class Playback : public AudioPlayer
39 | {
40 | std::unique_ptr dev{ nullptr, alcCloseDevice };
41 | std::unique_ptr ctx{ nullptr, alcDestroyContext };
42 |
43 | ALuint sourceId = 0;
44 | mutable ALuint playAfterBytes = 0;
45 |
46 | ALenum fmtFormat = 0;
47 | ALsizei fmtFrequency = 0;
48 |
49 | protected:
50 | ALint getBuffersProcessed(void) const;
51 | ALint getBuffersQueued(void) const;
52 | ALuint findFreeBufferId(void) const;
53 |
54 | public:
55 | Playback(const AudioFormat &, ALuint autoPlayAfterSec = 0);
56 | ~Playback();
57 |
58 | bool streamWrite(const uint8_t*, size_t) const override;
59 |
60 | bool playStart(void) const;
61 | bool playStop(void) const;
62 | bool playPause(void) const;
63 | bool stateIsPlaying(void) const;
64 | };
65 | }
66 | }
67 |
68 | #endif // _LTSM_AUDIO_OPENAL_
69 |
--------------------------------------------------------------------------------
/src/session_audio/ltsm_audio_session.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_AUDIO_SESSION_
25 | #define _LTSM_AUDIO_SESSION_
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #include "ltsm_streambuf.h"
34 | #include "ltsm_application.h"
35 | #include "ltsm_audio_pulse.h"
36 | #include "ltsm_audio_encoder.h"
37 | #include "ltsm_audio_adaptor.h"
38 |
39 | namespace LTSM
40 | {
41 | struct AudioClient
42 | {
43 | std::string socketPath;
44 |
45 | std::unique_ptr pulse;
46 | std::unique_ptr encoder;
47 | std::unique_ptr sock;
48 |
49 | std::thread thread;
50 | std::atomic shutdown{false};
51 |
52 | AudioClient(const std::string &);
53 | ~AudioClient();
54 | };
55 |
56 | class AudioSessionBus : public sdbus::AdaptorInterfaces, public Application
57 | {
58 | std::forward_list clients;
59 |
60 | public:
61 | AudioSessionBus(sdbus::IConnection &);
62 | virtual ~AudioSessionBus();
63 |
64 | int start(void) override;
65 |
66 | int32_t getVersion(void) override;
67 | void serviceShutdown(void) override;
68 | void setDebug(const std::string & level) override;
69 |
70 | bool connectChannel(const std::string & clientSocket) override;
71 | void disconnectChannel(const std::string & clientSocket) override;
72 |
73 | void pulseFragmentSize(const uint32_t & fragsz) override;
74 | };
75 | }
76 |
77 | #endif // _LTSM_AUDIO_SESSION_
78 |
--------------------------------------------------------------------------------
/src/session_fuse/ltsm_fuse.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_FUSE_
25 | #define _LTSM_FUSE_
26 |
27 | #define LTSM_FUSE2SESSION_VERSION 20240304
28 |
29 | #include
30 |
31 | namespace LTSM
32 | {
33 | namespace FuseOp
34 | {
35 | enum
36 | {
37 | Init = 0xFF01,
38 | Quit = 0xFF02,
39 | GetAttr = 0xFF03,
40 | ReadDir = 0xFF04,
41 | Open = 0xFF05,
42 | Read = 0xFF06,
43 | Release = 0xFF07,
44 | //
45 | Access = 0xFF08,
46 | RmDir = 0xFF09,
47 | UnLink = 0xFF10,
48 | Rename = 0xFF11,
49 | Truncate = 0xFF12,
50 | Write = 0xFF13,
51 | Create = 0xFF14,
52 | //
53 | Lookup = 0xFF15
54 | };
55 | }
56 |
57 | struct fuse_error : public std::runtime_error
58 | {
59 | explicit fuse_error(std::string_view what) : std::runtime_error(what.data()) {}
60 | };
61 | }
62 |
63 | #endif // _LTSM_FUSE_
64 |
--------------------------------------------------------------------------------
/src/session_fuse/ltsm_fuse_session.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_FUSE_SESSION_
25 | #define _LTSM_FUSE_SESSION_
26 |
27 | #include
28 | #include
29 |
30 | #include "ltsm_fuse.h"
31 | #include "ltsm_fuse_adaptor.h"
32 |
33 | namespace LTSM
34 | {
35 | struct FuseSession;
36 |
37 | class FuseSessionBus : public sdbus::AdaptorInterfaces, public Application
38 | {
39 | std::forward_list> childs;
40 |
41 | public:
42 | FuseSessionBus(sdbus::IConnection &);
43 | virtual ~FuseSessionBus();
44 |
45 | int start(void) override;
46 |
47 | int32_t getVersion(void) override;
48 | void serviceShutdown(void) override;
49 | void setDebug(const std::string & level) override;
50 |
51 | bool mountPoint(const std::string & localPoint, const std::string & remotePoint,
52 | const std::string & fuseSocket) override;
53 | void umountPoint(const std::string & point) override;
54 | };
55 | }
56 |
57 | #endif // _LTSM_FUSE_
58 |
--------------------------------------------------------------------------------
/src/session_pcsc/ltsm_pcsc.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_PCSC_
25 | #define _LTSM_PCSC_
26 |
27 | #define LTSM_PCSC2SESSION_VERSION 20240723
28 |
29 | #include
30 | #include
31 |
32 | namespace PcscLite
33 | {
34 | enum
35 | {
36 | EstablishContext = 0x01,
37 | ReleaseContext = 0x02,
38 | ListReaders = 0x03,
39 | Connect = 0x04,
40 | Reconnect = 0x05,
41 | Disconnect = 0x06,
42 | BeginTransaction = 0x07,
43 | EndTransaction = 0x08,
44 | Transmit = 0x09,
45 | Control = 0x0A,
46 | Status = 0x0B,
47 | GetStatusChange = 0x0C,
48 | Cancel = 0x0D,
49 | CancelTransaction = 0x0E,
50 | GetAttrib = 0x0F,
51 | SetAttrib = 0x10,
52 | GetVersion = 0x11,
53 | GetReaderState = 0x12,
54 | WaitReaderStateChangeStart = 0x13,
55 | WaitReaderStateChangeStop = 0x14
56 | };
57 | }
58 |
59 | namespace LTSM
60 | {
61 | namespace PcscOp
62 | {
63 | enum
64 | {
65 | Init = 0xFD01
66 | };
67 | }
68 |
69 | struct pcsc_error : public std::runtime_error
70 | {
71 | explicit pcsc_error(std::string_view what) : std::runtime_error(what.data()) {}
72 | };
73 | }
74 |
75 | #endif // _LTSM_PCSC_
76 |
--------------------------------------------------------------------------------
/src/session_pcsc/ltsm_pcsc_session.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_PCSC_SESSION_
25 | #define _LTSM_PCSC_SESSION_
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include "pcsclite.h"
35 |
36 | #include "ltsm_pcsc.h"
37 | #include "ltsm_streambuf.h"
38 | #include "ltsm_application.h"
39 | #include "ltsm_pcsc_adaptor.h"
40 |
41 | namespace PcscLite
42 | {
43 | // origin READER_STATE: PCSC/src/eventhandler.h
44 | struct ReaderState
45 | {
46 | char name[MAX_READERNAME];///< reader name
47 | uint32_t event = 0; ///< number of card events
48 | uint32_t state = 0; ///< SCARD_* bit field
49 | int32_t share = 0; ///< PCSCLITE_SHARING_* sharing status
50 |
51 | uint8_t atr[MAX_ATR_SIZE];///< ATR
52 | uint32_t atrLen = 0; ///< ATR length
53 | uint32_t protocol = 0; ///< SCARD_PROTOCOL_* value
54 |
55 | void reset(void);
56 | };
57 | }
58 |
59 | namespace LTSM
60 | {
61 | class PcscSessionBus;
62 |
63 | struct WaitStatus
64 | {
65 | std::future job;
66 | std::atomic stopped{true};
67 | std::atomic canceled{true};
68 |
69 | void reset(void)
70 | {
71 | stopped = true;
72 | canceled = true;
73 | }
74 |
75 | void start(void)
76 | {
77 | stopped = false;
78 | canceled = false;
79 | }
80 |
81 | void stop(void)
82 | {
83 | stopped = true;
84 |
85 | if(job.valid())
86 | {
87 | job.get();
88 | }
89 | }
90 |
91 | void cancel(void)
92 | {
93 | canceled = true;
94 |
95 | if(job.valid())
96 | {
97 | job.get();
98 | }
99 | }
100 | };
101 |
102 | struct PcscClient
103 | {
104 | SocketStream sock;
105 | PcscLite::ReaderState* reader = nullptr;
106 |
107 | std::thread thread;
108 | std::atomic shutdown{false};
109 |
110 | WaitStatus waitStatusChanged;
111 |
112 | uint64_t remoteContext = 0;
113 | uint64_t remoteHandle = 0;
114 |
115 | uint32_t versionMajor = 0;
116 | uint32_t versionMinor = 0;
117 |
118 | uint32_t context = 0;
119 | uint32_t handle = 0;
120 |
121 | PcscClient(int fd, PcscSessionBus* sessionBus);
122 | ~PcscClient();
123 |
124 | int id(void) const
125 | {
126 | return sock.fd();
127 | }
128 | };
129 |
130 | class PcscSessionBus : public sdbus::AdaptorInterfaces, public Application
131 | {
132 | std::forward_list clients;
133 | std::mutex clientsLock;
134 |
135 | std::array readers;
136 | std::mutex readersLock;
137 |
138 | std::unique_ptr ltsm;
139 | std::recursive_mutex ltsmLock;
140 |
141 | std::filesystem::path socketPath;
142 | int socketFd = -1;
143 |
144 | protected:
145 | bool pcscEstablishContext(PcscClient &, uint32_t len);
146 | bool pcscReleaseContext(PcscClient &, uint32_t len);
147 | bool pcscConnect(PcscClient &, uint32_t len);
148 | bool pcscReconnect(PcscClient &, uint32_t len);
149 | bool pcscDisconnect(PcscClient &, uint32_t len);
150 | bool pcscBeginTransaction(PcscClient &, uint32_t len);
151 | bool pcscEndTransaction(PcscClient &, uint32_t len);
152 | bool pcscTransmit(PcscClient &, uint32_t len);
153 | bool pcscStatus(PcscClient &, uint32_t len);
154 | bool pcscControl(PcscClient &, uint32_t len);
155 | bool pcscCancel(PcscClient &, uint32_t len);
156 | bool pcscGetAttrib(PcscClient &, uint32_t len);
157 | bool pcscSetAttrib(PcscClient &, uint32_t len);
158 | bool pcscGetVersion(PcscClient &, uint32_t len);
159 | bool pcscGetReaderState(PcscClient &, uint32_t len);
160 | bool pcscReaderStateChangeStart(PcscClient &, uint32_t len);
161 | bool pcscReaderStateChangeStop(PcscClient &, uint32_t len);
162 |
163 | int syncReaderStatusChange(PcscClient &, const std::string &, PcscLite::ReaderState &, bool* changed = nullptr);
164 | int64_t pcscGetStatusChange(PcscClient &, uint32_t timeout, SCARD_READERSTATE* states, uint32_t statesCount);
165 |
166 | std::list pcscListReaders(PcscClient &);
167 | PcscLite::ReaderState* findReaderState(const std::string & name);
168 |
169 | public:
170 | PcscSessionBus(sdbus::IConnection &, std::string_view pcscSockName);
171 | virtual ~PcscSessionBus();
172 |
173 | int start(void) override;
174 |
175 | int32_t getVersion(void) override;
176 | void serviceShutdown(void) override;
177 | void setDebug(const std::string & level) override;
178 |
179 | bool connectChannel(const std::string & clientSocket) override;
180 | void disconnectChannel(const std::string & clientSocket) override;
181 |
182 | bool pcscClientAction(PcscClient &);
183 |
184 | int64_t syncReaders(PcscClient &, bool* changed = nullptr);
185 | };
186 | }
187 |
188 | #endif // _LTSM_PCSC_SESSION_
189 |
--------------------------------------------------------------------------------
/src/session_pkcs11/ltsm_pkcs11.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LTSM_PKSC11_
25 | #define _LTSM_PKSC11_
26 |
27 | #define LTSM_PKCS11_VERSION 20240723
28 |
29 | namespace LTSM
30 | {
31 | namespace Pkcs11Op
32 | {
33 | enum
34 | {
35 | Init = 0xFC01,
36 | GetSlots = 0xFC02,
37 | GetSlotMechanisms = 0xFC03,
38 | GetSlotCertificates = 0xFC04,
39 | SignData = 0xFC11,
40 | DecryptData = 0xFC12
41 | };
42 | }
43 | }
44 |
45 | #endif // _LTSM_PKCS11_
46 |
--------------------------------------------------------------------------------
/src/session_pkcs11/ltsm_pkcs11_session.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright © 2024 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 3 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | * This program is distributed in the hope that it will be useful, *
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 | * GNU General Public License for more details. *
16 | * *
17 | * You should have received a copy of the GNU General Public License *
18 | * along with this program; if not, write to the *
19 | * Free Software Foundation, Inc., *
20 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 | ***************************************************************************/
22 |
23 | #ifndef LTSM_HELPER_PKCS11_H
24 | #define LTSM_HELPER_PKCS11_H
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include
33 |
34 | #include "ltsm_sockets.h"
35 | #include "ltsm_pkcs11_wrapper.h"
36 |
37 | struct Pkcs11Token
38 | {
39 | uint64_t slotId;
40 |
41 | LTSM::PKCS11::SlotInfo slotInfo;
42 | LTSM::PKCS11::TokenInfo tokenInfo;
43 |
44 | bool operator== (const Pkcs11Token & st) const
45 | {
46 | return tokenInfo.getModel() == st.tokenInfo.getModel() &&
47 | tokenInfo.getSerialNumber() == st.tokenInfo.getSerialNumber();
48 | }
49 |
50 | bool operator< (const Pkcs11Token & st) const
51 | {
52 | auto model1 = tokenInfo.getModel();
53 | auto model2 = st.tokenInfo.getModel();
54 |
55 | if(model1 == model2)
56 | {
57 | return tokenInfo.getSerialNumber() < st.tokenInfo.getSerialNumber();
58 | }
59 |
60 | return model1 < model2;
61 | }
62 | };
63 |
64 | struct Pkcs11Mech
65 | {
66 | uint64_t mechId;
67 | uint64_t minKey;
68 | uint64_t maxKey;
69 | uint64_t flags;
70 | std::string name;
71 | };
72 |
73 | struct Pkcs11Cert
74 | {
75 | std::vector objectId;
76 | std::vector objectValue;
77 | };
78 |
79 | class Pkcs11Client : public QThread
80 | {
81 | Q_OBJECT
82 |
83 | LTSM::SocketStream sock;
84 | QString templatePath;
85 |
86 | mutable std::mutex lock;
87 | std::atomic shutdown{false};
88 |
89 | std::list tokens;
90 |
91 | public:
92 | Pkcs11Client(int displayNum, QObject*);
93 | ~Pkcs11Client();
94 |
95 | const std::list & getTokens(void) const;
96 | std::list getCertificates(uint64_t slotId);
97 | std::list getMechanisms(uint64_t slotId);
98 |
99 | std::vector signData(uint64_t slotId, const std::string & pin, const std::vector & certId,
100 | const void* data, size_t len, uint64_t mechType = CKM_RSA_PKCS);
101 | std::vector decryptData(uint64_t slotId, const std::string & pin, const std::vector & certId,
102 | const void* data, size_t len, uint64_t mechType = CKM_RSA_PKCS);
103 |
104 | protected:
105 | void run(void) override;
106 |
107 | bool updateTokens(void);
108 |
109 | signals:
110 | void pkcs11Error(const QString &);
111 | void pkcs11Shutdown(void);
112 | void pkcs11TokensChanged(void);
113 | };
114 |
115 | #endif // LTSM_HELPER_PKCS11_H
116 |
--------------------------------------------------------------------------------
/src/tests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | foreach(DIR IN ITEMS json streambuf unixsocket framebuf xrandr x11clip)
2 | add_executable(LTSM_test_${DIR})
3 |
4 | file(GLOB_RECURSE SOURCELIST "${DIR}/*.cpp")
5 | target_sources(LTSM_test_${DIR} PRIVATE ${SOURCELIST})
6 |
7 | find_package(GnuTLS REQUIRED)
8 |
9 | target_link_libraries(LTSM_test_${DIR} ${SDL2_LIBRARIES})
10 | target_link_libraries(LTSM_test_${DIR} ${SDL2_IMAGE_LIBRARIES})
11 | target_compile_options(LTSM_test_${DIR} PRIVATE ${EXTRA_CFLAGS})
12 | target_compile_definitions(LTSM_test_${DIR} PRIVATE -DLTSM_WITH_GNUTLS -DLTSM_SOCKET_ZLIB)
13 |
14 | target_include_directories(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/common)
15 |
16 | target_link_libraries(LTSM_test_${DIR} LTSM_common)
17 | target_link_libraries(LTSM_test_${DIR} ${GNUTLS_LIBRARIES})
18 | target_link_libraries(LTSM_test_${DIR} z)
19 |
20 | set_target_properties(LTSM_test_${DIR} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..)
21 | endforeach()
22 |
23 | foreach(DIR IN ITEMS encodings x11enc)
24 | add_executable(LTSM_test_${DIR})
25 |
26 | file(GLOB_RECURSE SOURCELIST "${DIR}/*.cpp")
27 | target_sources(LTSM_test_${DIR} PRIVATE ${SOURCELIST}
28 | ${CMAKE_SOURCE_DIR}/src/librfb/ltsm_librfb.cpp
29 | ${CMAKE_SOURCE_DIR}/src/librfb/librfb_encodings.cpp
30 | ${CMAKE_SOURCE_DIR}/src/librfb/librfb_ffmpeg.cpp
31 | ${CMAKE_SOURCE_DIR}/src/channels/channel_system.cpp)
32 |
33 | find_package(GnuTLS REQUIRED)
34 |
35 | pkg_search_module(SDL2 REQUIRED sdl2>=2.0.1)
36 | pkg_search_module(SDL2_IMAGE REQUIRED SDL2_image>=2.0.1)
37 | pkg_search_module(LZ4 REQUIRED lz4)
38 | pkg_search_module(TURBOJPEG REQUIRED turbojpeg)
39 |
40 | target_link_libraries(LTSM_test_${DIR} ${SDL2_LIBRARIES})
41 | target_link_libraries(LTSM_test_${DIR} ${SDL2_IMAGE_LIBRARIES} ${LZ4_LIBRARIES} ${TURBOJPEG_LIBRARIES})
42 | target_compile_options(LTSM_test_${DIR} PRIVATE ${EXTRA_CFLAGS})
43 | target_compile_definitions(LTSM_test_${DIR} PRIVATE -DLTSM_WITH_GNUTLS -DLTSM_SOCKET_ZLIB -DLTSM_ENCODING -DLTSM_ENCODING_FFMPEG)
44 |
45 | target_include_directories(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/librfb)
46 | target_include_directories(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/common)
47 | target_include_directories(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/channels)
48 |
49 | if(LTSM_FFMPEG)
50 | pkg_search_module(AVDEVICE REQUIRED libavdevice)
51 | pkg_search_module(AVFORMAT REQUIRED libavformat)
52 | pkg_search_module(AVCODEC REQUIRED libavcodec)
53 | pkg_search_module(AVSWSCALE REQUIRED libswscale)
54 | pkg_search_module(AVSWRESAMPLE REQUIRED libswresample)
55 | pkg_search_module(AVUTIL REQUIRED libavutil)
56 |
57 | target_sources(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/librfb/ffmpeg_tools.cpp ${CMAKE_SOURCE_DIR}/src/librfb/librfb_ffmpeg.cpp)
58 |
59 | target_compile_options(LTSM_test_${DIR} PRIVATE
60 | ${AVDEVICE_CFLAGS} ${AVFORMAT_CFLAGS} ${AVCODEC_CFLAGS}
61 | ${AVSWSCALE_CFLAGS} ${AVSWRESAMPLE_CFLAGS} ${AVUTIL_CFLAGS})
62 |
63 | target_link_options(LTSM_test_${DIR} PRIVATE
64 | ${AVDEVICE_LDFLAGS} ${AVFORMAT_LDFLAGS} ${AVCODEC_LDFLAGS}
65 | ${AVSWSCALE_LDFLAGS} ${AVSWRESAMPLE_LDFLAGS} ${AVUTIL_LDFLAGS})
66 |
67 | target_link_libraries(LTSM_test_${DIR}
68 | ${AVDEVICE_LIBRARIES} ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES}
69 | ${AVSWSCALE_LIBRARIES} ${AVSWRESAMPLE_LIBRARIES} ${AVUTIL_LIBRARIES})
70 | endif()
71 |
72 | if(LTSM_PKCS11_AUTH)
73 | pkg_search_module(P11KIT REQUIRED p11-kit-1)
74 | target_include_directories(LTSM_test_${DIR} PRIVATE ${CMAKE_SOURCE_DIR}/src/session_pkcs11 ${P11KIT_INCLUDE_DIRS})
75 | endif()
76 |
77 | target_link_libraries(LTSM_test_${DIR} LTSM_common)
78 | target_link_libraries(LTSM_test_${DIR} ${SDL2_LIBRARIES})
79 | target_link_libraries(LTSM_test_${DIR} ${SDL2_IMAGE_LIBRARIES})
80 | target_link_libraries(LTSM_test_${DIR} ${GNUTLS_LIBRARIES})
81 | target_link_libraries(LTSM_test_${DIR} z)
82 |
83 | set_target_properties(LTSM_test_${DIR} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..)
84 | endforeach()
85 |
--------------------------------------------------------------------------------
/src/tests/encodings/images/001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/tests/encodings/images/001.png
--------------------------------------------------------------------------------
/src/tests/encodings/images/002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/tests/encodings/images/002.png
--------------------------------------------------------------------------------
/src/tests/encodings/images/003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/tests/encodings/images/003.png
--------------------------------------------------------------------------------
/src/tests/encodings/images/004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndreyBarmaley/linux-terminal-service-manager/ce163fff8ded0cdcb6fdbc234a61082a53f33e64/src/tests/encodings/images/004.png
--------------------------------------------------------------------------------
/src/tests/encodings/librfb_server2.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Copyright © 2022 by Andrey Afletdinov *
3 | * *
4 | * Part of the LTSM: Linux Terminal Service Manager: *
5 | * https://github.com/AndreyBarmaley/linux-terminal-service-manager *
6 | * *
7 | * This program is free software; *
8 | * you can redistribute it and/or modify it under the terms of the *
9 | * GNU Affero General Public License as published by the *
10 | * Free Software Foundation; either version 3 of the License, or *
11 | * (at your option) any later version. *
12 | * *
13 | * This program is distributed in the hope that it will be useful, *
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
16 | * See the GNU Affero General Public License for more details. *
17 | * *
18 | * You should have received a copy of the *
19 | * GNU Affero General Public License along with this program; *
20 | * if not, write to the Free Software Foundation, Inc., *
21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 | **********************************************************************/
23 |
24 | #ifndef _LIBRFB_SERVER_
25 | #define _LIBRFB_SERVER_
26 |
27 | #include
28 | #include
29 | #include
30 |
31 | #include "ltsm_librfb.h"
32 | #include "librfb_encodings.h"
33 |
34 | namespace LTSM
35 | {
36 | namespace RFB
37 | {
38 | /// ServerEncoder
39 | class ServerEncoderBuf : public EncoderStream
40 | {
41 | std::vector clientEncodings;
42 |
43 | BinaryBuf bufData;
44 | std::unique_ptr socket;
45 | std::unique_ptr encoder;
46 |
47 | XCB::Size dsz;
48 | PixelFormat clientPf, serverPf;
49 | std::mutex sendLock;
50 |
51 | mutable size_t netStatRx = 0;
52 | mutable size_t netStatTx = 0;
53 |
54 | NetworkStream* streamIn = nullptr;
55 | NetworkStream* streamOut = nullptr;
56 |
57 | bool clientTrueColor = true;
58 | bool clientBigEndian = false;
59 |
60 | protected:
61 | friend class EncodingBase;
62 | friend class EncodingRaw;
63 | friend class EncodingRRE;
64 | friend class EncodingHexTile;
65 | friend class EncodingTRLE;
66 | friend class EncodingZlib;
67 |
68 | // network stream interface
69 | void sendFlush(void) override;
70 | void sendRaw(const void* ptr, size_t len) override;
71 | void recvRaw(void* ptr, size_t len) const override;
72 | bool hasInput(void) const override;
73 | size_t hasData(void) const override;
74 | uint8_t peekInt8(void) const override;
75 |
76 | XCB::Size displaySize(void) const override;
77 |
78 | //bool isUpdateProcessed(void) const;
79 | //void waitUpdateProcess(void);
80 |
81 | void recvPixelFormat(void);
82 | void recvSetEncodings(void);
83 | void recvKeyCode(void);
84 | void recvPointer(void);
85 | void recvCutText(void);
86 | void recvFramebufferUpdate(void);
87 | void recvSetContinuousUpdates(void);
88 | void recvSetDesktopSize(void);
89 |
90 | public:
91 | ServerEncoderBuf(const FrameBuffer*);
92 |
93 | const PixelFormat & clientFormat(void) const override { return clientPf; }
94 | const PixelFormat & serverFormat(void) const override { return serverPf; }
95 | bool clientIsBigEndian(void) const override { return clientBigEndian; }
96 |
97 | void sendFrameBufferUpdate(const FrameBuffer &);
98 |
99 | void setEncodingDebug(int v);
100 | void setEncodingThreads(int v);
101 | bool serverSetClientEncoding(int type);
102 |
103 | const std::vector & getBuffer(void) const;
104 | void resetBuffer(void);
105 | };
106 | }
107 | }
108 |
109 | #endif // _LTSM_LIBRFB_
110 |
--------------------------------------------------------------------------------
/src/tests/encodings/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 |
11 | #include "ltsm_application.h"
12 | #include "ltsm_framebuffer.h"
13 | #include "librfb_server2.h"
14 | #include "ltsm_tools.h"
15 |
16 | using namespace LTSM;
17 |
18 | struct Image
19 | {
20 | std::unique_ptr fb;
21 |
22 | Image(std::filesystem::path file)
23 | {
24 | std::unique_ptr sf{IMG_Load(file.c_str()), SDL_FreeSurface};
25 |
26 | if(sf)
27 | {
28 | SDL_PixelFormat* pf = sf->format;
29 | auto fb24 = FrameBuffer((uint8_t*) sf->pixels, XCB::Region(0, 0, sf->w, sf->h), PixelFormat(pf->BitsPerPixel, pf->Rmask, pf->Gmask, pf->Bmask, pf->Amask), sf->pitch);
30 | fb = std::make_unique(XCB::Size(fb24.width(), fb24.height()), BGRA32);
31 | fb->blitRegion(fb24, XCB::Region(0, 0, fb->width(), fb->height()), XCB::Point(0, 0));
32 | }
33 |
34 | Application::info("%s: loading: %s", __FUNCTION__, file.c_str());
35 | }
36 | };
37 |
38 | class EncodingTest : public Application
39 | {
40 | std::unique_ptr srv;
41 | std::list images;
42 | std::string imagesPath;
43 | int useThreads = 1;
44 |
45 | public:
46 | EncodingTest(const std::string & folder, int threadNum) : Application("encoding-test"), imagesPath(folder), useThreads(threadNum)
47 | {
48 | }
49 |
50 | int start(void)
51 | {
52 | std::list jobs;
53 |
54 | if(std::filesystem::is_directory(imagesPath))
55 | {
56 | for(auto const & dirEntry : std::filesystem::directory_iterator{imagesPath})
57 | {
58 | jobs.emplace_back(std::thread([this, file = dirEntry.path()]()
59 | {
60 | images.emplace_back(std::move(file));
61 | }));
62 | }
63 | }
64 |
65 | for(auto & job: jobs)
66 | if(job.joinable()) job.join();
67 |
68 | if(! images.empty())
69 | {
70 | /*
71 | auto encodings = { RFB::ENCODING_RRE, RFB::ENCODING_CORRE, RFB::ENCODING_HEXTILE,
72 | #ifdef LTSM_ENCODING_FFMPEG
73 | RFB::ENCODING_FFMPEG_H264,
74 | #endif
75 | #ifdef LTSM_ENCODING
76 | RFB::ENCODING_LTSM_QOI, RFB::ENCODING_LTSM_LZ4, RFB::ENCODING_LTSM_TJPG,
77 | #endif
78 | RFB::ENCODING_ZLIB, RFB::ENCODING_TRLE, RFB::ENCODING_ZRLE };
79 | */
80 | auto encodings = {
81 | RFB::ENCODING_LTSM_QOI, RFB::ENCODING_LTSM_LZ4, RFB::ENCODING_LTSM_TJPG };
82 |
83 | auto & pf = images.front().fb->pixelFormat();
84 |
85 | srv = std::make_unique(images.front().fb.get());
86 |
87 | Application::info("%s: pixel format, bpp: %d, rmask: 0x%08x, gmask: 0x%08x, bmask: 0x%08x, amask: 0x%08x",
88 | __FUNCTION__, (int) pf.bitsPerPixel(), pf.rmask(), pf.gmask(), pf.bmask(), pf.amask());
89 |
90 |
91 | for(auto type: encodings)
92 | {
93 | srv->serverSetClientEncoding(type);
94 | srv->setEncodingDebug(0);
95 | srv->setEncodingThreads(useThreads);
96 |
97 | auto tp = std::chrono::steady_clock::now();
98 |
99 | for(const auto & img: images)
100 | srv->sendFrameBufferUpdate(*img.fb);
101 |
102 | auto dt = std::chrono::duration_cast(std::chrono::steady_clock::now() - tp);
103 | Application::info("%s: encoding: %s, time: %dms, stream sz: %dMb", __FUNCTION__, RFB::encodingName(type), dt.count(), srv->getBuffer().size()/(1024*1024));
104 |
105 | srv->resetBuffer();
106 | }
107 | }
108 |
109 | return 0;
110 | }
111 | };
112 |
113 | int main(int argc, char** argv)
114 | {
115 | auto hardwareThreads = std::thread::hardware_concurrency();
116 | int threadNum = hardwareThreads;
117 | std::string folder = "images";
118 |
119 | for(int it = 1; it < argc; ++it)
120 | {
121 | if(0 == std::strcmp(argv[it], "--thread") && it + 1 < argc)
122 | {
123 | try
124 | {
125 | threadNum = std::stoi(argv[it + 1]);
126 | }
127 | catch(const std::invalid_argument &)
128 | {
129 | std::cerr << "incorrect threads number" << std::endl;
130 | }
131 | it = it + 1;
132 | }
133 | else
134 | if(0 == std::strcmp(argv[it], "--images") && it + 1 < argc)
135 | {
136 | folder.assign(argv[it + 1]);
137 | it = it + 1;
138 | }
139 | else
140 | {
141 | std::cout << "usage: " << argv[0] << " --thread " << " --images " << std::endl;
142 | return 0;
143 | }
144 | }
145 |
146 | if(threadNum < 0 || hardwareThreads < threadNum)
147 | threadNum = hardwareThreads;
148 |
149 | int res = 0;
150 | SDL_Init(SDL_INIT_TIMER);
151 |
152 | try
153 | {
154 | res = EncodingTest(folder, threadNum).start();
155 | }
156 | catch(const std::exception & err)
157 | {
158 | Application::error("exception: %s", err.what());
159 | }
160 |
161 | SDL_Quit();
162 | return res;
163 | }
164 |
--------------------------------------------------------------------------------
/src/tests/framebuf/main.cpp:
--------------------------------------------------------------------------------
1 | //#include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "ltsm_framebuffer.h"
11 | #include "ltsm_xcb_wrapper.h"
12 |
13 | using namespace LTSM;
14 |
15 | int rand2(int min, int max)
16 | {
17 | if(min > max) std::swap(min, max);
18 | return min + std::rand() / (RAND_MAX + 1.0) * (max - min + 1);
19 | }
20 |
21 | XCB::RegionPixel regionPixelRandom(const XCB::Size & wsz, const PixelFormat & pixelFormat)
22 | {
23 | uint8_t cr = rand2(0, 255);
24 | uint8_t cg = rand2(0, 255);
25 | uint8_t cb = rand2(0, 255);
26 |
27 | auto col = Color(cr, cg, cb, 0xFF);
28 | auto reg = XCB::Region(rand2(0, wsz.width - 1), rand2(0, wsz.height - 1), 32, 32);
29 |
30 | return XCB::RegionPixel(reg, pixelFormat.pixel(col));
31 | }
32 |
33 | FrameBuffer generate(const PixelFormat & pf)
34 | {
35 | FrameBuffer back(XCB::Size(640, 480), pf);
36 | back.fillColor(back.region(), Color());
37 |
38 | std::cout << "generate 1000 regions" << std::endl;
39 | for(int it = 0; it < 1000; ++it)
40 | {
41 | auto rp = regionPixelRandom(back.region(), back.pixelFormat());
42 | back.fillPixel(rp.region(), rp.pixel());
43 | }
44 |
45 | back.drawRect(XCB::Region(160, 120, 320, 240), Color(0xFF, 0xFF, 0));
46 | return back;
47 | }
48 |
49 | int main(int argc, char** argv)
50 | {
51 | std::cout << "sizeof PixelFormat " << sizeof(LTSM::PixelFormat) << std::endl;
52 | std::cout << "sizeof FrameBuffer " << sizeof(LTSM::FrameBuffer) << std::endl;
53 | std::cout << "sizeof Region " << sizeof(LTSM::XCB::Region) << std::endl;
54 | std::cout << "sizeof unique_ptr " << sizeof(std::unique_ptr) << std::endl;
55 | std::cout << "sizeof shared_ptr " << sizeof(std::shared_ptr) << std::endl;
56 | std::cout << "sizeof atomic " << sizeof(std::atomic