Commit graph

415 commits

Author SHA1 Message Date
Romain Vimont
eb34098add Simplify portable build configuration
To create a portable build (with scrcpy-server.jar accessible from the
scrcpy directory), replace OVERRIDE_SERVER_PATH by a simple compilation
flag: PORTABLE.

This paves the way to use more complex rules to determine the path of
scrcpy-server.jar in portable builds.
2019-06-11 17:44:07 +02:00
Romain Vimont
b777760bca Simplify scrcpy-server path configuration
The full path of scrcpy-server.jar was partially configured from
meson.build then concatenated by C code.

Instead, directly write the path in C.
2019-06-11 17:44:07 +02:00
Romain Vimont
72bdfbc7a6 Never return 0 for stream protocol
On socket disconnection, on Linux, recv() returns -1 and errno is set.
But on Windows, errno is 0.

In that case, AVERROR(errno) == 0, leading to the warning:

> Invalid return value 0 for stream protocol

To avoid the problem, if errno is 0, return AVERROR_EOF.

Ref: commit 2876463d39
2019-06-11 17:44:07 +02:00
Romain Vimont
5d11339259 Inline lock_util functions
They are just tiny wrappers.
2019-06-07 17:19:00 +02:00
Romain Vimont
e2a272bf99 Improve framerate counting
The FPS counter was called only on new frames, so it could not print
values regularly, especially when there are very few FPS (when the
device surface does not change).

To the extreme, it was never able to display 0 fps.

Add a separate thread to print framerate every second.
2019-06-07 17:16:26 +02:00
Romain Vimont
d104d3bda9 Add cond_wait_timeout()
Add a "timed out" version of cond_wait().
2019-06-07 16:54:31 +02:00
Romain Vimont
eda44b6068 Fix controller cleanup
After commit bfb86ca2c2, the controller
was not stopped and destroyed on quit.
2019-06-07 00:03:21 +02:00
Romain Vimont
ebccb9f6cc Add runtime option to render expired frames
Replace the compilation flag SKIP_FRAMES by a runtime flag to force
rendering of expired frames. By default, the expired frames are skipped.
2019-06-05 21:39:42 +02:00
Romain Vimont
a143b8b07a Indent command-line options
Prepare indentation for --render-expired-frames.
2019-06-05 19:02:42 +02:00
Romain Vimont
8e66b33000 Add option to turn device screen off
In addition to the shortcut (Ctrl+o) to turn the device screen off, add
a command-line argument to turn it off on start.
2019-06-05 00:55:46 +02:00
Romain Vimont
7f07b13446 Indent command-line options
Preparse indentation for --turn-screen-off.
2019-06-05 00:55:39 +02:00
Romain Vimont
acc4dcd520 Disable server controller if --no-control
If --no-control is disabled, there is no need for a controller.

It also avoids to power on the device on start if control is disabled.
2019-06-05 00:25:57 +02:00
Romain Vimont
ca767ba364 Group server params in a struct
Starting the server requires more and more parameters. For clarity,
group them in a struct.
2019-06-05 00:25:57 +02:00
Romain Vimont
c8a6783494 Use positive options names internally
For clarity, store the flag resulting of the command-line options
--no-control and --no-display into "control" and "display".
2019-06-05 00:25:15 +02:00
Romain Vimont
5b56900e2b Rename unused field
The flag is used only in the server_start() implementation, there is no
need to store it in the structure.
2019-06-04 21:29:14 +02:00
Romain Vimont
8c8649cfcd Remove "turn device screen on" feature
Only keep "turn device screen off" and POWER button.

After we turn the device screen off (with Ctrl+o), turning it back on
does not always work, and leaves the device in a weird state, where even
the power button may not be sufficient:
<https://github.com/Genymobile/scrcpy/issues/175#issuecomment-497946596>

This is not an acceptable behavior, so disable the shortcut to turn the
physical device screen on. We can use the POWER button (or Ctrl+p)
instead.
2019-06-03 11:44:39 +02:00
Romain Vimont
41225c3e41 Improve key processing readability
The condition "event->type == SDL_KEYDOWN" and the variable
input_manager->controller are used many times. Replace them by local
variables to reduce verbosity.
2019-06-01 07:18:05 +02:00
Romain Vimont
296047d82a Use net_close() to close sockets
So that it also works on Windows.
2019-05-31 23:33:44 +02:00
Romain Vimont
12a3bb25d3 Implement device screen off while mirroring
Add two shortcuts:
 - Ctrl+o to turn the device screen off while mirroring
 - Ctrl+Shift+o to turn it back on

On power on (either via the POWER key or BACK while screen is off), both
the device screen and the mirror are turned on.

<https://github.com/Genymobile/scrcpy/issues/175>
2019-05-31 23:07:23 +02:00
Romain Vimont
3ee9560ece Fix comment style
For consistency.
2019-05-31 22:57:12 +02:00
Yu-Chen Lin
a56045dd80 Prevent socket leak on error
Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-31 22:24:31 +02:00
Yu-Chen Lin
fcf225049d Use consistent variable names
Use the same variable name in functions declaration and definition.

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-31 22:24:17 +02:00
Romain Vimont
6537c2ef01 Add clipboard logs
Synchronizing local and device clipboards in invisible. Add INFO logs
on success.
2019-05-31 16:18:00 +02:00
Romain Vimont
9712cb8123 Do not minimize on focus loss
The default behavior seems annoying.

Fixes <https://github.com/Genymobile/scrcpy/issues/554>
2019-05-31 16:18:00 +02:00
Romain Vimont
28980bbc90 Rename "event" to "message"
After the recent refactorings, a "control event" is not necessarily an
"event" (it may be a "command"). Similarly, the unique "device event"
used to send the device clipboard content is more a "reponse" to the
request from the client than an "event".

Rename both to "message", and rename the message types to better
describe their intent.
2019-05-31 16:18:00 +02:00
Yu-Chen Lin
2a8a3e6ed5 Correct return value type in handle_event
handle_event return the type enum event_result not bool

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
2019-05-31 20:57:06 +08:00
Romain Vimont
c13a24389c Implement computer-to-device clipboard copy
It was already possible to _paste_ (with Ctrl+v) the content of the
computer clipboard on the device. Technically, it injects a sequence of
events to generate the text.

Add a new feature (Ctrl+Shift+v) to copy to the device clipboard
instead, without injecting the content. Contrary to events injection,
this preserves the UTF-8 content exactly, so the text is not broken by
special characters.

<https://github.com/Genymobile/scrcpy/issues/413>
2019-05-30 22:46:52 +02:00
Romain Vimont
63c078ee6c Implement device-to-computer clipboard copy
On Ctrl+C:
 - the client sends a GET_CLIPBOARD command to the device;
 - the device retrieve its current clipboard text and sends it in a
   GET_CLIPBOARD device event;
 - the client sets this text as the system clipboard text, so that it
   can be pasted in another application.

Fixes <https://github.com/Genymobile/scrcpy/issues/145>
2019-05-30 22:46:52 +02:00
Romain Vimont
6112095e75 Add device event receiver
Create a separate component to handle device events, managed by the
controller.
2019-05-30 22:46:52 +02:00
Romain Vimont
f9d2d99166 Add GET_CLIPBOARD device event
Add the first device event, used to forward the device clipboard to the
computer.
2019-05-30 22:36:22 +02:00
Romain Vimont
ec71a3f66a Use two sockets for video and control
The socket used the device-to-computer direction to stream the video and
the computer-to-device direction to send control events.

Some features, like copy-paste from device to computer, require to send
non-video data from the device to the computer.

To make them possible, use two sockets:
 - one for streaming the video from the device to the client;
 - one for control/events in both directions.
2019-05-30 22:35:41 +02:00
Romain Vimont
69360c7407 Extract control event string serialization
A string is serialized as a length (2 bytes) followed by the string data
(non nul-terminated).

For now, it is used only once, but we will need to serialize strings in
other events.
2019-05-30 22:35:04 +02:00
Romain Vimont
6ec2ddd2d1 Truncate UTF-8 properly
This will avoid to produce invalid UTF-8 results (although unlikely).
2019-05-30 22:34:59 +02:00
Romain Vimont
0a7fe7ad57 Add helpers to truncate UTF-8 at code points
This will help to avoid truncating a UTF-8 string in the middle of a
code point, producing an invalid UTF-8 result.
2019-05-30 22:30:18 +02:00
Romain Vimont
3aa5426cad Add unit tests for control events serialization
Add missing tests for serialization and deserialization of control
events.
2019-05-30 22:30:18 +02:00
Romain Vimont
63207d9cd5 Fix wrong comment in unit test 2019-05-30 22:30:18 +02:00
Romain Vimont
63909fd10d Merge commands with other control events
Several commands were grouped under the same event type "command", with
a separate field to indicate the actual command.

Move these commands at the same level as other control events. It will
allow to implement commands with arguments.
2019-05-30 22:30:18 +02:00
Romain Vimont
3b4366e5bf Stop stream immediately on quit
If the stream is stopped, av_read_frame() will be woken up and yield a
corrupted packet. Do not try to decode or record it.
2019-05-30 22:30:18 +02:00
Romain Vimont
47f1003200 Close server socket before killing process
The sockets may be closed and shutdown on server_stop(). This will
interrupt the stream and controller threads more quickly and gracefully.
2019-05-30 22:30:18 +02:00
Romain Vimont
bfb86ca2c2 Simplify cleanup
The cleanup is not linear: for example, the server must be stopped and
its sockets must be shutdown after the stream and controller are stopped
(so that they don't continue processing garbage), but before they are
joined, to avoid a deadlock if they are blocked on a socket read.

Simplify the spaghetti-cleanup by keeping trace of initialization at
runtime.
2019-05-30 22:30:18 +02:00
Romain Vimont
0dee9b04b2 Use net_recv() to read only one byte
Partial read is impossible for 1 byte, so net_recv_all() is useless.
2019-05-30 22:30:18 +02:00
Romain Vimont
8fc58bde75 Simplify server_connect_to()
Only use 2 branches, using either forward or remote tunnel.
2019-05-30 22:30:18 +02:00
Romain Vimont
5a431cdf9b Make server_connect_to() return a bool
The resulting socket is accessible from the server instance, there is no
need to return it.

This paves the way to use several sockets in parallel.
2019-05-30 22:30:18 +02:00
Romain Vimont
6edb1294f0 Add missing return 0 in unit test 2019-05-30 22:30:18 +02:00
Romain Vimont
073181b294 Use cbuf for file handler request queue
Replace the file_handler_request_queue implementation by cbuf.
2019-05-30 22:30:18 +02:00
Romain Vimont
241a3dcba5 Use cbuf for control event queue
Replace the control_event_queue implementation by cbuf.
2019-05-30 22:30:18 +02:00
Romain Vimont
b38292cd69 Add generic circular buffer
Add a circular buffer implementation, to factorize multiple specific
queues implementation.
2019-05-30 22:30:18 +02:00
Romain Vimont
7475550ae8 Add buffer_read16be()
Add a function to read 16 bits in big-endian to a uint16_t.
2019-05-30 22:30:18 +02:00
Romain Vimont
7fc8793d5b Make buffer util functions accept const buffers
So that they can be used both on const and non-const input buffers.
2019-05-30 22:30:18 +02:00
Romain Vimont
bf5e54b2e9 Make control_event_serialize() return size_t
control_event_serialize() returns the number of bytes written, so the
type should be size_t.
2019-05-30 22:30:18 +02:00
Romain Vimont
507b0bcccf Fix memory leak on error
The variable condition was not destroyed on strdup() failure.
2019-05-30 22:30:18 +02:00
Romain Vimont
e1afd9f8b0 Fix event ownership comment 2019-05-30 22:30:18 +02:00
Romain Vimont
b08dada6c1 Prefix control event constants by namespace
This will avoid conflicts with future device events.
2019-05-30 22:30:18 +02:00
Romain Vimont
999c964689 Make macro expansion-safe
Use parentheses to avoid unexpected results.

For example, make:

    2 * SERIALIZED_EVENT_MAX_SIZE

expand to:

    2 * (3 + TEXT_MAX_LENGTH)

instead of:

    2 * 3 + TEXT_MAX_LENGTH
2019-05-30 22:30:18 +02:00
Romain Vimont
befe455e44 Remove unused includes
The struct control_event does not use mutexes, and net.h does not need
SDL_platform.h.
2019-05-30 22:30:18 +02:00
Romain Vimont
d2504f974c Fix indentation
Previous refactorings broke indentation.
2019-05-30 22:30:18 +02:00
Romain Vimont
0fbab42f8c Format meson.build for readability 2019-05-30 22:30:18 +02:00
Romain Vimont
08f506b24f Replace SDL_bool by bool in tests
Commit dfed1b250e replaced SDL types by
standard types in sources, but tests were not updated.
2019-05-30 22:30:18 +02:00
Romain Vimont
3bc1c51b91 Always use SDL_malloc() and SDL_free()
To avoid mixing SDL_malloc()/SDL_strdup() with free(), or malloc() with
SDL_free(), always use the SDL version.
2019-05-30 22:30:08 +02:00
Romain Vimont
5d473efeb5 Bind Home key to MOVE_HOME
On pressing Home key on the computer, move the cursor to the beginning
of the line instead of going back to the home screen.

<https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME>
<https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_MOVE_HOME>

Fixes (part of) <https://github.com/Genymobile/scrcpy/issues/555>.
2019-05-27 10:24:47 +02:00
Romain Vimont
a41dd6c79f Make owned filename a pointer-to-non-const
The file handler owns the filename string, so it needs to free it.
Therefore, it should not be a pointer-to-const.
2019-05-24 17:25:31 +02:00
Romain Vimont
c3779d8513 Make owned serial a pointer-to-non-const
The file handler owns the serial, so it needs to free it. Therefore, it
should not be a pointer-to-const.
2019-05-24 17:24:17 +02:00
Romain Vimont
b3bd5f1b80 Remove useless casts to (void *) 2019-05-24 17:23:21 +02:00
Romain Vimont
3133d5d1c7 Continue on icon loading failure
If loading the icon from xpm fails, launch scrcpy without window icon.

<https://github.com/Genymobile/scrcpy/issues/539>
2019-05-23 20:58:08 +02:00
Romain Vimont
2dc1a59471 Check surface returned for icon
SDL_CreateRGBSurfaceFrom() may return NULL, causing a segfault.

<https://github.com/Genymobile/scrcpy/issues/539>
2019-05-20 09:44:45 +02:00
Romain Vimont
e443518ed9 Print adb command on error
When the execution of an adb command fails, print the command. This will
help to understand what went wrong.

See <https://github.com/Genymobile/scrcpy/issues/530>.
2019-05-12 15:16:13 +02:00
Romain Vimont
eeb8e8420f Use size_t for command length
The size of an array should have type size_t.
2019-05-12 14:31:18 +02:00
Sebastian Krzyszkowiak
b941854c73 Disable X11 compositor bypass
Compositor bypass is meant for fullscreen games consuming lots of GPU
resources. For a light app that will usually be windowed, this only
causes unnecessary compositor suspends, especially visible (and
annoying) with complying window manager like KWin.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-05 17:35:00 +02:00
Sebastian Krzyszkowiak
068253a3a2 Fix mouse focus clickthrough
Mouse focus clickthrough didn't work due to compat.h header not being
included in scrcpy.c.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-05 17:28:25 +02:00
Gerdal
ffa8c66979 Fix link error on Windows Subsystem for Linux
Build failed on WSL because of lack of reference to WinMain@16 during
linking.

Fixes <https://github.com/Genymobile/scrcpy/issues/316>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-03-31 20:07:07 +02:00
Romain Vimont
e2ef39fae5 Fix overflow in test
The serialized text is not nul-terminated (its size is explicitely
provided), but the input text in the event is a nul-terminated string.

The test was failing with ASAN enabled.
2019-03-25 11:33:32 +01:00
Romain Vimont
50dac2eaee Log "new texture" at INFO level
The "initial texture" is logged at INFO level. For consistency, log "new
texture" at the same level.
2019-03-07 20:18:03 +01:00
Romain Vimont
a7b3901c31 Add more consts
Some decoder and recorder functions must not write to AVCodec and
AVPacket.
2019-03-03 12:02:41 +01:00
Romain Vimont
f7efafd846 Explicitly pass control flag to input manager
Replace the "global" control flag in the input_manager by a function
parameter to make explicit that the behavior depends whether
--no-control has been set.
2019-03-03 11:05:26 +01:00
Romain Vimont
6baed8a06f Do not init SDL video subsystem if no display
The SDL video subsystem is not necessary if we don't display the video.

Move the sdl_init_and_configure() function from screen.c to scrcpy.c,
because it is not only related to the screen display.
2019-03-03 01:41:35 +01:00
Romain Vimont
8595862005 Use explicit output parameter for skipped frame
The function video_buffer_offer_decoded_frame() returned a bool to
indicate whether the previous frame had been consumed.

This was confusing, because we could expect the returned bool report
whether the action succeeded.

Make the semantic explicit by using an output parameter.

Also revert the flag (report if the frame has been skipped instead of
consumed) to avoid confusion for the first frame (the previous is
neither skipped nor consumed because there is no previous frame).
2019-03-03 00:35:20 +01:00
Romain Vimont
9ef345fdd0 Make owned serial a pointer-to-non-const
The server owns the serial, so it needs to free it. Therefore, it should
not be a pointer-to-const.
2019-03-03 00:01:16 +01:00
Romain Vimont
dfed1b250e Replace SDL types by C99 standard types
Scrcpy is a C11 project. Use the C99 standard types instead of the
SDL-specific types:

    SDL_bool -> bool
    SintXX   -> intXX_t
    UintXX   -> uintXX_t
2019-03-02 23:55:23 +01:00
Romain Vimont
8655ba7197 Add option to mirror in read-only
Add an option to disable device control: -n/--no-control.
2019-03-02 23:10:21 +01:00
Romain Vimont
163cd36ccc Rename -n/--no-window to -N/--no-display
The description of scrcpy is "Display and control your Android device".
We want an option to disable display, another one to disable control.

For naming consistency, name it --no-display.

Also change the shortname to -N, so that we can use -n for --no-control
later.
2019-03-02 22:46:46 +01:00
Romain Vimont
db6644f1f9 Add missing no_window initialization
Initialize the field no_window in "struct args"
2019-03-02 22:42:28 +01:00
Romain Vimont
36191b7eec Avoid unnecessary call if display is disabled
If --no-window is passed, there is no need to register an event watcher.
2019-03-02 21:51:07 +01:00
Romain Vimont
33ccb1368f Extract event processing out of event_loop()
To avoid too many levels of nested blocks, move the event handling logic
in a separate function.
2019-03-02 21:51:07 +01:00
Romain Vimont
aeda583a2c Update code style
Limit source code to 80 chars, and declare functions return type and
modifiers on a separate line.

This allows to avoid very long lines, and all function names are
aligned.

(We do this on VLC, and I like it.)
2019-03-02 20:28:46 +01:00
Romain Vimont
b2fe005498 Replace uint64_t by Uint64 for consistency
The field pts is declared Uint64 in struct frame_meta.
2019-03-02 20:10:34 +01:00
Romain Vimont
89812e4eee Implement the --no-window flag
Disable decoder, screen (display), file_handler and controller when
--no-window is requested.

<https://github.com/Genymobile/scrcpy/pull/418>
2019-03-02 18:45:56 +01:00
CapsLock
421a1141e2 Add a new option: -n/--no-window
This option will allow scrcpy to record the stream without display.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-03-02 18:45:56 +01:00
Romain Vimont
e6e011baaf Add stream layer
The decoder initially read from the socket, decoded the video and sent
the decoded frames to the screen:

              +---------+      +----------+
  socket ---> | decoder | ---> |  screen  |
              +---------+      +----------+

The design was simple, but the decoder had several responsabilities.

Then we added the recording feature, so we added a recorder, which
reused the packets received from the socket managed by the decoder:

                                    +----------+
                               ---> |  screen  |
              +---------+     /     +----------+
  socket ---> | decoder | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This lack of separation of concerns now have concrete implications: we
could not (properly) disable the decoder/display to only record the
video.

Therefore, split the decoder to extract the stream:

                                    +----------+      +----------+
                               ---> | decoder  | ---> |  screen  |
              +---------+     /     +----------+      +----------+
  socket ---> | stream  | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This will allow to record the stream without decoding the video.
2019-03-02 18:45:45 +01:00
Romain Vimont
e7b7b083aa Store the recording request in a local bool
This avoids to test explicitly whether options->record_filename is NULL.
2019-03-02 18:21:20 +01:00
Romain Vimont
8aeb5c0e3c Fix cleanup order
The order of cleanup was not the reverse as the initialization order. As
a consequence, recorder_destroy() could theoretically be called even if
recorder_init() failed.
2019-03-02 18:13:11 +01:00
Romain Vimont
bcd4090d51 Fix recording with old decoding/encoding API
The deprecated avcodec_decode_video2() should always the whole packet,
so there is no need to loop (cf doc/examples/demuxing_decoding.c in
FFmpeg).

This hack changed the packet size and data pointer. This broke recording
which used the same packet.
2019-03-02 17:03:15 +01:00
Romain Vimont
84270e2d18 Rename "stop" to "interrupt"
The purpose of video_buffer_stop() is to interrupt any blocking call, so
rename it to video_buffer_interrupt().
2019-03-02 17:03:15 +01:00
Romain Vimont
fff87095d9 Rename "frames" to "video_buffer"
It better describes the purpose of the structure.
2019-03-02 15:24:33 +01:00
Romain Vimont
aacb09a3d6 Remove unused mutex field in decoder 2019-03-02 14:48:34 +01:00
Romain Vimont
7d10ec2b5a Add shortcut to expand/collapse notification panel
Use Ctrl+n to expand, Ctrl+Shift+n to collapse.

Fixes <https://github.com/Genymobile/scrcpy/issues/392>
2019-02-26 20:35:37 +01:00
Romain Vimont
1c1fe5ec53 Use "always on top" only for SDL >= 2.0.5
The flag SDL_WINDOW_ALWAYS_ON_TOP is available since SDL 2.0.5.

Do not use it if SDL is older, to fix compilation failure.

Fixes <https://github.com/Genymobile/scrcpy/issues/432>
2019-02-16 15:28:56 +01:00
Romain Vimont
751600a7f9 Move all compat ifdefs definitions to compat.h
This allows to give a proper name to features requirements.
2019-02-16 15:28:56 +01:00
Romain Vimont
f5f4e6b1c5 Allocate extradata with av_malloc()
The extradata buffer is owned by libav, so it must be allocated with
av_malloc(), not SDL_malloc().

This fixes a crash on Windows during avformat_free_context().
2019-02-16 00:53:12 +01:00
Romain Vimont
6c40dbd27d Regroup Windows-ifdefs in command.h 2019-02-10 14:33:59 +01:00
Romain Vimont
477c0a2cab Create process with wide chars on Windows
Windows does not support UTF-8, so pushing a file with non-ASCII
characters failed.

Convert the UTF-8 command line to a wide characters string and call
CreateProcessW().

Fixes <https://github.com/Genymobile/scrcpy/issues/422>
2019-02-10 13:08:28 +01:00