Commit graph

149 commits

Author SHA1 Message Date
Romain Vimont
73c332e3e4 Unref last packet on exit 2018-03-23 13:57:32 +01:00
Romain Vimont
f00c6c5b13 Disable custom SDL signal handlers
Request SDL not to replace the SIGINT and SIGTERM handlers, so that the
process is immediately terminated on Ctrl+C.

This avoids process hanging on Ctrl+C during network calls on
initialization.

Some of them accepted a timeout, but it was not used since
commit 9b056f5091 anymore.
2018-03-21 21:43:12 +01:00
Romain Vimont
3b3803da0d Remove useless blocks in switch/case
Remove unnecessary additional blocks.
2018-03-21 11:14:15 +01:00
Romain Vimont
f5cf6c1b2c Include source root directory
All headers and sources are in src/. To avoid using relative includes
from subdirectories ("../../"), include the source root directory.
2018-03-20 21:32:41 +01:00
Romain Vimont
c65cb36d3b Increase the number of connection attempts
In "adb forward" mode, it may take a while before the server socket is
listening, so increase the number of connection attempts.

See <https://github.com/Genymobile/scrcpy/issues/5#issuecomment-373718551>.
2018-03-16 14:59:08 +01:00
Romain Vimont
821ec9843c Fix win32 build
The types size_t and ssize_t are defined on Windows (in MSYS2), so there
is no need to typedef SIZE_T and SSIZE_T.

Exit code is "unsigned long" both on Windows 32 and 64 bits.

See <https://github.com/Genymobile/scrcpy/issues/46#issuecomment-373603596>.
2018-03-16 08:58:59 +01:00
Romain Vimont
f16bd88802 Remove useless cast
For consistency with mouse button events handling, directly assign from
Sint32 to Uint16.
2018-03-15 16:30:51 +01:00
Romain Vimont
f3e8834a3c Fix warning message
Mouse "wheel button" is meaningless :)
2018-03-15 16:14:40 +01:00
Romain Vimont
080df5eb5d Fix switch/case code style
For readability and consistency, indent case statatements, and remove
unnecessary additional blocks.
2018-03-15 16:00:40 +01:00
Romain Vimont
f7bc0bd5b5 Merge branch 'dev' into release 2018-03-14 09:33:53 +01:00
Romain Vimont
8a3c6a3ae7 Remove useless argument
Do not pass any data to the event watcher, it is unused.
2018-03-14 09:32:05 +01:00
Romain Vimont
0b1e59186f Workaround continuous resizing on Windows/MacOS
On Windows and MacOS, resizing blocks the event loop, so resizing events
are not triggered:
 - <https://bugzilla.libsdl.org/show_bug.cgi?id=2077>
 - <https://stackoverflow.com/a/40693139/1987178>

As a workaround, register an event watcher to render the screen from
another thread.

Since the whole event loop is blocked during resizing, the screen
content is not refreshed (on Windows and MacOS) until resizing ends.
2018-03-13 22:48:04 +01:00
Romain Vimont
e69f6f710d Disable stdout/stderr buffering on Windows
In MSYS2 on Windows, the output is buffered by default. Disable
buffering to print output immediately.

Note that in cmd.exe, it still prints nothing.
2018-03-13 10:20:09 +01:00
Romain Vimont
b858204786 Remove black borders on double-click
Resize the window to fit the device screen on click on black borders
(same as Ctrl+x).

Suggested-by: Guillaume Roche <groche@genymobile.com>
2018-03-13 08:37:46 +01:00
Romain Vimont
1038bad385 Make it work over tcpip
"adb reverse" currently does not work over tcpip (i.e. on a device
connected by "adb connect"):
<https://issuetracker.google.com/issues/37066218>

To work around the problem, if the call to "adb reverse" fails, then
fallback to "adb forward", and reverse the client/server roles.

Keep the "adb reverse" mode as the default because it does not involve
connection retries: when using "adb forward", the client must try to
connect successively until the server listens.

Due to the tunnel, every connect() will succeed, so the client must
attempt to read() to detect a connection failure. For this purpose, when
using the "adb forward" mode, the server initially writes a dummy byte,
read by the client.

Fixes <https://github.com/Genymobile/scrcpy/issues/5>.
2018-03-12 14:10:32 +01:00
Romain Vimont
2b3ed5bcdb Store serial in server instance
The serial is needed for many server actions, but this is an
implementation detail, so the caller should not have to provide it on
every call.

Instead, store the serial in the server instance on server_start().

This paves the way to implement the "adb forward" fallback properly.
2018-03-12 14:10:32 +01:00
Romain Vimont
9e328ef98b Always use the best render scale quality available
Because why not.

See <https://wiki.libsdl.org/SDL_HINT_RENDER_SCALE_QUALITY>.
2018-03-12 14:10:12 +01:00
Romain Vimont
f9a63ec272 Reverse horizontal scrolling behavior
The SDL mouse wheel event seems inconsistent between horizontal and
vertical scrolling.

> Movements to the left generate negative x values and to the right
> generate positive x values. Movements down (scroll backward) generate
> negative y values and up (scroll forward) generate positive y values.

<https://wiki.libsdl.org/SDL_MouseWheelEvent#Remarks>

Reverse the horizontal.

Fixes <https://github.com/Genymobile/scrcpy/issues/49>.
2018-03-12 09:37:46 +01:00
Romain Vimont
c87d94ee27 Map middle-click to HOME
Middle-click is useless in practice. Use it for HOME.
2018-03-10 00:44:19 +01:00
Romain Vimont
675704c71c Map right-click to BACK if screen is on
Right-click was used to turn the screen on. It did nothing when the
screen was already on.

Instead, in that case, press BACK (like Vysor).

Suggested by: <https://www.reddit.com/r/Android/comments/834zmr/introducing_scrcpy_an_app_to_display_and_control/dvfueft/>
2018-03-10 00:16:29 +01:00
Romain Vimont
9396ea6d42 Fix text input event segfault
The text input control_event was initially designed for mapping
SDL_TextInputEvent, limited to 32 characters.

For simplicity, the copy/paste feature was implemented using the same
control_event: it just sends the text to paste.

However, the pasted text might have a length breaking some assumptions:
 - on the client, the event max-size was smaller than the text
   max-length,
 - on the server, the raw buffer storing the events was smaller than the
   max event size.

Fix these inconsistencies, and encode the length on 2 bytes, to accept
more than 256 characters.

Fixes <https://github.com/Genymobile/scrcpy/issues/10>.
2018-03-09 22:30:10 +01:00
Romain Vimont
f9562f537a Unref the packet on error
Do not leak the packet data on error.
2018-03-08 21:36:04 +01:00
Romain Vimont
a34fbd23e9 Do not leak the packet data
Oops! The content of the packets were never freed.
2018-03-08 20:46:02 +01:00
Romain Vimont
e2a7abcd53 Implement clipboard paste
Paste computer clipboard to the device on Ctrl+v.

The other direction (pasting the device clipboard to the computer) is
not implemented. It would require a communication channel from the
device to the computer, other than the socket used by the video stream.
2018-03-07 18:07:02 +01:00
Romain Vimont
e4d64e8752 Initialize struct field by field
Initializing with braces initializes the other fields to 0, which is not
necessary.
2018-03-07 18:07:02 +01:00
Romain Vimont
fffeedffda Expose High DPI support configuration flag
The High DPI support is enabled by default, so that the renderer use the
full definition of High DPI screens.

However, there are still mouse coordinates problems on some MacOS having
High DPI support (but not all), so expose a way to disable it.
2018-03-07 18:07:02 +01:00
Romain Vimont
82b4acee73 Do not fail on EAGAIN
A call to avcodec_receive_frame() may return AVERROR(EAGAIN) if more
input is required. This is not an error, do not fail.
2018-03-07 18:07:02 +01:00
Romain Vimont
ab780ce26d Avoid useless variables initialization
Initialize variables only when necessary.
2018-03-07 18:07:02 +01:00
Romain Vimont
84ad6633a6 Move the new avcodec implementation before the old
The API to decode the video frames is different depending on the
libavcodec version.

Move the new API usage to the #if-block.
2018-03-07 18:07:01 +01:00
Romain Vimont
1b0cea61a5 Do not use return code for thread run function
The decoder sometimes returned a non-zero value on error, but not on
every path.

Since we never use the value, always return 0 at the end (like in the
controller).
2018-03-07 18:07:01 +01:00
Romain Vimont
42f6341a14 Revert "Enable high dpi support"
Just enabling this flag breaks mouse location values.

This reverts commit 38b56f552e.
2018-03-07 18:06:43 +01:00
Romain Vimont
acd2dc3183 Shutdown sockets before closing
The server socket does not release the port it was listening for if we
just close it: we must also shutdown it.
2018-03-07 18:04:39 +01:00
Romain Vimont
db396f2138 Fix scroll wheel mouse position
SDL_MouseWheelEvent does not provide the mouse location, so we used
SDL_GetMouseState() to retrieve it.

Unfortunately, SDL_GetMouseState() returns a position expressed in the
window coordinate system while the position filled in SDL events are
expressed in the renderer coordinate system. As a consequence, the
scroll was not applied at the right position on the device.

Therefore, convert the coordinate system.

See <https://stackoverflow.com/questions/49111054/how-to-get-mouse-position-on-mouse-wheel-event>.
2018-03-07 18:04:39 +01:00
Romain Vimont
e6feb991db Fix comment typo
Replace "at network level" by "at the network level".
2018-03-07 18:04:38 +01:00
Romain Vimont
38b56f552e Enable high dpi support
Use high DPI if available.

Note that on Mac OS X, setting this flag is not sufficient:

> On Apple's OS X you must set the NSHighResolutionCapable Info.plist
> property to YES, otherwise you will not receive a High DPI OpenGL
> display.

<https://wiki.libsdl.org/SDL_CreateWindow#flags>
2018-03-07 18:04:38 +01:00
Romain Vimont
c78ad6377c Terminate the server on stop
On user request to quit, two kinds of blocking calls must be interrupted
on the server:
 1. the reads from and writes to the socket;
 2. the call to MediaCodec.dequeueOutputBuffer().

The former case was handled by calling shutdown() on the socket from the
client, but the latter was not managed.

There is no easy way to wake this call properly, so just terminate the
process from the client (i.e. send SIGTERM on Linux) instead.
2018-02-28 16:56:20 +01:00
Romain Vimont
221a7d0826 Clean up the server from temporary folder
The server is copied to /data/local/tmp/scrcpy-server.jar and executed
on the device.

As soon as we are connected, we can unlink (rm) it from /data/local/tmp,
to keep the device clean.
2018-02-28 15:27:45 +01:00
Romain Vimont
08d32e3bae Clean up useless const-casts
The function adb_execute() now expects a "const char *const *" parameter
for the adb command, so there is no need to cast.
2018-02-28 15:05:49 +01:00
Romain Vimont
487cb10cf0 Rename ScrCpyServer to Server
The Server class is in package scrcpy, there is no need to repeat the
name in the classname.
2018-02-28 14:57:18 +01:00
Romain Vimont
089378926b Rename SCRCPY_SERVER_JAR to SCRCPY_SERVER_PATH
The server is currently a JAR, but it may ba an APK or a DEX, so the
variable name should not contain the type.

Rename the environment variable, the Meson options and the C
definitions.
2018-02-16 15:36:25 +01:00
Romain Vimont
60f3185185 Reuse server address
Set SO_REUSEADDR flag to server socket, so that bind() does not fail if
we restart scrcpy immediately after we closed the previous one.
2018-02-16 15:36:25 +01:00
Romain Vimont
6db22ef339 Log socket errors
Do not silently ignore close() and shutdown() errors, and use perror()
to get the errno.
2018-02-16 15:03:50 +01:00
Romain Vimont
ad6209f6ff Terminate the device process gracefully
Call shutdown() on the device socket to make the device process finish
its execution quickly and gracefully, without killing it.
2018-02-16 11:47:42 +01:00
Romain Vimont
a791c272bc Send and recv all data when necessary
Expose net_recv_all() and net_send_all(), equivalent of net_recv() and
net_send(), but that waits/retries until the requested length has been
transferred.

Use these new functions where it was (wrongly) assumed that the
requested length had been transferred.
2018-02-16 00:57:48 +01:00
Romain Vimont
d646f95a31 Avoid division by 0
If the frame_size width or height is 0, just return the current size to
avoid calculations involving divison by 0.
2018-02-16 00:57:48 +01:00
Romain Vimont
27b9159b07 Cleanup old code comment 2018-02-16 00:57:48 +01:00
Romain Vimont
cf59d49d25 Detect failure of device information read
If the received data is smaller than the device information size, then
something is wrong.
2018-02-16 00:57:47 +01:00
Romain Vimont
9b056f5091 Replace SDL_net by custom implementation
SDL_net is not very suitable for scrcpy.

For example, SDLNet_TCP_Accept() is non-blocking, so we have to wrap it
by calling many SDL_Net-specific functions to make it blocking.

But above all, SDLNet_TCP_Open() is a server socket only when no IP is
provided; otherwise, it's a client socket. Therefore, it is not possible
to create a server socket bound to localhost, so it accepts connections
from anywhere.

This is a problem for scrcpy, because on start, the application listens
for nearly 1 second until it accepts the first connection, supposedly
from the device. If someone on the local network manages to connect to
the server socket first, then they can stream arbitrary H.264 video.
This may be troublesome, for example during a public presentation ;-)

Provide our own simplified API (net.h) instead, implemented for the
different platforms.
2018-02-16 00:56:58 +01:00
Romain Vimont
bf41e5479b Improve decoder stopped event
The syntax was correct, but less readable, and it unnecessarily zeroed
the fields other than "type".

Create the event properly, from a separate method.
2018-02-15 22:59:04 +01:00
Romain Vimont
518d6d5dcd Prevent new window opening with CreateProcess()
Executing commands (like "adb push") created a new terminal window on
Windows. Avoid it.
2018-02-15 22:42:37 +01:00