Commit graph

1617 commits

Author SHA1 Message Date
Romain Vimont
9af3bacdd6 Refactor AOA handling
Extract event processing to a separate function.

This will make the code more readable when more event types will be
added.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
2dd02ebb80 Move HID ids to common HID code
The HID ids (accessory ids or UHID ids) were defined by the keyboard and
mouse implementations.

Instead, define them in the common HID part, and make that id part of
the sc_hid_event.

This prepares the introduction of gamepad support, which will handle
several gamepads (and ids) in the common HID gamepad code.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
dad04bf138 Fix HID mouse header guard
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
1afc8ca368 Add missing SC_ prefix for HID mouse event size
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
785099b74d Remove duplicate definition SC_HID_MAX_SIZE
This constant is defined in hid_event.h.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
08da2e068e Fail on AOA keyboard/mouse initialization error
If the AOA keyboard or the AOA mouse fails to be initialized, this is a
fatal error.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
49c8ca34fd Introduce non-droppable control messages
Control messages are queued from the main thread and sent to the device
from a separate thread.

When the queue is full, messages are just dropped. This avoids to
accumulate too much delay between the client and the device in case of
network issue.

However, some messages should not be dropped: for example, dropping a
UHID_CREATE message would make all further UHID_INPUT messages invalid.
Therefore, mark these messages as non-droppable.

A non-droppable event is queued anyway (resizing the queue if
necessary, unless the allocation fails).

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
a84b0dfd0c Remove atomics from keyboard_uhid
The UHID output callback is now called from the same (main) thread as
the process_key() function.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
cbf5db85c1 Process UHID outputs events from the main thread
This will guarantee that the callbacks of UHID devices implementations
will always be called from the same (main) thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
72ee195693 Set clipboard from the main thread
The clipboard changes from the device are received from a separate
thread, but they must be handled from the main thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:56 +02:00
Romain Vimont
8620d06741 Add mechanism to execute code on the main thread
This allows to schedule a runnable to be executed on the main thread,
until the event loop is explicitly terminated.

It is guaranteed that all accepted runnables will be executed (this
avoids possible memory leaks if a runnable owns resources).

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-15 11:21:55 +02:00
Romain Vimont
e9240f6804 Expose main thread id
This will allow to assert that a function is called from the main
thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-14 21:24:15 +02:00
Romain Vimont
e9b32d8a52 Extract sc_push_event()
Expose a convenience function to push an event without args to the main
thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-14 21:24:15 +02:00
Romain Vimont
ce4e1fc420 Store events numbers in an enum
This avoids to manually set an explicit value for each item.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-14 21:24:15 +02:00
Romain Vimont
e8f02685e9 Fix deprecated references in scrcpy manpage
The options --hid-keyboard and --hid-mouse do not exist anymore. They
have been replaced by --keyboard=XXX and --mouse=XXX.
2024-09-14 21:24:15 +02:00
Romain Vimont
4a6b335f7d Do not send uninitialized HID event
If the function returns false, then there is nothing to send.
2024-09-14 21:24:15 +02:00
Romain Vimont
90ee0062cb Fix compilation with -Dusb=false
UHID does not depend on USB support, so the struct sc_uhid_devices must
always be defined.
2024-09-14 21:24:15 +02:00
Romain Vimont
e03888d587 Reject arguments containing new line characters
Refs bec3321fff
2024-09-14 21:23:44 +02:00
Romain Vimont
8453e3ba7d Enable TCP_NODELAY for the control socket
It is better to disable Nagle's algorithm to avoid unnecessary latency
for control messages. (I'm not sure this has any impact for a local TCP
socket though.)
2024-09-14 19:46:55 +02:00
Romain Vimont
145a9468fd Fix ifdef _WIN32
We use _WIN32 across the code base, not __WIN32.
2024-09-14 14:42:00 +02:00
Romain Vimont
1d713d7598 Do not parse --max-fps float in the client
Many parsing and formatting C functions like strtof() and asprintf() are
locale-dependent. Forcing a C locale just for the conversions in a way
that works on all platforms is a mess.

In practice, this is not a problem, scrcpy always uses the C locale,
because it never calls:

    setlocale(LC_ALL, "");

But the max-fps option should not depend on the locale configuration
anyway.

Since the value is parsed by the client in Java anyway, just forward the
string value as is.
2024-09-14 14:37:30 +02:00
Romain Vimont
265a15e0b1 Accept float values for --max-fps
Android accepts a float value, there is no reason to limit the option
to be an integer.

In particular, it allows to capture at a rate lower than 1 fps. For
example, to capture 1 frame every 5 seconds:

    scrcpy --video-source=camera --max-fps=0.2

It was already possible to pass a float manually:

    scrcpy --video-source=camera \
        --video-codec-options=max-fps-to-encoder:float=0.2

But accepting a float directly for --max-fps is more convenient.

Refs <https://developer.android.com/reference/android/media/MediaFormat#KEY_MAX_FPS_TO_ENCODER>
2024-09-13 22:02:25 +02:00
Romain Vimont
bec3321fff Validate server arguments
Some command line arguments are passed as is to "adb shell". Therefore,
they must not contain special shell characters.
2024-09-13 19:53:05 +02:00
Romain Vimont
dea1fe3386 Validate crop and video size
A video width or height of 0 triggered an assert.

Fail explicitly instead: the server may actually send this size in
practice (for example on cropping with small dimensions, even if the
requested crop size is not 0).
2024-09-13 19:48:55 +02:00
Romain Vimont
a7cae59578 Improve delay buffer startup
The delay buffer clock estimates the clock offset between the PTS and
the frame decoded date using an "Exponentially Weighted Moving Average"
(EWMA).

But for the first frames, the clock have less than SC_CLOCK_RANGE
points to average. Since the timing for the first frames are typically
the worst ones, give more weight to the last point for the estimation.

Once SC_CLOCK_RANGE points are available (i.e. when SC_CLOCK_RANGE ==
clock->range), the new estimation is equivalent to the previous version.
2024-09-12 11:06:13 +02:00
Romain Vimont
f089ea67e1 Add missing flag initialization
The delay buffer `stopped` field was not initialized.

Since it practice the unique instance of sc_delay_buffer is initialized
in static memory, the flag was initialized to false as a side effect.

But with commit fd0f432e87, in debug mode
only, the delay buffer was broken.
2024-09-11 15:41:49 +02:00
Romain Vimont
63ced79842 Reverse NDEBUG conditions
By default, these specific debug logs are disabled.

Make the ifdef condition less confusing.
2024-09-11 15:41:29 +02:00
Romain Vimont
33a8c39beb Fix local NDEBUG define
The struct definition and the implementation did not use the same NDEBUG
constant.
2024-09-11 11:26:07 +02:00
Romain Vimont
903a5aaaf5 Replace "could not" by "cannot" where appropriate
"Could not" implies that the system tried to disable the option but
encountered an issue or failure.

"Cannot" indicates a rule or restriction, meaning it's not possible to
perform the action at all.
2024-09-09 08:24:52 +02:00
yangfl
dd47cefa47 Fix typos
Refs <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1077968#27>
PR #5171 <https://github.com/Genymobile/scrcpy/pull/5171>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-08-05 16:13:02 +02:00
Romain Vimont
cc41115625 Bump version to 2.6.1 2024-08-02 22:32:04 +02:00
Romain Vimont
52136268ef Bump version to 2.6 2024-08-01 18:15:59 +02:00
Romain Vimont
5d2441d198 Upgrade SDL (2.30.5) for Windows 2024-08-01 18:15:37 +02:00
Romain Vimont
071d459ad7 Fix --no-audio
By default, the audio source is initialized to SC_AUDIO_SOURCE_AUTO, and
is "resolved" only if audio is enabled.

But the server arguments were built assuming that the audio source was
never SC_AUDIO_SOURCE_AUTO (even with audio disabled), causing a crash.

Regression introduced by a10f8cd798.
2024-07-29 20:03:44 +02:00
Romain Vimont
127a271d34 Switch audio source if audio-dup is set
Automatically switch implicit audio source to "playback" if --audio-dup
is passed.

This allows to run:

    scrcpy --audio-dup

without specifying explicitly:

    scrcpy --audio-source=playback --audio-dup

PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>
2024-07-19 17:48:39 +02:00
Romain Vimont
31116a60d7 Add --audio-dup
Add an option to duplicate audio on the device, compatible with the new
audio playback capture (--audio-source=playback).

Fixes #3875 <https://github.com/Genymobile/scrcpy/issues/3875>
Fixes #4380 <https://github.com/Genymobile/scrcpy/issues/4380>
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2024-07-19 17:48:39 +02:00
Romain Vimont
a10f8cd798 Add audio playback capture method
Add a new method to capture audio playback.

It requires Android 13 (where the Shell app has MODIFY_AUDIO_ROUTING
permission).

The main benefit is that it supports keeping audio playing on the device
(implemented in a further commit).

Fixes #4380 <https://github.com/Genymobile/scrcpy/issues/4380>
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2024-07-19 17:48:39 +02:00
Romain Vimont
c57a0512ba Add assertions
Passing an unknown enum value to convert them to string would return
NULL without any error, possibly causing undefined behavior later.

Add assertions to catch such programming errors early.
2024-07-16 21:31:31 +02:00
Romain Vimont
9989668226 Add mouse secondary bindings
Add secondary bindings (Shift+click) for mouse buttons.

In addition to:

    --mouse-bind=xxxx

It is now possible to pass a sequence of secondary bindings:

    --mouse-bind=xxxx:xxxx
                 <--> <-->
             primary   secondary
            bindings   bindings

If the second sequence is omitted, then it is the same as the first one.

By default, for SDK mouse, primary bindings trigger shortcuts and
secondary bindings forward all clicks.

For AOA and UHID, the default bindings are reversed: all clicks are
forwarded by default, whereas pressing Shift+click trigger shortcuts.

    --mouse-bind=bhsn:++++  # default for SDK
    --mouse-bind=++++:bhsn  # default for AOA and UHID

Refs 035d60cf5d
Refs f5e6b8092a
Fixes #5055 <https://github.com/Genymobile/scrcpy/issues/5055>
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
6baea57987 Track mouse buttons state manually
The buttons state was tracked by SDL_GetMouseState(), and scrcpy applied
a mask to ignore buttons used for shortcuts.

Instead, track the buttons actually pressed (ignoring shortcuts)
manually, to prepare the introduction of more dynamic mouse shortcuts.

PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
86b8286217 Remove unused virtual mouse
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
51fee79bf5 Use finger source when a pointer is simulated
For pinch-to-zoom, rotation and tilt simulation, always use a finger
source (instead of a mouse) for both pointers (the real one and the
simulated one).

A "virtual" mouse does not work on all devices (e.g. on Pixel 8).

PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
6808288823 Make pointer id independent of mouse bindings
The device source (MOUSE or FINGER) to use depended on whether a
secondary click was possible via mouse bindings.

As a first step, always use a mouse source to break this dependency.
Note that this change might cause regressions in some (unknown) cases
(refs f70359f14f), but hopefully not.

Further commits will restore a finger source in some specific use cases,
but independent of secondary clicks.

Refs #5055 <https://github.com/Genymobile/scrcpy/issues/5055>
Fixes #5067 <https://github.com/Genymobile/scrcpy/issues/5067>
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
0bce4d7f56 Add missing SC_ prefix for pointer id constants
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
6d98766cd5 Simplify boolean condition using XOR
(A && !B) || (!A && B) <==> A ^ B

PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Romain Vimont
487a6b9cf4 Remove top-level const
For consistency, never use top-level const for local variables.

PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00
Yan
46041e0cc0 Always initialize display->gl_context on macOS
Otherwise SDL_GL_DeleteContext() tried to access an uninitialized
pointer upon exit when not using the OpenGL renderer.

SDL_GL_DeleteContext() doesn't try to delete a NULL pointer, so no need
to check for that.

Fixes #5057 <https://github.com/Genymobile/scrcpy/issues/5057>
PR #5058 <https://github.com/Genymobile/scrcpy/pull/5058>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-07-06 00:11:48 +02:00
Romain Vimont
b419eef55e Do not report error on device disconnected
A device disconnection (when the adb connection is closed) makes the
read() on the "receiver" socket fail.

Since commit 063a8339ed, this is reported
as an error. As a consequence, scrcpy fails with:

    ERROR: Controller error

instead of:

    WARN: Device disconnected

To fix the issue, report a device disconnection in that case.

PR #5044 <https://github.com/Genymobile/scrcpy/pull/5044>
2024-07-06 00:04:07 +02:00
Romain Vimont
a4f8c02502 Reorder initialization to simplify
This also avoids a warning with some compilers which do not understand
that the condition to initialize the variable is the same as the
condition to use it:

    ../app/src/scrcpy.c: In function ‘scrcpy’:
    ../app/src/scrcpy.c:750:13: warning: ‘src’ may be used uninitialized in this function [-Wmaybe-uninitialized]
      750 |             sc_frame_source_add_sink(src, &s->screen.frame_sink);
          |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Refs 45fe6b602b
Refs <https://github.com/Genymobile/scrcpy/issues/5045#issuecomment-2201589757>
2024-07-02 08:14:58 +02:00
Romain Vimont
89df38f641 Bump version to 2.5 2024-06-29 16:52:45 +02:00