Skip to content
Commits on Source (56)
  • Мирослав Николић's avatar
    70d63416
  • Sveinn í Felli's avatar
    Update Icelandic translation · 47f9048f
    Sveinn í Felli authored
    47f9048f
  • Pascal Nowack's avatar
    clipboard-rdp: Also check for / separator when preparing uri-list · de9e158e
    Pascal Nowack authored
    When preparing the uri-list for a file list of copied files, only the
    actual selected files and folders need to be included in the uri-list,
    since files in subfolders are automatically handled.
    To check for the selected files, gnome-remote-desktop only checks for
    the backslash ('\\') operator, but not also for the slash operator
    ('/'), which could lead to errors during the pasting operation, even
    though the use of the slash operator in file lists is discouraged.
    
    Fix this situation by also accounting for the slash operator, when
    preparing uri-lists.
    
    See also: https://github.com/FreeRDP/FreeRDP/issues/8350
    de9e158e
  • Nathan Follens's avatar
    Update Dutch translation · 56878f70
    Nathan Follens authored
    56878f70
  • Pascal Nowack's avatar
    rdp: Deprecate the legacy graphics path · 35dfaaad
    Pascal Nowack authored
    In the initial days the RDP backend in gnome-remote-desktop, the legacy
    path (mostly the RemoteFX codec path) was an easy and fast way to
    implement a way to submit frame updates to the client.
    In addition to the RemoteFX codec path, a path for the NSCodec and for
    raw bitmaps was added.
    The reason for the latter two was a misconfiguration of popular
    clients, namely Remmina and xfreerdp.
    
    Remmina by default assumed, that the server side always supports AVC
    and that the client side is able to choose the used codec.
    The reality is that Remmina actually limited the supported codecs,
    forcing the server side to use worse codecs, leading to a reduced
    remote desktop experience.
    xfreerdp also supported all codecs, but never advertised them, leading
    to the same bad experience (high bandwidth usage, very low
    performance).
    Remminas issues were fixed two years ago in [0] by always advertising
    all supported codecs by default.
    xfreerdp does the same since version 2.7.0.
    Distributions, like Ubuntu also backported the respective changes.
    
    As times passed, the problems of the legacy path became visible:
    Fastpath updates cannot be larger than a negotiated size, and therefore
    PDUs using the fastpath must be split into multiple parts manually.
    This is especially a problem for the NSCodec and the raw bitmaps path,
    as their maximum output size is not predictable, resulting in bad
    performance and dropped updates.
    Both symptoms result in a horrible remote desktop experience.
    The graphics pipeline and any other virtual channels are unaffected by
    this, as virtual channels either run via the slowpath or via UDP.
    Despite its name, the slowpath is not slow, but has additional overhead
    on the network traffic.
    PDUs of dynamic virtual channels (DVCs) are also split, but on a lower
    level, basically not affecting any PDU usage in the channels
    themselves.
    
    Additionally, the raw bitmap path has certain alignment restrictions
    (e.g. width and height MUST be a multiple of 4), making it unsuitable
    for the usage of headless sessions, where arbitrary resolutions are
    used.
    Furthermore, users don't know any internals of the Remote Desktop
    Protocol (RDP) and if they try to force the usage of the legacy path,
    they will have a slow remote desktop experience and blame it on the
    server.
    
    Due to the amount of problems with the legacy path and the maintenance
    cost, start deprecating the legacy path.
    For this, only allow for now the legacy path to be used, when the
    respective debug environment variable is set.
    In the next development cycle, start removing the legacy path.
    The graphics pipeline is already the default in Azure, where it is used
    for the infamous RDP short path and with the aforementioned changes
    both xfreerdp and Remmina also now always prefer the usage of the
    graphics pipeline.
    
    [0]: https://gitlab.com/Remmina/Remmina/-/merge_requests/2099
    35dfaaad
  • ThatFatPat's avatar
    18d0e211
  • Pascal Nowack's avatar
    rdp-server: Remove stray new line · 526fc491
    Pascal Nowack authored
    526fc491
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Assert buffer types to be either MemFds or DmaBufs · d395a141
    Pascal Nowack authored
    Buffers containing frame data received by mutter always contain buffers
    of type MemFd or DmaBuf.
    So, remove the path that ignores the buffer data, as it is supposed to
    be never hit.
    d395a141
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Assert buffer types to be either MemFds or DmaBufs · 4173532e
    Pascal Nowack authored
    Buffers containing frame data received by mutter always contain buffers
    of type MemFd or DmaBuf.
    So, remove the path that ignores the buffer data, as it is supposed to
    be never hit.
    4173532e
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Don't pass NULL as frame to on_frame_ready · 48a30bd2
    Pascal Nowack authored
    This only leads to an assertion hit. If it would not hit the assertion
    in on_frame_ready, it would leak the frame.
    
    Fixes: https://errors.ubuntu.com/problem/6f9ac35833672d86f0f7a13a9a68551f186a55f2
    48a30bd2
  • Pascal Nowack's avatar
    rdp-buffer: Add getters to retrieve buffer attributes · 7725f3c1
    Pascal Nowack authored
    This is a preparatory step in making the buffer struct private.
    7725f3c1
  • Pascal Nowack's avatar
    rdp-buffer: Rename unmap_resources to queue_resource_unmap · 5ad6b0a2
    Pascal Nowack authored
    The task is not directly done, but actually queued to the EGL thread.
    Also invert the is-mapped-condition for more readability of the code.
    5ad6b0a2
  • Pascal Nowack's avatar
    rdp-buffer: Add API to actually unmap the CUDA resource · 783163f9
    Pascal Nowack authored
    This allows us later to hide the buffer struct internals, while keeping
    its functionality.
    The actual code was just copied from the rdp-pipewire-stream class.
    783163f9
  • Pascal Nowack's avatar
    rdp-buffer: Add API to map CUDA resource · 1539eb76
    Pascal Nowack authored
    This allows us later to hide the buffer struct internals, while keeping
    its functionality.
    The actual code was just copied from the rdp-pipewire-stream class.
    1539eb76
  • Pascal Nowack's avatar
    rdp-buffer: Add API to register read-only GL buffer · 88d08075
    Pascal Nowack authored
    This allows us later to hide the buffer struct internals, while keeping
    its functionality.
    The actual code was just copied from the rdp-pipewire-stream class.
    88d08075
  • Pascal Nowack's avatar
    rdp: Avoid direct usage of the attributes of RDP buffers · be0091b7
    Pascal Nowack authored
    With the previously added APIs to access some of the buffer internals,
    avoid now the direct usage of any buffer attributes by using the buffer
    API methods instead.
    be0091b7
  • Pascal Nowack's avatar
    rdp-buffer: Make buffer struct private · 7c3696bf
    Pascal Nowack authored
    Now that the buffer attributes are no longer used directly, make the
    buffer struct private.
    7c3696bf
  • Pascal Nowack's avatar
    egl-thread: Remove unused callback context · b599861a
    Pascal Nowack authored
    b599861a
  • Pascal Nowack's avatar
    egl-thread: Remove unused typedef · 4750effe
    Pascal Nowack authored
    4750effe
  • Olga Smirnova's avatar
    Add Interlingue translation · c0bd4f47
    Olga Smirnova authored
    (cherry picked from commit 09849926)
    c0bd4f47
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Ignore frame data, when mapping memfd fails · 789ae171
    Pascal Nowack authored
    Since the mapping operation failed, the frame data is invalid.
    So, ignore it by using FALSE as success value for on_frame_ready.
    789ae171
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Decouple pointer updates from frame updates · f67d1918
    Pascal Nowack authored
    When handling PipeWire buffer contents, it is possible that a frame
    contains both frame data and pointer data.
    In such case, the frame data might need to be processed on the EGL
    thread.
    In this particular situation, the pointer data is handled first in the
    PipeWire data thread and then a task is pushed into the queue of the
    EGL thread.
    
    While the frame data is processed on the EGL thread, a new pointer
    update can occur and be directly handled.
    If the frame data of the previous PipeWire buffer was now finished
    processing, both frame data and pointer data of that PipeWire buffer
    are now pushed to the actual frame handling of the respective backend.
    The frame data is now new, but the pointer data is not and should be
    dropped.
    
    This currently results into old pointer updates replacing newer
    updates.
    To handle this situation, simply decouple pointer updates from frame
    updates.
    For that, add a separate GSource for the pointer data, where it is
    handled alone.
    f67d1918
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Decouple pointer updates from frame updates · c899b6c4
    Pascal Nowack authored
    When handling PipeWire buffer contents, it is possible that a frame
    contains both frame data and pointer data.
    In such case, the frame data might need to be processed on the EGL
    thread.
    In this particular situation, the pointer data is handled first in the
    PipeWire data thread and then a task is pushed into the queue of the
    EGL thread.
    
    While the frame data is processed on the EGL thread, a new pointer
    update can occur and be directly handled.
    If the frame data of the previous PipeWire buffer was now finished
    processing, both frame data and pointer data of that PipeWire buffer
    are now pushed to the actual frame handling of the respective backend.
    The frame data is now new, but the pointer data is not and should be
    dropped.
    
    This currently results into old pointer updates replacing newer
    updates.
    To handle this situation, simply decouple pointer updates from frame
    updates.
    For that, add a separate GSource for the pointer data, where it is
    handled alone.
    c899b6c4
  • Jonas Ådahl's avatar
    build: Bump version to 44.alpha · 76ea41dd
    Jonas Ådahl authored
    76ea41dd
  • Vasil Pupkin's avatar
    Add Belarusian translation · 6071c201
    Vasil Pupkin authored
    6071c201
  • Sabri Ünal's avatar
    Update Turkish translation · 6a4274b9
    Sabri Ünal authored
    6a4274b9
  • Pascal Nowack's avatar
    hwaccel-nvidia: Replace deprecated function cuDeviceComputeCapability · 0bd317f9
    Pascal Nowack authored
    The usage of the CUDA function cuDeviceComputeCapability is deprecated.
    The CUDA documentation mentions, that this function was superceded by
    cuDeviceGetAttribute, so use that one instead to retrieve the compute
    capability of CUDA devices.
    0bd317f9
  • Pascal Nowack's avatar
    session: Fix a small style issue · a7b4b2a0
    Pascal Nowack authored
    a7b4b2a0
  • Pascal Nowack's avatar
    pipewire-utils: Fix a few style issues · 8f149b36
    Pascal Nowack authored
    8f149b36
  • Pascal Nowack's avatar
    rdp: Stop dequeuing PipeWire buffers while destroying the stream · 20f6725c
    Pascal Nowack authored
    When destroying a PipeWire stream, gnome-remote-desktop needs to handle
    two cases:
    
    1. Ensure, that all PipeWire buffers have been processed by the EGL
       thread.
    2. Ensure, that while waiting on the EGL thread, no new buffers are
       queued onto the EGL thread.
    
    This was initially done with a helper variable and a call to
    pw_stream_flush, which mostly solved the situation, but not always.
    When audio output forwarding was implemented, it was discovered, that
    setting a PipeWire stream inactive seems to wait for the PipeWire data
    thread, as the PipeWire data thread in audio streams was waiting for a
    mutex to be released, and the inactive call did only return, when that
    mutex was unlocked.
    As a result, the old mechanic during the stream destruction was
    replaced by setting the PipeWire stream inactive.
    However, regardless of this, there are still crash reports in both
    Fedora retrace and Ubuntu errors.
    
    It appears, with some help in reproduction using GConds and g_usleep(),
    that setting a PipeWire stream inactive, does not wait for the data
    thread to end its iteration.
    This is at least true for any screencast stream.
    
    So, to finally fix this situation, do not rely on any PipeWire methods
    any more.
    Instead, introduce, like initially done, a helper variable, that tells
    the PipeWire data thread to not dequeue any buffers any more.
    However, instead of flushing the stream, pair the helper variable with
    a mutex.
    The PipeWire data thread will lock the mutex during its whole
    operation, while the main thread only locks it to set the helper
    variable.
    
    This partly reverts 4303a4f5.
    20f6725c
  • Pascal Nowack's avatar
    rdp: Only invoke frame source, when previous operation was successful · 9f8bd8d3
    Pascal Nowack authored
    There is no need to invoke the frame source here, as there is no new
    frame in this situation.
    9f8bd8d3
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Remove code path, that is not hit any more · 26a9ad4e
    Pascal Nowack authored
    Since frame updates and pointer updates were decoupled, each frame
    always has a buffer, when success is TRUE, so remove the
    steal-buffer-operation.
    26a9ad4e
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Remove superfluous condition · fdcbfa14
    Pascal Nowack authored
    Since frame- and pointer-update-operations were decoupled, this
    condition is not necessary any more.
    fdcbfa14
  • Pascal Nowack's avatar
    vnc: Stop dequeuing PipeWire buffers while destroying the stream · 37638fcc
    Pascal Nowack authored
    When destroying a PipeWire stream, gnome-remote-desktop needs to handle
    two cases:
    
    1. Ensure, that all PipeWire buffers have been processed by the EGL
       thread.
    2. Ensure, that while waiting on the EGL thread, no new buffers are
       queued onto the EGL thread.
    
    This was initially done with a helper variable and a call to
    pw_stream_flush, which mostly solved the situation, but not always.
    When audio output forwarding was implemented, it was discovered, that
    setting a PipeWire stream inactive seems to wait for the PipeWire data
    thread, as the PipeWire data thread in audio streams was waiting for a
    mutex to be released, and the inactive call did only return, when that
    mutex was unlocked.
    As a result, the old mechanic during the stream destruction was
    replaced by setting the PipeWire stream inactive.
    However, regardless of this, there are still crash reports in both
    Fedora retrace and Ubuntu errors.
    
    It appears, with some help in reproduction using GConds and g_usleep(),
    that setting a PipeWire stream inactive, does not wait for the data
    thread to end its iteration.
    This is at least true for any screencast stream.
    
    So, to finally fix this situation, do not rely on any PipeWire methods
    any more.
    Instead, introduce, like initially done, a helper variable, that tells
    the PipeWire data thread to not dequeue any buffers any more.
    However, instead of flushing the stream, pair the helper variable with
    a mutex.
    The PipeWire data thread will lock the mutex during its whole
    operation, while the main thread only locks it to set the helper
    variable.
    
    This partly reverts ce68ee97.
    37638fcc
  • Pascal Nowack's avatar
    vnc: Only invoke frame source, when previous operation was successful · 9e6468a6
    Pascal Nowack authored
    There is no need to invoke the frame source here, as there is no new
    frame in this situation.
    9e6468a6
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Remove code path, that is not hit any more · 3dbde9ca
    Pascal Nowack authored
    Since frame updates and pointer updates were decoupled, each frame
    always has a buffer, when success is TRUE, so remove the
    steal-buffer-operation.
    3dbde9ca
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Remove superfluous condition · a6bfd627
    Pascal Nowack authored
    Since frame- and pointer-update-operations were decoupled, this
    condition is not necessary any more.
    a6bfd627
  • Pascal Nowack's avatar
    rdp-audio-output-stream: Destroy the stream before clearing its pointer · 43421cda
    Pascal Nowack authored
    Like with screencast streams, do not assume, that setting the stream
    inactive will also always stop the PipeWire data thread.
    Directly destroying the PipeWire stream also clears the stream
    listener, so don't try to remove it manually, as clearing it before the
    stream could potentially lead to unwanted side effects and trying to
    clear the hook after the stream itself is an invalid operation.
    43421cda
  • Pascal Nowack's avatar
    session-rdp: Add error info for invalid monitor layouts · f5c6c653
    Pascal Nowack authored
    Clients can send invalid monitor layouts and that is a problem on the
    client side.
    Such clients should be disconnected, so extend the possibilities for the
    error info PDU to be able to also notify such errors before
    disconnecting such client.
    f5c6c653
  • Pascal Nowack's avatar
    rdp: Be more strict with invalid monitor layouts · 2343df77
    Pascal Nowack authored
    Currently, when a remote desktop client sends an invalid monitor layout,
    gnome-remote-desktop either assesses it as valid or it ignores it.
    This is not ideal, because if the layout is invalid, it is a bug in the
    remote desktop client.
    If the layout really changed, then users may perceive such situation,
    where gnome-remote-desktop just ignores such layout, as server issue.
    Especially, for future situations, where gnome-remote-desktop will have
    to handle multi monitor configuration, an invalid layout can lead to
    undefined behaviour, when attempting to sanitize the layout data, such
    as gaps between monitors in the layout, or overlapping monitors.
    
    To handle these situations better, always output warnings for invalid
    monitor layouts and disconnect the client.
    2343df77
  • Pascal Nowack's avatar
    rdp-display-control: Disconnect clients, that violate message order · df47eb7d
    Pascal Nowack authored
    The display virtual channel extension is very simple: The server side
    first sends the capabilities PDU and only then, the client is allowed to
    send new monitor layouts.
    If the client sends a layout, before the server sent the capabilities,
    the client violated the protocol message order.
    In such case, the client was also not able to constrain the layout to
    the given capabilities.
    
    To handle this situation, disconnect the faulty client.
    df47eb7d
  • Pascal Nowack's avatar
    rdp-fuse-clipboard: Rely on include dir in pkgconfig file · d5f16cd8
    Pascal Nowack authored
    While unexpected, theoretically, the include dir in the pkgconfig could
    change between updates.
    So, don't use the full path for the include path of the related header
    files.
    d5f16cd8
  • Pascal Nowack's avatar
    session-rdp: Also advertise RemoteFX in image mode · 31bccd03
    Pascal Nowack authored
    Plain RemoteFX exists not only in the graphics pipeline, but also in
    the legacy path.
    RemoteFX in the legacy path has two modes: image mode and video mode.
    While gnome-remote-desktop already advertises RemoteFX in video mode,
    the image mode is currently not advertised.
    
    To avoid any potential problems with clients, also advertise RemoteFX
    in image mode.
    Since only the server side produces RemoteFX encoded content, this
    won't lead to problems.
    RemoteFX in image mode is an inferior method to transfer encoded image
    content, compared to the video mode.
    However, it might be accepted by more clients.
    31bccd03
  • Pascal Nowack's avatar
    clipboard: Always call g_task_return_pointer() after reading content · 663348a1
    Pascal Nowack authored
    Recent glib versions have an additional check in the handling of
    GTasks, where it is checked, whether a GTask returned anything before
    it is destroyed.
    When no GTask-return call has been made, glib will print an annoying
    warning about a potential bug, regardless of whether it is a bug to not
    call g_task_return_*() or doing it.
    
    For the clipboard handling in gnome-remote-desktop,
    gnome-remote-desktop must be able to retrieve the clipboard content in
    an async way, while also be able to answer clipboard content requests
    before advertising new mime type lists.
    As a result, gnome-remote-desktop cannot handle the read result in the
    GTask callback, because in that case, the new mime type list was
    already announced and the read request must have been already handled.
    To be able to handle that situation, gnome-remote-desktop cannot use
    any g_task_return_*() calls to return actual results.
    
    To just get rid of this new glib warning, just call
    g_task_return_pointer() with a NULL pointer in the GTask thread.
    The overall behaviour stays the same and will continue to function,
    however without that new annoying warning.
    663348a1
  • Pascal Nowack's avatar
    egl: Release current context before destroying it in error paths · 9e7f89b1
    Pascal Nowack authored
    Otherwise, resources associated to the context are leaked.
    9e7f89b1
  • Pascal Nowack's avatar
    egl-thread: Add ability to replace transfer tasks · de24f2a6
    Pascal Nowack authored
    The EGL thread handles transfer tasks, like uploading frame data to the
    GPU or downloading dma-buf images to the host.
    These tasks are all queued up into a queue, so before a task is
    handled, all its previous tasks must be handled.
    Some GPU drivers, like the Intel driver are extremely slow, and during
    screencast sessions it is not rare, that multiple frames for one stream
    are queued up, while the previous ones could and should be dropped, as
    having a low frame latency is important in remote desktop sessions.
    
    To be able to drop older operations, add the ability to acquire EGL
    slots.
    When submitting tasks to these slots, the pending frame operation is
    dropped, while its callback is still called to be able to queue the
    related PipeWire buffer again.
    The overall order in the queue is still preserved across slots, so sync
    operations are still possible to do.
    de24f2a6
  • Pascal Nowack's avatar
    rdp-pipewire-stream: Acquire EGL slot for transfer tasks · 83c58a83
    Pascal Nowack authored
    Since the EGL thread can now replace transfer tasks using EGL slots,
    create one for each stream.
    This eliminates the frame latency, that was caused due to lots of
    pending tasks, when using slow drivers, like the Intel driver, where
    previously it was not unusual to have up to 7 pending download tasks.
    Do, however, not create an EGL slot for streams, when CUDA is
    available, as currently gnome-remote-desktop still relies on CUDA-map
    and -unmap operations for hardware acceleration with NVIDIA GPUs and
    these tasks are not considered in this design.
    In the future, these CUDA-map and CUDA-unmap operations will be replaced
    by a different mechanism.
    83c58a83
  • Pascal Nowack's avatar
    vnc-pipewire-stream: Acquire EGL slot for transfer tasks · 3e703e08
    Pascal Nowack authored
    Since the EGL thread can now replace transfer tasks using EGL slots,
    create one for each stream.
    This eliminates the frame latency, that was caused due to lots of
    pending tasks, when using slow drivers, like the Intel driver, where
    previously it was not unusual to have up to 7 pending download tasks.
    3e703e08
  • Pascal Nowack's avatar
    rdp-dsp: Fix typo in error message · 9a0e9ba1
    Pascal Nowack authored
    9a0e9ba1
  • Pascal Nowack's avatar
    build: Bump FreeRDP version requirement · d2888749
    Pascal Nowack authored
    FreeRDP 2.10.0 contains a very important fix ([0]) in the DRDYNVC
    handling, which prevents data PDUs in DVCs (DYNVC_DATA_FIRST and
    DYNVC_DATA) to be processed and forwarded to channel handlers, when the
    respective channel has not been opened successfully.
    This fix is a requirement for the [MS-RDPEA] SVC fallback handling, as
    otherwise a security issue would be introduced, where a malicious client
    could respond with a negative creation status for the DVC creation, but
    continue sending PDUs of that not successfully opened DVC, leading to
    undefined behaviour.
    This undefined behaviour cannot be reliably prevented without the fix in
    [0].
    So bump the FreeRDP version accordingly.
    
    [0]: https://github.com/FreeRDP/FreeRDP/commit/559dcf214a2a1203e43d57d2b7b048c5612b4f05
    d2888749
  • Pascal Nowack's avatar
    rdp-audio-playback: Add SVC fallback, when DVC is unavailable · 5e53d4e3
    Pascal Nowack authored
    In the early days of RDP, only static virtual channels (SVCs) existed.
    As a result, there was only the RDPSND SVC for audio output
    redirection.
    Later, Microsoft added the DRDYNVC SVC, which tunnels dynamic virtual
    channels (DVCs).
    Dynamic virtual channels have some advantages: They can be opened and
    closed on-the-fly during the session without problems, are not limited
    by the maximum of 31 SVCs, and, if available, can use UDP as transport
    method.
    
    The audio output redirection protocol is quite unique in RDP, as it can
    be used over multiple types of channels.
    While in the past only the RDPSND SVC was used, today, MS Windows RDS
    first tries to open the DVC for audio output redirection and then falls
    back to the SVC, if the DVC is unavailable.
    
    gnome-remote-desktop currently only supports the DVC. The main reason
    was: It works with the major clients mstsc and FreeRDP-based clients.
    Mobile clients, like the Microsofts iOS and Android client did cause
    problems, because it appeared, that audio and remote desktop
    interaction stuttered heavily, when both audio and graphics updates
    were sent at the same time.
    These mobile clients only support the SVC and as a result, an SVC
    fallback, when the client does not support the DVC was not added.
    
    However, Microsofts Mac client also does not support the DVC and
    therefore requires the SVC in order to have audio output redirection.
    
    So, implement the SVC fallback for [MS-RDPEA] and in the next commit,
    exclude mobile clients based on their reported OS type.
    5e53d4e3
  • Pascal Nowack's avatar
    session-rdp: Disable audio output redirection for mobile clients · f60f0ede
    Pascal Nowack authored
    Now that the SVC fallback has been implemented, mobile client (iOS and
    Android) need to be excluded with a different method.
    Use for this their reported osMajorType versions.
    
    In the future, when their heavy audio stutter issue during simultaneous
    audio and graphics updates is resolved, remove this exclusion.
    f60f0ede
  • Pascal Nowack's avatar
    rdp-audio-playback: Also output client version, when version is too old · d1404e4c
    Pascal Nowack authored
    This might help, when debugging issues.
    d1404e4c
  • Pascal Nowack's avatar
    2824b92c
  • Jonas Ådahl's avatar
    build: Bump version to 44.rc · 3d1eb780
    Jonas Ådahl authored
    3d1eb780
  • Jeremy Bicha's avatar
    New upstream version 44~rc · 4093b1bd
    Jeremy Bicha authored
    4093b1bd
......@@ -9,7 +9,7 @@ stages:
.gnome-remote-desktop.fedora:35@common:
variables:
FDO_DISTRIBUTION_VERSION: 36
BASE_TAG: '2022-08-03.0'
BASE_TAG: '2023-03-02.0'
FDO_UPSTREAM_REPO: GNOME/gnome-remote-desktop
FDO_DISTRIBUTION_EXEC: |
dnf -y update && dnf -y upgrade &&
......@@ -48,7 +48,7 @@ stages:
-DWITH_CLIENT_CHANNELS=ON \
-DWITH_SERVER_CHANNELS=ON \
https://github.com/FreeRDP/FreeRDP \
master . e3fc97feb512053189e276b2ca79762990bb8c4c &&
2.10.0 . &&
dnf clean all
......
project('gnome-remote-desktop', 'c',
version: '43.3',
version: '44.rc',
meson_version: '>= 0.57.0',
default_options: ['warning_level=1',
'buildtype=debugoptimized'])
cuda_req = '>= 11.1.5.0'
epoxy_req = '>= 1.4'
freerdp_req = '>= 2.8.0'
freerdp_req = '>= 2.10.0'
fuse_req = '>= 3.9.1'
xkbcommon_req = '>= 1.0.0'
......
# please keep this list sorted alphabetically
#
ab
be
bg
ca
cs
......
# Belarusian translation for gnome-remote-desktop.
# Copyright (C) 2022 gnome-remote-desktop's COPYRIGHT HOLDER
# This file is distributed under the same license as the gnome-remote-desktop package.
# Yuras Shumovich <shumovichy@gmail.com>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-remote-desktop master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-remote-desktop/"
"issues\n"
"POT-Creation-Date: 2022-11-20 13:27+0000\n"
"PO-Revision-Date: 2023-01-08 22:52+0300\n"
"Last-Translator: Yuras Shumovich <shumovichy@gmail.com>\n"
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
"Language: be\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 3.2.2\n"
#: src/grd-daemon.c:503
msgid "GNOME Remote Desktop"
msgstr "Аддалены працоўны стол GNOME"
#: src/grd-prompt.c:124
#, c-format
msgid "Do you want to share your desktop?"
msgstr "Хочаце даць доступ да свайго працоўнага стала?"
#: src/grd-prompt.c:125
#, c-format
msgid ""
"A user on the computer '%s' is trying to remotely view or control your "
"desktop."
msgstr ""
"Карыстальнік камп'ютара «%s» спрабуе аддалена праглядаць або кіраваць вашым "
"працоўным столом."
#: src/grd-prompt.c:131
msgid "Refuse"
msgstr "Адхіліць"
#: src/grd-prompt.c:136
msgid "Accept"
msgstr "Прыняць"
#: src/grd-ctl.c:53
#, c-format
msgid "Usage: %s [OPTIONS...] COMMAND [SUBCOMMAND]...\n"
msgstr "Выкарыстанне: %s [ПАРАМЕТРЫ...] КАМАНДА [ПАДКАМАНДА ]...\n"
#: src/grd-ctl.c:461
msgid "Commands:\n"
msgstr "Каманды:\n"
#: src/grd-ctl.c:466
msgid ""
" rdp - RDP subcommands:\n"
" enable - Enable the RDP backend\n"
" disable - Disable the RDP backend\n"
" set-tls-cert <path-to-cert> - Set path to TLS certificate\n"
" set-tls-key <path-to-key> - Set path to TLS key\n"
" set-credentials <username> <password> - Set username and password\n"
" credentials\n"
" clear-credentials - Clear username and password\n"
" credentials\n"
" enable-view-only - Disable remote control of "
"input\n"
" devices\n"
" disable-view-only - Enable remote control of "
"input\n"
" devices\n"
"\n"
msgstr ""
" rdp - Падкаманды RDP:\n"
" enable - Уключыць бэкэнд RDP\n"
" disable - Адключыць бэкэнд RDP\n"
" set-tls-cert <path-to-cert> - Задаць шлях да сертыфікату "
"TLS\n"
" set-tls-key <path-to-key> - Задаць шлях да ключа TLS\n"
" set-credentials <username> <password> - Задаць імя карыстальніка і\n"
" пароль\n"
" clear-credentials - Ачысціць імя карыстальніка і\n"
" пароль\n"
" enable-view-only - Адключыць аддаленае "
"кіраванне\n"
" прыладамі ўводу\n"
" disable-view-only - Уключыць аддаленае кіраванне\n"
" прыладамі ўводу\n"
"\n"
#: src/grd-ctl.c:485
msgid ""
" vnc - VNC subcommands:\n"
" enable - Enable the VNC backend\n"
" disable - Disable the VNC backend\n"
" set-password <password> - Set the VNC password\n"
" clear-password - Clear the VNC password\n"
" set-auth-method password|prompt - Set the authorization method\n"
" enable-view-only - Disable remote control of "
"input\n"
" devices\n"
" disable-view-only - Enable remote control of "
"input\n"
" devices\n"
"\n"
msgstr ""
" vnc - Падкаманды VNC:\n"
" enable - Уключыць бэкэнд VNC\n"
" disable - Адключыць бэкэнд VNC\n"
" set-password <password> - Задаць пароль VNC\n"
" clear-password - Ачысціць пароль VNC\n"
" set-auth-method password|prompt - Задаць метад аўтарызацыі\n"
" enable-view-only - Адключыць аддаленае "
"кіраванне\n"
" прыладамі ўводу\n"
" disable-view-only - Уключыць аддаленае кіраванне\n"
" прыладамі ўводу\n"
"\n"
#: src/grd-ctl.c:500
msgid ""
" status [--show-credentials] - Show current status\n"
"\n"
"Options:\n"
" --headless - Use headless credentials "
"storage\n"
" --help - Print this help text\n"
msgstr ""
" status [--show-credentials] - Паказаць бягучы стан\n"
"\n"
"Параметры:\n"
" --headless - Выкарыстоўваць сховішча "
"ўліковых\n"
" даных без манітора\n"
" --help - Вывесці гэту даведку\n"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:7
msgid "Whether the RDP backend is enabled or not"
msgstr "Ці ўключаны бэкэнд RDP"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:8
msgid "If set to 'true' the RDP backend will be initialized."
msgstr "Калі значэнне «true», будзе ініцыялізаваны бэкэнд RDP."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:14
msgid "Screenshare mode of RDP connections"
msgstr "Рэжым супольнага доступу да экрана для злучэнняў RDP"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:15
msgid ""
"The screenshare mode specifies, whether the RDP backend mirrors the primary "
"screen, or whether a virtual monitor is created. For the initial resolution "
"of the virtual monitor, the RDP backend uses either the client core data "
"([MS-RDPBCGR] 2.2.1.3.2) or the client monitor data ([MS-RDPBCGR] "
"2.2.1.3.6), depending on what is available. When using a remote desktop "
"session with a virtual monitor, clients can resize the resolution of the "
"virtual monitor during a session with the Display Update Virtual Channel "
"Extension ([MS-RDPEDISP]). Allowed screenshare modes include: * mirror-"
"primary - Record the primary monitor of the current user session. * extend - "
"Create a new virtual monitor and use it for the remote desktop session. The "
"resolution of this virtual monitor is derived from the monitor "
"configuration, submitted by the remote desktop client."
msgstr ""
"Рэжым супольнага доступу да экрана вызначае, будзе бэкэнд RDP адлюстроўваць "
"асноўны экран або будзе створаны віртуальны манітор. У залежнасці ад таго, "
"што даступна, пачатковую раздзяляльную здольнасць для віртуальнага манітора "
"бэкэнд RDP бярэ або з даных ядра кліента ([MS-RDPBCGR] 2.2.1.3.2), або з "
"даных манітора кліента ([MS-RDPBCGR] 2.2.1.3.6). Пры выкарыстанні сеанса "
"аддаленага працоўнага стала з віртуальным маніторам кліенты могуць змяняць "
"падчас сеанса раздзяляльную здольнасць віртуальнага манітора праз Display "
"Update Virtual Channel Extension ([MS-RDPEDISP]). Дазволеныя рэжымы "
"супольнага доступу да экрана: * mirror-primary - запіс асноўнага манітора з "
"бягучага сеанса карыстальніка, * extend - стварыць новы віртуальны манітор і "
"выкарыстоўваць яго для сеанса аддаленага працоўнага стала. Раздзяляльная "
"здольнасць гэтага віртуальнага манітора вызначаецца з канфігурацыі манітора, "
"якая перадаецца кліентам аддаленага працоўнага стала."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:41
msgid "Path to the certificate file"
msgstr "Шлях да файла сертыфіката"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:42
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:50
msgid ""
"In order to be able to use RDP with TLS Security, both the private key file "
"and the certificate file need to be provided to the RDP server."
msgstr ""
"Каб мець магчымасць выкарыстоўваць RDP з TLS Security, для сервера RDP "
"патрэбна ўказаць файл закрытага ключа і файл сертыфіката."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:49
msgid "Path to the private key file"
msgstr "Шлях да файла закрытага ключа"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:57
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:74
msgid "Only allow remote connections to view the screen content"
msgstr "Дазволіць аддаленым злучэнням толькі праглядаць змесціва экрана"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:58
msgid ""
"When view-only is true, remote RDP connections cannot manipulate input "
"devices (e.g. mouse and keyboard)."
msgstr ""
"Калі значэнне ключа view-only (толькі для прагляду) мае значэнне «true», "
"аддаленыя злучэнні RDP не могуць кіраваць прыладамі ўводу (напрыклад, мышшу "
"і клавіятурай)."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:67
msgid "Whether the VNC backend is enabled or not"
msgstr "Ці ўключаны бэкэнд VNC"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:68
msgid "If set to 'true' the VNC backend will be initialized."
msgstr "Калі значэнне «true», будзе ініцыялізаваны бэкэнд VNC."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:75
msgid ""
"When view-only is true, remote VNC connections cannot manipulate input "
"devices (e.g. mouse and keyboard)."
msgstr ""
"Калі значэнне ключа view-only (толькі для прагляду) мае значэнне «true», "
"аддаленыя злучэнні VNC не могуць кіраваць прыладамі ўводу (напрыклад, мышшу "
"і клавіятурай)."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:82
msgid "Method used to authenticate VNC connections"
msgstr "Метад аўтэнтыфікацыі для злучэнняў VNC"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:83
msgid ""
"The VNC authentication method describes how a remote connection is "
"authenticated. It can currently be done in two different ways: * prompt - by "
"prompting the user for each new connection, requiring a person with physical "
"access to the workstation to explicitly approve the new connection. * "
"password - by requiring the remote client to provide a known password"
msgstr ""
"Метад аўтэнтыфікацыі VNC апісвае, як выконваецца аўтэнтыфікацыя аддаленага "
"злучэння. Зараз гэта можа быць зроблена двума спосабамі: * prompt - запыт "
"пры кожным новым злучэнні, ад карыстальніка, які мае фізічны доступ да "
"працоўнай станцыі, патрабуецца яўна ўхваліць новае злучэнне; * password - ад "
"аддаленага кліента патрабуецца ўвесці вядомы яму пароль"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:95
msgid "Screenshare mode of VNC connections"
msgstr "Рэжым супольнага доступу да экрана для злучэнняў VNC"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:96
msgid ""
"The screenshare mode specifies, whether the VNC backend mirrors the primary "
"screen, or whether a virtual monitor is created. For the initial resolution "
"of the virtual monitor, the VNC backend uses a default size of 1920x1080 "
"pixels. When using a remote desktop session with a virtual monitor, clients "
"can resize the resolution of the virtual monitor during a session with the "
"setDesktopSize PDU. Allowed screenshare modes include: * mirror-primary - "
"Record the primary monitor of the current user session. * extend - Create a "
"new virtual monitor and use it for the remote desktop session. The initial "
"monitor resolution of this virtual monitor is set to 1920x1080 pixels. "
"Clients can override the initial resolution with subsequent monitor "
"configuration updates."
msgstr ""
"Рэжым супольнага доступу да экрана вызначае, будзе бэкэнд VNC адлюстроўваць "
"асноўны экран або будзе створаны віртуальны манітор. Прадвызначаная "
"пачатковая раздзяляльнасць для віртуальнага манітора 1920x1080 пікселяў. Пры "
"выкарыстанні сеанса аддаленага працоўнага стала з віртуальным маніторам, "
"кліенты могуць змяняць падчас сеанса раздзяляльную здольнасць віртуальнага "
"манітора праз setDesktopSize PDU. Дазволеныя рэжымы супольнага доступу да "
"экрана: * mirror-primary - запіс асноўнага манітора з бягучага сеанса "
"карыстальніка, * extend - стварыць новы віртуальны манітор і выкарыстоўваць "
"яго для сеанса аддаленага працоўнага стала. Пачатковая раздзяляльная "
"здольнасць гэтага віртуальнага манітора 1920x1080 пікселяў. У далейшым "
"кліенты могуць абнавіць канфігурацыю манітора і змяніць пачатковую "
"раздзяляльную здольнасць."
......@@ -7,8 +7,8 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-remote-desktop/issu"
"es\n"
"POT-Creation-Date: 2022-11-20 15:07+0000\n"
"PO-Revision-Date: 2022-11-30 17:24+0000\n"
"POT-Creation-Date: 2022-09-05 10:19+0000\n"
"PO-Revision-Date: 2022-10-25 16:04+0000\n"
"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
"Language-Team: Icelandic\n"
"Language: is\n"
......@@ -47,7 +47,7 @@ msgstr "Samþykkja"
#: src/grd-ctl.c:53
#, c-format
msgid "Usage: %s [OPTIONS...] COMMAND [SUBCOMMAND]...\n"
msgstr ""
msgstr "Notkun: %s [VALKOSTIR...] SKIPUN [UNDIRSKIPUN]...\n"
#: src/grd-ctl.c:461
msgid "Commands:\n"
......@@ -99,6 +99,12 @@ msgid ""
"storage\n"
" --help - Print this help text\n"
msgstr ""
" status [--show-credentials] - Sýna fyrirliggjandi stöðu\n"
"\n"
"Valkostir:\n"
" --headless - Nota hauslausa"
" auðkenningageymslu\n"
" --help - Birta þennan hjálpartexta\n"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:7
msgid "Whether the RDP backend is enabled or not"
......
......@@ -11,7 +11,7 @@ msgstr ""
"Project-Id-Version: gnome-remote-desktop.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-remote-desktop/"
"issues\n"
"POT-Creation-Date: 2022-11-08 16:56+0000\n"
"POT-Creation-Date: 2022-10-30 11:45+0000\n"
"PO-Revision-Date: 2022-11-01 23:06+0100\n"
"Last-Translator: Nathan Follens <nfollens@gnome.org>\n"
"Language-Team: Dutch <gnome-nl-list@gnome.org>\n"
......
# Serbian translation for gnome-remote-desktop.
# Copyright (C) 2021 gnome-remote-desktop's COPYRIGHT HOLDER
# Copyright © 2021 gnome-remote-desktop's COPYRIGHT HOLDER
# This file is distributed under the same license as the gnome-remote-desktop package.
# Марко Костић <marko.m.kostic@gmail.com>, 2021.
# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2022.
......@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: gnome-remote-desktop master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-remote-desktop/"
"issues\n"
"POT-Creation-Date: 2022-11-06 15:30+0000\n"
"PO-Revision-Date: 2022-11-20 15:06+0100\n"
"POT-Creation-Date: 2022-09-18 07:45+0000\n"
"PO-Revision-Date: 2022-10-19 09:46+0200\n"
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
"Language-Team: Serbian <српски <gnome-sr@googlegroups.org>>\n"
"Language: sr\n"
......@@ -19,6 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
"X-Generator: Gtranslator 3.36.0\n"
#: src/grd-daemon.c:503
msgid "GNOME Remote Desktop"
......@@ -49,7 +50,7 @@ msgstr "Прихвати"
#: src/grd-ctl.c:53
#, c-format
msgid "Usage: %s [OPTIONS...] COMMAND [SUBCOMMAND]...\n"
msgstr "Употреба: %s [ОПЦИЈЕ...] НАРЕДБА [ПОДНАРЕДБА]...\n"
msgstr "Коришћење: %s [ОПЦИЈЕ...] НАРЕДБА [ПОДНАРЕДБА]...\n"
#: src/grd-ctl.c:461
msgid "Commands:\n"
......@@ -75,20 +76,21 @@ msgid ""
"\n"
msgstr ""
" rdp - РДП поднаредбе:\n"
" enable - Омогући РДП позадинца\n"
" disable - Онемогући РДП позадинца\n"
" set-tls-cert <path-to-cert> - Подеси путању до ТЛС "
" enable - Омогућава РДП позадинца\n"
" disable - Онемогућава РДП позадинца\n"
" set-tls-cert <path-to-cert> - Подешава путању до ТЛС "
"сертификата\n"
" set-tls-key <path-to-key> - Подеси путању до ТЛС кључа\n"
" set-credentials <username> <password> - Подеси акредитиве за "
" set-tls-key <path-to-key> - Подешава путању до ТЛС кључа\n"
" set-credentials <username> <password> - Подешава акредитиве за "
"корисничко\n"
" име и лозинку\n"
" clear-credentials - Очисти акредитиве корисничког "
" clear-credentials - Чисти акредитиве корисничког "
"имена и\n"
" лозинке\n"
" enable-view-only - Онемогући удаљено управљање\n"
" enable-view-only - Онемогућава удаљено "
"управљање\n"
" улазних уређаја\n"
" disable-view-only - Омогући удаљено управљање\n"
" disable-view-only - Омогућава удаљено управљање\n"
" улазних уређаја\n"
"\n"
......@@ -109,14 +111,15 @@ msgid ""
"\n"
msgstr ""
" vnc - ВНЦ поднаредбе:\n"
" enable - Омогући ВНЦ позадинца\n"
" disable - Онемогући ВНЦ позадинца\n"
" set-password <password> - Подеси ВНЦ лозинку\n"
" clear-password - Очисти ВНЦ лозинку\n"
" set-auth-method password|prompt - Подеси начин ауторизације\n"
" enable-view-only - Онемогући удаљено управљање\n"
" enable - Омогућава ВНЦ позадинца\n"
" disable - Онемогућава ВНЦ позадинца\n"
" set-password <password> - Подешава ВНЦ лозинку\n"
" clear-password - Чисти ВНЦ лозинку\n"
" set-auth-method password|prompt - Подешава начин ауторизације\n"
" enable-view-only - Онемогућава удаљено "
"управљање\n"
" улазних уређаја\n"
" disable-view-only - Омогући удаљено управљање\n"
" disable-view-only - Омогућава удаљено управљање\n"
" улазних уређаја\n"
"\n"
......@@ -137,8 +140,8 @@ msgstr ""
" status [--show-credentials] - Приказује тренутно стање\n"
"\n"
"Опције:\n"
" --headless - Користи безглави смештај "
"креденцијала\n"
" --headless - Користи безглаво смештање "
"опонумоћења\n"
" --help - Приказује ову поруку помоћи\n"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:7
......@@ -181,17 +184,17 @@ msgid ""
"resolution of this virtual monitor is derived from the monitor "
"configuration, submitted by the remote desktop client."
msgstr ""
"Режим дељења екрана наводи да ли РДП позадинац пресликава примарни екран или "
"се прави виртуелни екран. За почетну резолуцију виртуелног екрана, РДП "
"Режим дељења екрана одређује да ли РДП позадинац пресликава примарни екран "
"или се прави виртуелни екран. За почетну резолуцију виртуелног екрана, РДП "
"позадинац користи или основне податке клијента ([MS-RDPBCGR] 2.2.1.3.2) или "
"податке екрана клијента ([MS-RDPBCGR] 2.2.1.3.6), зависно од тога шта је "
"доступно. Када се користи сесија удаљеног приступа са виртуелним екраном, "
"клијенти могу променити резолуцију виртуелног екрана у току сесије са "
"„Display Control Channel Extension ([MS-RDPEDISP]). Дозвољени режими дељења "
"екрана садрже: * mirror-primary – снима примарни екран тренутне корисничке "
"сесије. * extend – прави нови виртуелни екран и користи га током сесије "
"удаљеног приступа. Резолуција овог виртуелног екрана се изводи из подешавања "
"екрана које шаље клијент удаљеног приступа."
"„Display Update Virtual Channel Extension ([MS-RDPEDISP]). Дозвољени режими "
"дељења екрана садрже: * mirror-primary – снима примарни екран тренутне "
"корисничке сесије. * extend – прави нови виртуелни екран и користи га током "
"сесије удаљеног приступа. Резолуција овог виртуелног екрана се изводи из "
"подешавања екрана, које шаље клијент удаљеног приступа."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:41
msgid "Path to the certificate file"
......@@ -203,7 +206,7 @@ msgid ""
"In order to be able to use RDP with TLS Security, both the private key file "
"and the certificate file need to be provided to the RDP server."
msgstr ""
"Да бисте користили РДП са ТЛС безбедношћу, морате дати датотеку приватног "
"Да бисте користили РДП са ТЛС безбедношћу, морате дати и датотеку приватног "
"кључа и датотеку сертификата РДП серверу."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:49
......@@ -229,7 +232,7 @@ msgstr "Да ли је ВНЦ позадинац омогућен или не"
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:68
msgid "If set to 'true' the VNC backend will be initialized."
msgstr "Ако је изабрано, ВНЦ позадинац биће покренут."
msgstr "Ако је подешено на „true“, ВНЦ позадинац биће подешен."
#: src/org.gnome.desktop.remote-desktop.gschema.xml.in:75
msgid ""
......@@ -289,12 +292,13 @@ msgid ""
"configuration updates."
msgstr ""
"Режим дељења екрана наводи да ли РДП позадинац пресликава примарни екран или "
"се прави виртуелни екран. За почетну резолуцију виртуелног екрана, ВНЦ "
"позадинац користи основну величину од 1920×1080 пиксела. Када се користи "
"сесија удаљеног приступа са виртуелним екраном, клијенти могу променити "
"величину виртуелног екрана у току сесије са „setDesktopSize PDU“. Дозвољени "
"режими дељења екрана садрже: * mirror-primary – снима примарни екран "
"тренутне корисничке сесије. * extend – прави нови виртуелни екран и користи "
"га током сесије удаљеног приступа. Почетна резолуција екрана овог виртуелног "
"екрана је постављена на 1920×1080 пиксела. Клијенти могу преписати почетну "
"резолуцију надокнадним ажурирањима подешавања екрана."
"се прави виртуелни екран. За почетну резолуцију виртуелног екрана, РДП "
"позадинац користи или основне податке клијента ([MS-RDPBCGR] 2.2.1.3.2) или "
"податке екрана клијента ([MS-RDPBCGR] 2.2.1.3.6), зависно од тога шта је "
"доступно. Када се користи сесија удаљеног приступа са виртуелним екраном, "
"клијенти могу променити величину виртуелног екрана у току сесије са "
"„setDesktopSize PDU“. Дозвољени режими дељења екрана садрже: * mirror-"
"primary – снима примарни екран тренутне корисничке сесије. * extend – прави "
"нови виртуелни екран и користи га током сесије удаљеног приступа. Резолуција "
"овог виртуелног екрана се изводи из подешавања екрана, које шаље клијент "
"удаљеног приступа."
# Turkish translation for gnome-remote-desktop.
# Copyright (C) 2021-2022 gnome-remote-desktop's COPYRIGHT HOLDER
# Copyright (C) 2021-2023 gnome-remote-desktop's COPYRIGHT HOLDER
# This file is distributed under the same license as the gnome-remote-desktop package.
#
# Emin Tufan Çetin <etcetin@gmail.com>, 2021, 2022.
# Sabri Ünal <libreajans@gmail.com>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-remote-desktop master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-remote-desktop/"
"issues\n"
"POT-Creation-Date: 2022-09-05 10:19+0000\n"
"POT-Creation-Date: 2022-10-30 11:45+0000\n"
"PO-Revision-Date: 2022-09-01 20:32+0300\n"
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Turkish <gnometurk@gnome.org>\n"
......@@ -172,7 +173,7 @@ msgid ""
"configuration, submitted by the remote desktop client."
msgstr ""
"Ekran paylaşım kipi RDP arka ucunun birincil ekranı aynalayacağını mı "
"yoksasanal monitör mü yaratacağını belirler. RDP arka ucu sanal monitörün "
"yoksa sanal monitör mü oluşturacağını belirler. RDP arka ucu sanal monitörün "
"ilk çözünürlüğü için; uygunluğa bağlı olarak, istemci çekirdek verisini ([MS-"
"RDPBCGR] 2.2.1.3.2) veya istemci monitör verisini ([MS-RDPBCGR] 2.2.1.3.6) "
"kullanır. İstemciler bir uzaktan masaüstü oturumunu sanal monitörle "
......@@ -266,7 +267,7 @@ msgid ""
"configuration updates."
msgstr ""
"Ekran paylaşım kipi VNC arka ucunun birincil ekranı aynalayacağını mı yoksa "
"sanal monitör mü yaratacağını belirler. VNC arka ucu, sanal monitörün ilk "
"sanal monitör mü oluşturacağını belirler. VNC arka ucu, sanal monitörün ilk "
"çözünürlüğü için öntanımlı olarak 1920x1080 piksel boyut kullanır.İstemciler "
"bir uzaktan masaüstü oturumunu sanal monitörle kullanırken, setDesktopSize "
"PDU ile oturum sırasında sanal monitörün çözünürlüğünü değiştirebilir. İzin "
......
......@@ -1746,7 +1746,7 @@ get_uri_list_from_packet_file_list (GrdClipboardRdp *clipboard_rdp,
g_array_free (dst_data, TRUE);
return NULL;
}
if (strchr (filename, '\\'))
if (strchr (filename, '\\') || strchr (filename, '/'))
{
g_free (filename);
continue;
......@@ -1911,7 +1911,7 @@ convert_client_content_for_server (GrdClipboardRdp *clipboard_rdp,
g_free (dst_data);
return NULL;
}
if (strchr (filename, '\\'))
if (strchr (filename, '\\') || strchr (filename, '/'))
{
g_free (filename);
continue;
......
......@@ -254,6 +254,8 @@ read_mime_type_content_in_thread (GTask *task,
priv->read_result = read_result;
g_cond_signal (&priv->pending_read_cond);
g_mutex_unlock (&priv->pending_read_mutex);
g_task_return_pointer (task, NULL, NULL);
}
static gboolean
......
......@@ -27,6 +27,7 @@
static const GDebugKey grd_debug_keys[] = {
{ "vnc", GRD_DEBUG_VNC },
{ "tpm", GRD_DEBUG_TPM },
{ "rdp-legacy-graphics", GRD_DEBUG_RDP_LEGACY_GRAPHICS },
};
static GrdDebugFlags debug_flags;
......
......@@ -26,6 +26,7 @@ typedef enum _GrdDebugFlags
GRD_DEBUG_NONE = 0,
GRD_DEBUG_VNC = 1 << 0,
GRD_DEBUG_TPM = 1 << 1,
GRD_DEBUG_RDP_LEGACY_GRAPHICS = 1 << 2,
} GrdDebugFlags;
GrdDebugFlags grd_get_debug_flags (void);
......
......@@ -33,6 +33,7 @@ struct _GrdEglThread
GCond cond;
GAsyncQueue *task_queue;
GHashTable *slot_table;
GHashTable *modifiers;
......@@ -56,12 +57,19 @@ typedef struct _GrdEglTask
GFunc func;
GDestroyNotify destroy;
GMainContext *callback_context;
GrdEglThreadCallback callback;
gpointer callback_user_data;
GDestroyNotify callback_destroy;
} GrdEglTask;
typedef struct
{
GrdEglTask base;
GMutex task_mutex;
GrdEglTask *task;
} GrdReplaceableTask;
typedef struct _GrdEglTaskCustom
{
GrdEglTask base;
......@@ -140,8 +148,83 @@ typedef struct _GrdEglTaskDownload
uint64_t *modifiers;
} GrdEglTaskDownload;
typedef void (* GrdEglFrameReady) (uint8_t *data,
gpointer user_data);
static void
grd_egl_task_free (GrdEglTask *task)
{
if (task->callback_destroy)
g_clear_pointer (&task->callback_user_data, task->callback_destroy);
g_free (task);
}
static void
run_replaceable_task_in_impl (gpointer data,
gpointer user_data)
{
GrdEglThread *egl_thread = data;
GrdReplaceableTask *replaceable_task = user_data;
g_autoptr (GMutexLocker) locker = NULL;
GrdEglTask *task;
locker = g_mutex_locker_new (&replaceable_task->task_mutex);
task = g_steal_pointer (&replaceable_task->task);
if (!task)
return;
g_clear_pointer (&locker, g_mutex_locker_free);
task->func (egl_thread, task);
task->destroy (task);
}
static void
replaceable_task_dummy_free (GrdEglTask *task_base)
{
}
static GrdReplaceableTask *
replaceable_task_new (void)
{
GrdReplaceableTask *replaceable_task;
replaceable_task = g_new0 (GrdReplaceableTask, 1);
replaceable_task->base.func = run_replaceable_task_in_impl;
replaceable_task->base.destroy = (GDestroyNotify) replaceable_task_dummy_free;
g_mutex_init (&replaceable_task->task_mutex);
return replaceable_task;
}
static void
replaceable_task_replace_task (GrdReplaceableTask *replaceable_task,
GrdEglTask *new_task)
{
GrdEglTask *task;
g_mutex_lock (&replaceable_task->task_mutex);
task = g_steal_pointer (&replaceable_task->task);
if (task)
{
if (task->callback)
task->callback (FALSE, task->callback_user_data);
task->destroy (task);
}
replaceable_task->task = new_task;
g_mutex_unlock (&replaceable_task->task_mutex);
}
static void
replaceable_task_free (GrdReplaceableTask *replaceable_task)
{
replaceable_task_replace_task (replaceable_task, NULL);
g_mutex_clear (&replaceable_task->task_mutex);
grd_egl_task_free (&replaceable_task->base);
}
static gboolean
is_hardware_accelerated (void)
......@@ -321,6 +404,8 @@ initialize_egl_context (GrdEglThread *egl_thread,
if (!query_format_modifiers (egl_thread, egl_display, error))
{
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext (egl_display, egl_context);
eglTerminate (egl_display);
return FALSE;
......@@ -328,6 +413,8 @@ initialize_egl_context (GrdEglThread *egl_thread,
if (g_hash_table_size (egl_thread->modifiers) == 0)
{
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext (egl_display, egl_context);
eglTerminate (egl_display);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
......@@ -337,6 +424,8 @@ initialize_egl_context (GrdEglThread *egl_thread,
if (!is_hardware_accelerated ())
{
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext (egl_display, egl_context);
eglTerminate (egl_display);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
......@@ -386,14 +475,6 @@ grd_egl_init_in_impl (GrdEglThread *egl_thread,
return initialized;
}
static void
grd_egl_task_free (GrdEglTask *task)
{
if (task->callback_destroy)
g_clear_pointer (&task->callback_user_data, task->callback_destroy);
g_free (task);
}
static void
grd_egl_task_download_free (GrdEglTask *task_base)
{
......@@ -552,10 +633,12 @@ grd_egl_thread_func (gpointer user_data)
GrdEglThread *
grd_egl_thread_new (GError **error)
{
GrdEglThread *egl_thread;
g_autoptr (GrdEglThread) egl_thread = NULL;
egl_thread = g_new0 (GrdEglThread, 1);
egl_thread->slot_table =
g_hash_table_new_full (NULL, NULL,
NULL, (GDestroyNotify) replaceable_task_free);
egl_thread->modifiers =
g_hash_table_new_full (NULL, NULL,
NULL, (GDestroyNotify) g_array_unref);
......@@ -576,11 +659,10 @@ grd_egl_thread_new (GError **error)
if (egl_thread->impl.error)
{
g_propagate_error (error, egl_thread->impl.error);
grd_egl_thread_free (egl_thread);
return NULL;
}
return egl_thread;
return g_steal_pointer (&egl_thread);
}
static gboolean
......@@ -611,9 +693,35 @@ grd_egl_thread_free (GrdEglThread *egl_thread)
g_clear_pointer (&egl_thread->modifiers, g_hash_table_unref);
g_clear_pointer (&egl_thread->impl.main_context, g_main_context_unref);
g_assert (g_hash_table_size (egl_thread->slot_table) == 0);
g_clear_pointer (&egl_thread->slot_table, g_hash_table_unref);
g_free (egl_thread);
}
void *
grd_egl_thread_acquire_slot (GrdEglThread *egl_thread)
{
GrdReplaceableTask *replaceable_task;
replaceable_task = replaceable_task_new ();
g_async_queue_lock (egl_thread->task_queue);
g_hash_table_add (egl_thread->slot_table, replaceable_task);
g_async_queue_unlock (egl_thread->task_queue);
return replaceable_task;
}
void
grd_egl_thread_release_slot (GrdEglThread *egl_thread,
GrdEglThreadSlot slot)
{
g_async_queue_lock (egl_thread->task_queue);
g_hash_table_remove (egl_thread->slot_table, slot);
g_async_queue_unlock (egl_thread->task_queue);
}
static EGLImageKHR
create_dmabuf_image (GrdEglThread *egl_thread,
unsigned int width,
......@@ -965,8 +1073,28 @@ run_custom_task_in_impl (gpointer data,
task->base.callback (success, task->base.callback_user_data);
}
static void
push_replaceable_task (GrdEglThread *egl_thread,
GrdEglThreadSlot slot,
GrdEglTask *task)
{
GrdReplaceableTask *replaceable_task = NULL;
g_async_queue_lock (egl_thread->task_queue);
if (!g_hash_table_lookup_extended (egl_thread->slot_table, slot,
NULL, (gpointer *) &replaceable_task))
g_assert_not_reached ();
g_assert (replaceable_task);
replaceable_task_replace_task (replaceable_task, task);
g_async_queue_push_unlocked (egl_thread->task_queue, replaceable_task);
g_async_queue_unlock (egl_thread->task_queue);
}
void
grd_egl_thread_download (GrdEglThread *egl_thread,
GrdEglThreadSlot slot,
uint32_t pbo,
uint32_t pbo_height,
uint32_t pbo_stride,
......@@ -1017,7 +1145,11 @@ grd_egl_thread_download (GrdEglThread *egl_thread,
task->base.callback_user_data = user_data;
task->base.callback_destroy = destroy;
g_async_queue_push (egl_thread->task_queue, task);
if (slot)
push_replaceable_task (egl_thread, slot, &task->base);
else
g_async_queue_push (egl_thread->task_queue, task);
g_main_context_wakeup (egl_thread->impl.main_context);
}
......@@ -1080,6 +1212,7 @@ grd_egl_thread_deallocate (GrdEglThread *egl_thread,
void
grd_egl_thread_upload (GrdEglThread *egl_thread,
GrdEglThreadSlot slot,
uint32_t pbo,
uint32_t height,
uint32_t stride,
......@@ -1118,7 +1251,11 @@ grd_egl_thread_upload (GrdEglThread *egl_thread,
task->base.callback_user_data = user_data;
task->base.callback_destroy = destroy;
g_async_queue_push (egl_thread->task_queue, task);
if (slot)
push_replaceable_task (egl_thread, slot, &task->base);
else
g_async_queue_push (egl_thread->task_queue, task);
g_main_context_wakeup (egl_thread->impl.main_context);
}
......
......@@ -26,6 +26,8 @@
#include "grd-types.h"
typedef gpointer GrdEglThreadSlot;
typedef void (* GrdEglThreadCallback) (gboolean success,
gpointer user_data);
typedef gboolean (* GrdEglThreadCustomFunc) (gpointer user_data);
......@@ -43,7 +45,13 @@ GrdEglThread * grd_egl_thread_new (GError **error);
void grd_egl_thread_free (GrdEglThread *egl_thread);
void * grd_egl_thread_acquire_slot (GrdEglThread *egl_thread);
void grd_egl_thread_release_slot (GrdEglThread *egl_thread,
GrdEglThreadSlot slot);
void grd_egl_thread_download (GrdEglThread *egl_thread,
GrdEglThreadSlot slot,
uint32_t pbo,
uint32_t pbo_height,
uint32_t pbo_stride,
......@@ -82,6 +90,7 @@ void grd_egl_thread_deallocate (GrdEglThread *egl_thread,
GDestroyNotify destroy);
void grd_egl_thread_upload (GrdEglThread *egl_thread,
GrdEglThreadSlot slot,
uint32_t pbo,
uint32_t height,
uint32_t stride,
......@@ -113,4 +122,6 @@ gboolean grd_egl_thread_get_modifiers_for_format (GrdEglThread *egl_thread,
int *out_n_modifiers,
uint64_t **out_modifiers);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GrdEglThread, grd_egl_thread_free)
#endif /* GRD_EGL_THREAD_H */
......@@ -850,7 +850,26 @@ grd_hwaccel_nvidia_new (GrdEglThread *egl_thread)
int cc_major = 0, cc_minor = 0;
cu_device = cu_devices[i];
cuda_funcs->cuDeviceComputeCapability (&cc_major, &cc_minor, cu_device);
cu_result =
cuda_funcs->cuDeviceGetAttribute (&cc_major,
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR,
cu_device);
if (cu_result != CUDA_SUCCESS)
{
g_warning ("[HWAccel.CUDA] Failed to get device attribute: %s",
get_cuda_error_string (hwaccel_nvidia, cu_result));
continue;
}
cu_result =
cuda_funcs->cuDeviceGetAttribute (&cc_minor,
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR,
cu_device);
if (cu_result != CUDA_SUCCESS)
{
g_warning ("[HWAccel.CUDA] Failed to get device attribute: %s",
get_cuda_error_string (hwaccel_nvidia, cu_result));
continue;
}
g_debug ("[HWAccel.CUDA] Device %u compute capability: [%i, %i]",
i, cc_major, cc_minor);
......
......@@ -26,7 +26,8 @@
#include <spa/param/video/raw.h>
#include <spa/utils/result.h>
static void pipewire_source_unref (GrdPipeWireSource *pipewire_source);
static void
pipewire_source_unref (GrdPipeWireSource *pipewire_source);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GrdPipeWireSource, pipewire_source_unref)
......@@ -54,7 +55,7 @@ pipewire_loop_source_dispatch (GSource *source,
spa_strerror (result));
}
return TRUE;
return G_SOURCE_CONTINUE;
}
static void
......
......@@ -346,10 +346,8 @@ grd_rdp_audio_output_stream_dispose (GObject *object)
if (audio_output_stream->pipewire_stream)
{
pw_stream_set_active (audio_output_stream->pipewire_stream, false);
spa_hook_remove (&audio_output_stream->pipewire_stream_listener);
g_clear_pointer (&audio_output_stream->pipewire_stream, pw_stream_destroy);
pw_stream_destroy (audio_output_stream->pipewire_stream);
audio_output_stream->pipewire_stream = NULL;
}
if (audio_output_stream->pipewire_node)
{
......
......@@ -70,6 +70,9 @@ struct _GrdRdpAudioPlayback
GrdSessionRdp *session_rdp;
GrdRdpDvc *rdp_dvc;
gboolean prevent_dvc_initialization;
GSource *svc_setup_source;
GMutex protocol_timeout_mutex;
GSource *channel_teardown_source;
GSource *protocol_timeout_source;
......@@ -141,6 +144,9 @@ grd_rdp_audio_playback_maybe_init (GrdRdpAudioPlayback *audio_playback)
if (audio_playback->channel_opened || audio_playback->channel_unavailable)
return;
if (audio_playback->prevent_dvc_initialization)
return;
rdpsnd_context = audio_playback->rdpsnd_context;
if (rdpsnd_context->Start (rdpsnd_context))
{
......@@ -251,7 +257,7 @@ acquire_stream_lock (GrdRdpAudioPlayback *audio_playback,
{
g_assert (!audio_playback->has_stream_lock);
g_debug ("[RDP.AUDIO_PLAYBACK] Locking audio stream to node id: %u", node_id);
g_debug ("[RDP.AUDIO_PLAYBACK] Locking audio stream to node id %u", node_id);
audio_playback->locked_node_id = node_id;
audio_playback->has_stream_lock = TRUE;
......@@ -428,9 +434,9 @@ dvc_creation_status (gpointer user_data,
if (creation_status < 0)
{
g_message ("[RDP.AUDIO_PLAYBACK] Failed to open AUDIO_PLAYBACK_DVC "
"channel (CreationStatus %i). Terminating protocol",
"channel (CreationStatus %i). Trying SVC fallback",
creation_status);
g_source_set_ready_time (audio_playback->channel_teardown_source, 0);
g_source_set_ready_time (audio_playback->svc_setup_source, 0);
}
}
......@@ -535,8 +541,8 @@ rdpsnd_activated (RdpsndServerContext *rdpsnd_context)
if (rdpsnd_context->clientVersion < 8)
{
g_message ("[RDP.AUDIO_PLAYBACK] Client protocol version too old. "
"Terminating protocol");
g_message ("[RDP.AUDIO_PLAYBACK] Client protocol version (%u) too old. "
"Terminating protocol", rdpsnd_context->clientVersion);
g_source_set_ready_time (audio_playback->channel_teardown_source, 0);
return;
}
......@@ -605,6 +611,12 @@ rdpsnd_training_confirm (RdpsndServerContext *rdpsnd_context,
}
g_mutex_unlock (&audio_playback->protocol_timeout_mutex);
if (audio_playback->svc_setup_source)
{
g_source_destroy (audio_playback->svc_setup_source);
g_clear_pointer (&audio_playback->svc_setup_source, g_source_unref);
}
audio_playback->pending_training_confirm = FALSE;
g_source_set_ready_time (audio_playback->pipewire_setup_source, 0);
......@@ -765,6 +777,11 @@ grd_rdp_audio_playback_dispose (GObject *object)
g_source_destroy (audio_playback->channel_teardown_source);
g_clear_pointer (&audio_playback->channel_teardown_source, g_source_unref);
}
if (audio_playback->svc_setup_source)
{
g_source_destroy (audio_playback->svc_setup_source);
g_clear_pointer (&audio_playback->svc_setup_source, g_source_unref);
}
g_clear_pointer (&audio_playback->encode_context, g_main_context_unref);
......@@ -798,6 +815,43 @@ grd_rdp_audio_playback_finalize (GObject *object)
G_OBJECT_CLASS (grd_rdp_audio_playback_parent_class)->finalize (object);
}
static gboolean
set_up_static_virtual_channel (gpointer user_data)
{
GrdRdpAudioPlayback *audio_playback = user_data;
RdpsndServerContext *rdpsnd_context = audio_playback->rdpsnd_context;
g_clear_pointer (&audio_playback->svc_setup_source, g_source_unref);
g_assert (audio_playback->channel_opened);
audio_playback->prevent_dvc_initialization = TRUE;
rdpsnd_context->Stop (rdpsnd_context);
audio_playback->channel_opened = FALSE;
if (audio_playback->subscribed_status)
{
grd_rdp_dvc_unsubscribe_dvc_creation_status (audio_playback->rdp_dvc,
audio_playback->channel_id,
audio_playback->dvc_subscription_id);
audio_playback->subscribed_status = FALSE;
}
rdpsnd_context->use_dynamic_virtual_channel = FALSE;
if (rdpsnd_context->Start (rdpsnd_context))
{
g_warning ("[RDP.AUDIO_PLAYBACK] Failed to open RDPSND channel. "
"Terminating protocol");
audio_playback->channel_unavailable = TRUE;
g_source_set_ready_time (audio_playback->channel_teardown_source, 0);
return G_SOURCE_REMOVE;
}
audio_playback->channel_opened = TRUE;
return G_SOURCE_REMOVE;
}
static gboolean
tear_down_channel (gpointer user_data)
{
......@@ -1274,6 +1328,7 @@ static GSourceFuncs source_funcs =
static void
grd_rdp_audio_playback_init (GrdRdpAudioPlayback *audio_playback)
{
GSource *svc_setup_source;
GSource *channel_teardown_source;
GSource *encode_source;
GSource *pipewire_setup_source;
......@@ -1296,6 +1351,13 @@ grd_rdp_audio_playback_init (GrdRdpAudioPlayback *audio_playback)
audio_playback->encode_context = g_main_context_new ();
svc_setup_source = g_source_new (&source_funcs, sizeof (GSource));
g_source_set_callback (svc_setup_source, set_up_static_virtual_channel,
audio_playback, NULL);
g_source_set_ready_time (svc_setup_source, -1);
g_source_attach (svc_setup_source, NULL);
audio_playback->svc_setup_source = svc_setup_source;
channel_teardown_source = g_source_new (&source_funcs, sizeof (GSource));
g_source_set_callback (channel_teardown_source, tear_down_channel,
audio_playback, NULL);
......
......@@ -119,7 +119,7 @@ grd_rdp_buffer_pool_resize_buffers (GrdRdpBufferPool *buffer_pool,
static gboolean
buffer_has_mapped_data (GrdRdpBuffer *buffer)
{
if (buffer->mapped_cuda_pointer)
if (grd_rdp_buffer_get_mapped_cuda_pointer (buffer))
return TRUE;
return FALSE;
......@@ -250,7 +250,7 @@ unmap_untaken_buffers (gpointer user_data)
(gpointer *) &buffer_info))
{
if (!buffer_info->buffer_taken)
grd_rdp_buffer_unmap_resources (buffer);
grd_rdp_buffer_queue_resource_unmap (buffer);
}
g_mutex_unlock (&buffer_pool->pool_mutex);
......
......@@ -21,8 +21,6 @@
#include "grd-rdp-buffer.h"
#include <ffnvcodec/dynlink_cuda.h>
#include "grd-egl-thread.h"
#include "grd-hwaccel-nvidia.h"
#include "grd-rdp-buffer-pool.h"
......@@ -39,7 +37,7 @@ typedef struct
typedef struct
{
GrdHwAccelNvidia *hwaccel_nvidia;
GrdRdpBuffer *buffer;
GrdRdpBuffer *rdp_buffer;
} AllocateBufferData;
typedef struct
......@@ -49,19 +47,38 @@ typedef struct
CUstream cuda_stream;
} UnmapBufferData;
struct _GrdRdpBuffer
{
GrdRdpBufferPool *buffer_pool;
GrdEglThread *egl_thread;
GrdHwAccelNvidia *hwaccel_nvidia;
uint32_t width;
uint32_t height;
uint8_t *local_data;
uint32_t pbo;
CUgraphicsResource cuda_resource;
CUstream cuda_stream;
CUdeviceptr mapped_cuda_pointer;
};
static gboolean
cuda_allocate_buffer (gpointer user_data,
uint32_t pbo)
{
AllocateBufferData *data = user_data;
GrdRdpBuffer *buffer = data->buffer;
GrdRdpBuffer *rdp_buffer = data->rdp_buffer;
gboolean success;
success = grd_hwaccel_nvidia_register_read_only_gl_buffer (data->hwaccel_nvidia,
&buffer->cuda_resource,
&rdp_buffer->cuda_resource,
pbo);
if (success)
buffer->pbo = pbo;
rdp_buffer->pbo = pbo;
return success;
}
......@@ -90,34 +107,34 @@ grd_rdp_buffer_new (GrdRdpBufferPool *buffer_pool,
uint32_t stride,
gboolean preallocate_on_gpu)
{
GrdRdpBuffer *buffer;
g_autoptr (GrdRdpBuffer) rdp_buffer = NULL;
gboolean success = TRUE;
buffer = g_new0 (GrdRdpBuffer, 1);
buffer->buffer_pool = buffer_pool;
buffer->egl_thread = egl_thread;
buffer->hwaccel_nvidia = hwaccel_nvidia;
rdp_buffer = g_new0 (GrdRdpBuffer, 1);
rdp_buffer->buffer_pool = buffer_pool;
rdp_buffer->egl_thread = egl_thread;
rdp_buffer->hwaccel_nvidia = hwaccel_nvidia;
buffer->cuda_stream = cuda_stream;
rdp_buffer->cuda_stream = cuda_stream;
buffer->width = width;
buffer->height = height;
buffer->local_data = g_malloc0 (stride * height * sizeof (uint8_t));
rdp_buffer->width = width;
rdp_buffer->height = height;
rdp_buffer->local_data = g_malloc0 (stride * height * sizeof (uint8_t));
if (preallocate_on_gpu &&
buffer->hwaccel_nvidia)
rdp_buffer->hwaccel_nvidia)
{
AllocateBufferData data = {};
GrdSyncPoint sync_point = {};
g_assert (buffer->egl_thread);
g_assert (rdp_buffer->egl_thread);
grd_sync_point_init (&sync_point);
data.hwaccel_nvidia = buffer->hwaccel_nvidia;
data.buffer = buffer;
data.hwaccel_nvidia = rdp_buffer->hwaccel_nvidia;
data.rdp_buffer = rdp_buffer;
grd_egl_thread_allocate (buffer->egl_thread,
buffer->height,
grd_egl_thread_allocate (rdp_buffer->egl_thread,
rdp_buffer->height,
stride,
cuda_allocate_buffer,
&data,
......@@ -130,9 +147,9 @@ grd_rdp_buffer_new (GrdRdpBufferPool *buffer_pool,
}
if (!success)
g_clear_pointer (&buffer, grd_rdp_buffer_free);
return NULL;
return buffer;
return g_steal_pointer (&rdp_buffer);
}
static void
......@@ -152,37 +169,108 @@ cuda_deallocate_buffer (gpointer user_data)
data->cuda_stream);
}
static void
clear_buffers (GrdRdpBuffer *buffer)
void
grd_rdp_buffer_free (GrdRdpBuffer *rdp_buffer)
{
if (buffer->cuda_resource)
if (rdp_buffer->cuda_resource)
{
ClearBufferData *data;
data = g_new0 (ClearBufferData, 1);
data->hwaccel_nvidia = buffer->hwaccel_nvidia;
data->cuda_resource = buffer->cuda_resource;
data->cuda_stream = buffer->cuda_stream;
data->is_mapped = !!buffer->mapped_cuda_pointer;
grd_egl_thread_deallocate (buffer->egl_thread,
buffer->pbo,
data->hwaccel_nvidia = rdp_buffer->hwaccel_nvidia;
data->cuda_resource = rdp_buffer->cuda_resource;
data->cuda_stream = rdp_buffer->cuda_stream;
data->is_mapped = !!rdp_buffer->mapped_cuda_pointer;
grd_egl_thread_deallocate (rdp_buffer->egl_thread,
rdp_buffer->pbo,
cuda_deallocate_buffer,
data,
NULL, data, g_free);
buffer->mapped_cuda_pointer = 0;
buffer->cuda_resource = NULL;
buffer->pbo = 0;
rdp_buffer->mapped_cuda_pointer = 0;
rdp_buffer->cuda_resource = NULL;
rdp_buffer->pbo = 0;
}
g_clear_pointer (&buffer->local_data, g_free);
g_clear_pointer (&rdp_buffer->local_data, g_free);
g_free (rdp_buffer);
}
uint32_t
grd_rdp_buffer_get_width (GrdRdpBuffer *rdp_buffer)
{
return rdp_buffer->width;
}
uint32_t
grd_rdp_buffer_get_height (GrdRdpBuffer *rdp_buffer)
{
return rdp_buffer->height;
}
uint8_t *
grd_rdp_buffer_get_local_data (GrdRdpBuffer *rdp_buffer)
{
return rdp_buffer->local_data;
}
uint32_t
grd_rdp_buffer_get_pbo (GrdRdpBuffer *rdp_buffer)
{
return rdp_buffer->pbo;
}
CUdeviceptr
grd_rdp_buffer_get_mapped_cuda_pointer (GrdRdpBuffer *rdp_buffer)
{
return rdp_buffer->mapped_cuda_pointer;
}
void
grd_rdp_buffer_release (GrdRdpBuffer *rdp_buffer)
{
grd_rdp_buffer_pool_release_buffer (rdp_buffer->buffer_pool, rdp_buffer);
}
gboolean
grd_rdp_buffer_register_read_only_gl_buffer (GrdRdpBuffer *rdp_buffer,
uint32_t pbo)
{
gboolean success;
success =
grd_hwaccel_nvidia_register_read_only_gl_buffer (rdp_buffer->hwaccel_nvidia,
&rdp_buffer->cuda_resource,
pbo);
if (success)
rdp_buffer->pbo = pbo;
return success;
}
gboolean
grd_rdp_buffer_map_cuda_resource (GrdRdpBuffer *rdp_buffer)
{
size_t mapped_size = 0;
return grd_hwaccel_nvidia_map_cuda_resource (rdp_buffer->hwaccel_nvidia,
rdp_buffer->cuda_resource,
&rdp_buffer->mapped_cuda_pointer,
&mapped_size,
rdp_buffer->cuda_stream);
}
void
grd_rdp_buffer_free (GrdRdpBuffer *buffer)
grd_rdp_buffer_unmap_cuda_resource (GrdRdpBuffer *rdp_buffer)
{
clear_buffers (buffer);
g_free (buffer);
if (!rdp_buffer->mapped_cuda_pointer)
return;
grd_hwaccel_nvidia_unmap_cuda_resource (rdp_buffer->hwaccel_nvidia,
rdp_buffer->cuda_resource,
rdp_buffer->cuda_stream);
rdp_buffer->mapped_cuda_pointer = 0;
}
static gboolean
......@@ -198,31 +286,25 @@ cuda_unmap_resource (gpointer user_data)
}
void
grd_rdp_buffer_unmap_resources (GrdRdpBuffer *buffer)
{
if (buffer->mapped_cuda_pointer)
{
UnmapBufferData *data;
data = g_new0 (UnmapBufferData, 1);
data->hwaccel_nvidia = buffer->hwaccel_nvidia;
data->cuda_resource = buffer->cuda_resource;
data->cuda_stream = buffer->cuda_stream;
grd_egl_thread_run_custom_task (buffer->egl_thread,
cuda_unmap_resource,
data,
NULL, data, g_free);
/*
* The mapped CUDA pointer indicates whether the resource is mapped, but
* it is itself not needed to unmap the resource.
*/
buffer->mapped_cuda_pointer = 0;
}
}
void
grd_rdp_buffer_release (GrdRdpBuffer *buffer)
grd_rdp_buffer_queue_resource_unmap (GrdRdpBuffer *rdp_buffer)
{
grd_rdp_buffer_pool_release_buffer (buffer->buffer_pool, buffer);
UnmapBufferData *data;
if (!rdp_buffer->mapped_cuda_pointer)
return;
data = g_new0 (UnmapBufferData, 1);
data->hwaccel_nvidia = rdp_buffer->hwaccel_nvidia;
data->cuda_resource = rdp_buffer->cuda_resource;
data->cuda_stream = rdp_buffer->cuda_stream;
grd_egl_thread_run_custom_task (rdp_buffer->egl_thread,
cuda_unmap_resource,
data,
NULL, data, g_free);
/*
* The mapped CUDA pointer indicates whether the resource is mapped, but
* it is itself not needed to unmap the resource.
*/
rdp_buffer->mapped_cuda_pointer = 0;
}