Commit Graph

142 Commits (e22660d698900f949cfc6afdb41d49cb371f7cff)

Author SHA1 Message Date
Romain Vimont 4f9e9c6619 Prefix UI events constants by SC_ 1 year ago
Romain Vimont d8c2fe6ef2 Revert "Remove continuous resizing workaround for Windows"
This reverts commit 18082f6069.

I can't reproduce, but it seems the workaround improves the behavior on
some Windows versions.

Fixes #3640 <https://github.com/Genymobile/scrcpy/issues/3640>
Refs #3458 <https://github.com/Genymobile/scrcpy/issues/3458>
2 years ago
Romain Vimont 18082f6069 Remove continuous resizing workaround for Windows
It turns out that the workaround only worked for MacOS.

Refs #3458 <https://github.com/Genymobile/scrcpy/issues/3458>
Refs SDL/#1059 <https://github.com/libsdl-org/SDL/issues/1059>
2 years ago
Romain Vimont 3ee3f8dc02 Work around mouse capture SDL bug on macOS
On macOS, SDL relative mouse mode does not work correctly when the
cursor is outside the window.

As a workaround, move the cursor inside the window before setting the
relative mouse mode.

Refs SDL/#5340 <https://github.com/libsdl-org/SDL/issues/5340>
PR #3031 <https://github.com/Genymobile/scrcpy/pull/3031>
2 years ago
Romain Vimont 9db42341e4 Pass screen instance to mouse capture functions
Using the screen instance or not in these functions is an implementation
detail. Further changes will require the screen instance.

Refs 7848a387c8
PR #3031 <https://github.com/Genymobile/scrcpy/pull/3031>
2 years ago
Romain Vimont 4b018be789 Add --print-fps to enable FPS counter on start
The FPS counter could be enabled/disabled via MOD+i.

Add a command line option to enable it on start. This is consistent with
other features like --turn-screen-off or --fullscreen.

Fixes #468 <https://github.com/Genymobile/scrcpy/issues/468>
PR #3030 <https://github.com/Genymobile/scrcpy/pull/3030>
2 years ago
Romain Vimont 03705b828b Use sc_prefix for fps counter 2 years ago
Romain Vimont 7848a387c8 Do not duplicate relative mouse mode state
The relative mouse mode is tracked by SDL, and accessible via
SDL_GetRelativeMouseMode().

This is more robust in case SDL changes the relative mouse mode on its
own.
2 years ago
Romain Vimont 61b6324ee9 Remove LOGC()
It is not clear when to use LOGC() rather than LOGE(). Always use
LOGE().

Moreover, enum sc_log_level has no "critical" log level.
2 years ago
Romain Vimont 063d103dd6 Capture mouse on start for --hid-mouse
If relative mode is enabled, capture the mouse immediately.
2 years ago
Romain Vimont 4bf9c057fe Extract relative mode check to an inline function
This will allow to reuse the condition in another function.
2 years ago
Romain Vimont 17c97820b2 Never forward capture keys
In relative mode, Alt and Super are "capture keys". Never forward them
to the input manager, to avoid inconsistencies between UP and DOWN
events.
2 years ago
Romain Vimont ac038f276e Add missing break statement
This was harmless because this is the last "case" of the switch, but for
consistency, add the missing break.
2 years ago
Romain Vimont 1f65b1bf87 Remove inline hint
There is no reason to request inlining here.
2 years ago
Romain Vimont 855819bbd8 Remove redundant control boolean
The controller is NULL if and only if control is disabled, so an
additional control boolean is redundant.
2 years ago
Romain Vimont 0ec3361bc9 Fix crash on --no-control
Relative mouse mode assumed that a mouse processor was always available,
but this is not the case if --no-control is passed.
2 years ago
Romain Vimont 1ffe312369 Handle file drop from input_manager
A file is pushed (or an apk is installed) to the device on file drop.
This behavior is specific to the screen and its input_manager.
2 years ago
Romain Vimont ebef027c4f Do not return status for event handling
It is never read. Simplify.
2 years ago
Romain Vimont 75c5dc6859 Position and size the window on first frame
The optimal initial size was computed from the expected dimensions, sent
immediately by the server before encoding any video frame.

However, the actual frame size may be different, for example when the
device encoder does not support the requested size.

To always handle this case properly, position and size the window only
once the first frame size is known.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2 years ago
Romain Vimont fa30f9806a Move "show window" call on first frame
Show the window only after the actual frame size is known (and if no
error has occurred).

This will allow to properly position and size the window when the size
of the first frame is different from the size initially announced by the
server.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2 years ago
Romain Vimont 5f7ddff8ae Use sc_ prefix for input_manager 3 years ago
Romain Vimont 2a0c2e5e99 Use sc_ prefix for screen 3 years ago
Romain Vimont 17d01b5bf7 Add UI/UX support for relative mouse mode
In relative mouse mode, the mouse pointer must be "captured" from the
computer.

Toggle (disable/enable) relative mouse mode using any of the hardcoded
capture keys:
 - left-Alt
 - left-Super
 - right-Super

These capture keys do not conflict with shortcuts, since a shortcut is
always a combination of the MOD key and some other key, while the
capture key triggers an action only if it is pressed and released alone.

The relative mouse mode is also automatically enabled on any click in
the window, and automatically disabled on focus lost (it is possible to
lose focus even without the mouse).
3 years ago
Romain Vimont 6102a0b5bb Move input_manager into screen
The input_manager is strongly tied to the screen, it could not work
independently of the specific screen implementation.

To implement a user-friendly HID mouse behavior, some SDL events
will need to be handled both by the screen and by the input manager. For
example, a click must typically be handled by the input_manager so that
it is forwarded to the device, but in HID mouse mode, the first click
should be handled by the screen to capture the mouse (enable relative
mouse mode).

Make the input_manager a descendant of the screen, so that the screen
decides what to do on SDL events.

Concretely, replace this structure hierarchy:

     +- struct scrcpy
        +- struct input_manager
        +- struct screen

by this one:

     +- struct scrcpy
        +- struct screen
           +- struct input_manager
3 years ago
Romain Vimont 6261bb0b5a Ignore display bounds on resize-to-fit
The "resize to fit" feature (MOD+w or double-click on black borders)
computed the "optimal size" using the same function computing the
initial window size on start.

However, on "resize to fit", only the black borders must be removed (the
content size must be preserved), so the display bounds must not be
considered.
3 years ago
Romain Vimont 2f091beeaa Simplify sc_size assignment
Assign the whole struct instead of each field separately.
3 years ago
Romain Vimont dca2c5f94f Require SDL >= 2.0.5
Icon loading uses SDL_CreateRGBSurfaceWithFormatFrom(), available since
SDL 2.0.5 (in 2016).

Refs #2862 <https://github.com/Genymobile/scrcpy/issues/2862>
3 years ago
Romain Vimont 3653fb6b15 Add OutOfMemory log helper
Add a special LOG_OOM() function to log all OutOfMemory errors (i.e.
allocations returning NULL).
3 years ago
Romain Vimont be55e250ca Make screen_render() static
It is only used from screen.c.
3 years ago
Romain Vimont dae091e3ab Handle SDL_PushEvent() errors
Pushing an event to the main thread may fail. If this happens, log an
error, and try to recover when possible.
3 years ago
Romain Vimont 4c4381de4c Use sc_ prefix for size, position and point 3 years ago
Romain Vimont e4d5c1ce36 Move scrcpy option structs to options.h
This will allow to define symbols in options.c without all the
dependencies of scrcpy.c.
3 years ago
Romain Vimont 6004f0b6b0 Use a new scrcpy icon
Use the new icon designed by @varlesh:
<https://github.com/Genymobile/scrcpy/pull/1987#issuecomment-949684080>

Load it from a PNG file (SDL only supports bitmap icons).
3 years ago
Romain Vimont 3397720330 Add buffering command line options
Add --display-buffer and --v4l2-buffer options to configure buffering
time.
3 years ago
Romain Vimont 79278961b9 Implement buffering
To minimize latency (at the cost of jitter), scrcpy always displays a
frame as soon as it available, without waiting.

However, when recording (--record), it still writes the captured
timestamps to the output file, so that the recorded file can be played
correctly without jitter.

Some real-time use cases might benefit from adding a small latency to
compensate for jitter too. For example, few tens of seconds of latency
for live-streaming are not important, but jitter is noticeable.

Therefore, implement a buffering mechanism (disabled by default) to add
a configurable latency delay.

PR #2417 <https://github.com/Genymobile/scrcpy/issues/2417>
3 years ago
Romain Vimont 408a301201 Notify new frames via callbacks
Currently, a frame is available to the consumer as soon as it is pushed
by the producer (which can detect if the previous frame is skipped).

Notify the new frames (and frame skipped) via callbacks instead.

This paves the way to add (optional) buffering, which will introduce a
delay between the time when the frame is produced and the time it is
available to be consumed.
3 years ago
Romain Vimont 336248df08 Rename video_buffer to sc_video_buffer
Add a scrcpy-specific prefix.
3 years ago
Romain Vimont 9b89b7ab72 Center the window on resize-to-fit
When removing the black borders (by double-clicking on them, or by
pressing MOD+w), the window is resized to fit the device screen, but its
top-left position was left unchanged.

Instead, move the window so that the new window area is at the center of
the old window area.

Refs #2387 <https://github.com/Genymobile/scrcpy/issues/2387>
3 years ago
Romain Vimont 7343b233e4 Render screen on window restored
It should not be necessary, since screen_render() is called just after
on SDL_WINDOWEVENT_EXPOSED, but in practice the window content might not
be correctly displayed on restored if a rotation occurred while
minimized.

Note that calling screen_render() twice in a row on
SDL_WINDOWEVENT_EXPOSED also "fixes" the issue.
3 years ago
Romain Vimont dcee7c0f7f Factorize screen_init() error management 3 years ago
Romain Vimont e604e8a752 Move fps_counter to screen
The FPS counter specifically count frames from the screen video buffer,
so it is specific to the screen.
3 years ago
Romain Vimont f19c455110 Fix leak on error
Destroy video buffer if screen window creation failed.
3 years ago
Romain Vimont 0541f1bff2 Hide the window immediately on close
The screen may not be destroyed immediately on close to avoid undefined
behavior, because it may still receive events from the decoder.

But the visual window must still be closed immediately.
3 years ago
Romain Vimont 0272e6dc77 Assert screen closed on destroy
The destruction order is important, but tricky, because the screen is
open/close by the decoder, but destroyed by scrcpy.c on the main thread.

Add assertions to guarantee that the screen is not destroyed before
being closed.
3 years ago
Romain Vimont 2a94a2b119 Remove video_buffer callbacks
Now that screen is both the owner and the listener of the video buffer,
execute the code directly without callbacks.
3 years ago
Romain Vimont e91acdb0c4 Move video_buffer to screen
The video buffer is now an internal detail of the screen component.

Since the screen is plugged to the decoder via the frame sink trait, the
decoder does not access to the video buffer anymore.
3 years ago
Romain Vimont 08b3086ffc Expose screen as frame sink
Make screen implement the frame sink trait.

This will allow the decoder to push frames without depending on the
concrete sink type.
3 years ago
Romain Vimont 2ddf760c09 Make video_buffer more generic
The video buffer took ownership of the producer frame (so that it could
swap frames quickly).

In order to support multiple sinks plugged to the decoder, the decoded
frame must not be consumed by the display video buffer.

Therefore, move the producer and consumer frames out of the video
buffer, and use FFmpeg AVFrame refcounting to share ownership while
avoiding copies.
3 years ago
Romain Vimont c23c38f99d Move resizing workaround to screen.c 3 years ago
Romain Vimont 65c4f487b3 Set initial fullscreen from screen.c 3 years ago