Compare commits

..

2 Commits

Author SHA1 Message Date
1ddf289d82 Enable close-on-interrupt for macOS
This behavior is also necessary on macOS.

TODO ref 5536
2024-11-27 10:19:34 +01:00
bf7c7d8038 Split network macro conditions
On Windows, interrupting a socket with shutdown() does not wake up
accept() or read() calls, the socket must be closed.

Introduce a new macro constant SC_SOCKET_CLOSE_ON_INTERRUPT, distinct of
_WIN32, because Windows will not be the only platform exhibiting this
behavior.

TODO ref 5536
2024-11-27 10:19:26 +01:00
159 changed files with 525 additions and 1089 deletions

View File

@ -42,10 +42,10 @@ jobs:
distribution: 'zulu'
java-version: '17'
- name: Build
- name: Build scrcpy-server
run: release/build_server.sh
- name: Upload artifact
- name: Upload scrcpy-server artifact
uses: actions/upload-artifact@v4
with:
name: scrcpy-server
@ -63,7 +63,7 @@ jobs:
distribution: 'zulu'
java-version: '17'
- name: Build without gradle
- name: Build scrcpy-server without gradle
run: server/build_without_gradle.sh
test-client:
@ -83,18 +83,9 @@ jobs:
- name: Test
run: release/test_client.sh
build-linux-x86_64:
runs-on: ubuntu-20.04
build-linux:
runs-on: ubuntu-latest
steps:
- name: Check architecture
run: |
arch=$(uname -m)
if [[ "$arch" != x86_64 ]]
then
echo "Unexpected architecture: $arch" >&2
exit 1
fi
- name: Checkout code
uses: actions/checkout@v4
@ -106,22 +97,22 @@ jobs:
libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \
libv4l-dev
- name: Build
run: release/build_linux.sh x86_64
- name: Build linux
run: release/build_linux.sh
# upload-artifact does not preserve permissions
- name: Tar
run: |
cd release/work/build-linux-x86_64
cd release/work/build-linux
mkdir dist-tar
cd dist-tar
tar -C .. -cvf dist.tar.gz dist/
- name: Upload artifact
- name: Upload build-linux artifact
uses: actions/upload-artifact@v4
with:
name: build-linux-x86_64-intermediate
path: release/work/build-linux-x86_64/dist-tar/
name: build-linux-intermediate
path: release/work/build-linux/dist-tar/
build-win32:
runs-on: ubuntu-latest
@ -137,7 +128,10 @@ jobs:
libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \
mingw-w64 mingw-w64-tools libz-mingw-w64-dev
- name: Build
- name: Workaround for old meson version run by Github Actions
run: sed -i 's/^pkg-config/pkgconfig/' cross_win32.txt
- name: Build win32
run: release/build_windows.sh 32
# upload-artifact does not preserve permissions
@ -148,7 +142,7 @@ jobs:
cd dist-tar
tar -C .. -cvf dist.tar.gz dist/
- name: Upload artifact
- name: Upload build-win32 artifact
uses: actions/upload-artifact@v4
with:
name: build-win32-intermediate
@ -168,7 +162,10 @@ jobs:
libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \
mingw-w64 mingw-w64-tools libz-mingw-w64-dev
- name: Build
- name: Workaround for old meson version run by Github Actions
run: sed -i 's/^pkg-config/pkgconfig/' cross_win64.txt
- name: Build win64
run: release/build_windows.sh 64
# upload-artifact does not preserve permissions
@ -179,24 +176,15 @@ jobs:
cd dist-tar
tar -C .. -cvf dist.tar.gz dist/
- name: Upload artifact
- name: Upload build-win64 artifact
uses: actions/upload-artifact@v4
with:
name: build-win64-intermediate
path: release/work/build-win64/dist-tar/
build-macos-aarch64:
build-macos:
runs-on: macos-latest
steps:
- name: Check architecture
run: |
arch=$(uname -m)
if [[ "$arch" != arm64 ]]
then
echo "Unexpected architecture: $arch" >&2
exit 1
fi
- name: Checkout code
uses: actions/checkout@v4
@ -205,77 +193,27 @@ jobs:
brew install meson ninja nasm libiconv zlib automake autoconf \
libtool
- name: Build
env:
# the default Xcode (and macOS SDK) version can be found at
# <https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md#xcode>
#
# then the minimal supported deployment target of that macOS SDK can be found at
# <https://developer.apple.com/support/xcode/#minimum-requirements>
MACOSX_DEPLOYMENT_TARGET: 10.13
run: release/build_macos.sh aarch64
- name: Build macOS
run: release/build_macos.sh
# upload-artifact does not preserve permissions
- name: Tar
run: |
cd release/work/build-macos-aarch64
cd release/work/build-macos
mkdir dist-tar
cd dist-tar
tar -C .. -cvf dist.tar.gz dist/
- name: Upload artifact
- name: Upload build-macos artifact
uses: actions/upload-artifact@v4
with:
name: build-macos-aarch64-intermediate
path: release/work/build-macos-aarch64/dist-tar/
name: build-macos-intermediate
path: release/work/build-macos/dist-tar/
build-macos-x86_64:
runs-on: macos-13
steps:
- name: Check architecture
run: |
arch=$(uname -m)
if [[ "$arch" != x86_64 ]]
then
echo "Unexpected architecture: $arch" >&2
exit 1
fi
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: brew install meson ninja nasm libiconv zlib automake
# autoconf and libtool are already installed on macos-13
- name: Build
env:
# the default Xcode (and macOS SDK) version can be found at
# <https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#xcode>
#
# then the minimal supported deployment target of that macOS SDK can be found at
# <https://developer.apple.com/support/xcode/#minimum-requirements>
MACOSX_DEPLOYMENT_TARGET: 10.13
run: release/build_macos.sh x86_64
# upload-artifact does not preserve permissions
- name: Tar
run: |
cd release/work/build-macos-x86_64
mkdir dist-tar
cd dist-tar
tar -C .. -cvf dist.tar.gz dist/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build-macos-x86_64-intermediate
path: release/work/build-macos-x86_64/dist-tar/
package-linux-x86_64:
package-linux:
needs:
- build-scrcpy-server
- build-linux-x86_64
- build-linux
runs-on: ubuntu-latest
steps:
- name: Checkout code
@ -287,25 +225,25 @@ jobs:
name: scrcpy-server
path: release/work/build-server/server/
- name: Download build-linux-x86_64
- name: Download build-linux
uses: actions/download-artifact@v4
with:
name: build-linux-x86_64-intermediate
path: release/work/build-linux-x86_64/dist-tar/
name: build-linux-intermediate
path: release/work/build-linux/dist-tar/
# upload-artifact does not preserve permissions
- name: Detar
run: |
cd release/work/build-linux-x86_64
cd release/work/build-linux
tar xf dist-tar/dist.tar.gz
- name: Package
run: release/package_client.sh linux-x86_64 tar.gz
- name: Package linux
run: release/package_client.sh linux tar.gz
- name: Upload release
- name: Upload linux release
uses: actions/upload-artifact@v4
with:
name: release-linux-x86_64
name: release-linux
path: release/output/
package-win32:
@ -335,10 +273,10 @@ jobs:
cd release/work/build-win32
tar xf dist-tar/dist.tar.gz
- name: Package
- name: Package win32
run: release/package_client.sh win32 zip
- name: Upload release
- name: Upload win32 release
uses: actions/upload-artifact@v4
with:
name: release-win32
@ -371,55 +309,19 @@ jobs:
cd release/work/build-win64
tar xf dist-tar/dist.tar.gz
- name: Package
- name: Package win64
run: release/package_client.sh win64 zip
- name: Upload release
- name: Upload win64 release
uses: actions/upload-artifact@v4
with:
name: release-win64
path: release/output
package-macos-aarch64:
package-macos:
needs:
- build-scrcpy-server
- build-macos-aarch64
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download scrcpy-server
uses: actions/download-artifact@v4
with:
name: scrcpy-server
path: release/work/build-server/server/
- name: Download build-macos-aarch64
uses: actions/download-artifact@v4
with:
name: build-macos-aarch64-intermediate
path: release/work/build-macos-aarch64/dist-tar/
# upload-artifact does not preserve permissions
- name: Detar
run: |
cd release/work/build-macos-aarch64
tar xf dist-tar/dist.tar.gz
- name: Package
run: release/package_client.sh macos-aarch64 tar.gz
- name: Upload release
uses: actions/upload-artifact@v4
with:
name: release-macos-aarch64
path: release/output/
package-macos-x86_64:
needs:
- build-scrcpy-server
- build-macos-x86_64
- build-macos
runs-on: ubuntu-latest
steps:
- name: Checkout code
@ -434,32 +336,31 @@ jobs:
- name: Download build-macos
uses: actions/download-artifact@v4
with:
name: build-macos-x86_64-intermediate
path: release/work/build-macos-x86_64/dist-tar/
name: build-macos-intermediate
path: release/work/build-macos/dist-tar/
# upload-artifact does not preserve permissions
- name: Detar
run: |
cd release/work/build-macos-x86_64
cd release/work/build-macos
tar xf dist-tar/dist.tar.gz
- name: Package
run: release/package_client.sh macos-x86_64 tar.gz
- name: Package macos
run: release/package_client.sh macos tar.gz
- name: Upload release
- name: Upload macos release
uses: actions/upload-artifact@v4
with:
name: release-macos-x86_64
name: release-macos
path: release/output/
release:
needs:
- build-scrcpy-server
- package-linux-x86_64
- package-linux
- package-win32
- package-win64
- package-macos-aarch64
- package-macos-x86_64
- package-macos
runs-on: ubuntu-latest
steps:
- name: Checkout code
@ -471,10 +372,10 @@ jobs:
name: scrcpy-server
path: release/work/build-server/server/
- name: Download release-linux-x86_64
- name: Download release-linux
uses: actions/download-artifact@v4
with:
name: release-linux-x86_64
name: release-linux
path: release/output/
- name: Download release-win32
@ -489,16 +390,10 @@ jobs:
name: release-win64
path: release/output/
- name: Download release-macos-aarch64
- name: Download release-macos
uses: actions/download-artifact@v4
with:
name: release-macos-aarch64
path: release/output/
- name: Download release-macos-x86_64
uses: actions/download-artifact@v4
with:
name: release-macos-x86_64
name: release-macos
path: release/output/
- name: Package server

View File

@ -2,7 +2,7 @@
source for the project. Do not download releases from random websites, even if
their name contains `scrcpy`.**
# scrcpy (v3.1)
# scrcpy (v3.0)
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />

View File

@ -57,7 +57,6 @@ _scrcpy() {
--no-mipmaps
--no-mouse-hover
--no-power-on
--no-vd-destroy-content
--no-vd-system-decorations
--no-video
--no-video-playback

View File

@ -0,0 +1,6 @@
#!/bin/bash
cd "$(dirname ${BASH_SOURCE[0]})"
export ADB="${ADB:-./adb}"
export SCRCPY_SERVER_PATH="${SCRCPY_SERVER_PATH:-./scrcpy-server}"
export SCRCPY_ICON_PATH="${SCRCPY_ICON_PATH:-./icon.png}"
./scrcpy_bin "$@"

View File

@ -63,7 +63,6 @@ arguments=(
'--no-mipmaps[Disable the generation of mipmaps]'
'--no-mouse-hover[Do not forward mouse hover events]'
'--no-power-on[Do not power on the device on start]'
'--no-vd-destroy-content[Disable virtual display "destroy content on removal" flag]'
'--no-vd-system-decorations[Disable virtual display system decorations flag]'
'--no-video[Disable video forwarding]'
'--no-video-playback[Disable video playback]'

View File

@ -1,68 +0,0 @@
#!/usr/bin/env bash
set -ex
DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
cd "$DEPS_DIR"
. common
process_args "$@"
VERSION=1.5.0
FILENAME=dav1d-$VERSION.tar.gz
PROJECT_DIR=dav1d-$VERSION
SHA256SUM=78b15d9954b513ea92d27f39362535ded2243e1b0924fde39f37a31ebed5f76b
cd "$SOURCES_DIR"
if [[ -d "$PROJECT_DIR" ]]
then
echo "$PWD/$PROJECT_DIR" found
else
get_file "https://code.videolan.org/videolan/dav1d/-/archive/$VERSION/$FILENAME" "$FILENAME" "$SHA256SUM"
tar xf "$FILENAME" # First level directory is "$PROJECT_DIR"
fi
mkdir -p "$BUILD_DIR/$PROJECT_DIR"
cd "$BUILD_DIR/$PROJECT_DIR"
if [[ -d "$DIRNAME" ]]
then
echo "'$PWD/$DIRNAME' already exists, not reconfigured"
cd "$DIRNAME"
else
mkdir "$DIRNAME"
cd "$DIRNAME"
conf=(
--prefix="$INSTALL_DIR/$DIRNAME"
--libdir=lib
-Denable_tests=false
-Denable_tools=false
# Always build dav1d statically
--default-library=static
)
if [[ "$BUILD_TYPE" == cross ]]
then
case "$HOST" in
win32)
conf+=(
--cross-file="$SOURCES_DIR/$PROJECT_DIR/package/crossfiles/i686-w64-mingw32.meson"
)
;;
win64)
conf+=(
--cross-file="$SOURCES_DIR/$PROJECT_DIR/package/crossfiles/x86_64-w64-mingw32.meson"
)
;;
*)
echo "Unsupported host: $HOST" >&2
exit 1
esac
fi
meson setup . "$SOURCES_DIR/$PROJECT_DIR" "${conf[@]}"
fi
ninja
ninja install

View File

@ -40,14 +40,16 @@ else
export LDFLAGS='-static-libgcc -static'
elif [[ "$HOST" == "macos" ]]
then
export LDFLAGS="$LDFLAGS -L/opt/homebrew/opt/zlib/lib"
export CPPFLAGS="$CPPFLAGS -I/opt/homebrew/opt/zlib/include"
export LDFLAGS="$LDFLAGS-L/opt/homebrew/opt/libiconv/lib"
export CPPFLAGS="$CPPFLAGS -I/opt/homebrew/opt/libiconv/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/zlib/lib/pkgconfig"
fi
export PKG_CONFIG_PATH="$INSTALL_DIR/$DIRNAME/lib/pkgconfig:$PKG_CONFIG_PATH"
conf=(
--prefix="$INSTALL_DIR/$DIRNAME"
--pkg-config-flags="--static"
--extra-cflags="-O2 -fPIC"
--disable-programs
--disable-doc
@ -60,11 +62,9 @@ else
--disable-vaapi
--disable-vdpau
--enable-swresample
--enable-libdav1d
--enable-decoder=h264
--enable-decoder=hevc
--enable-decoder=av1
--enable-decoder=libdav1d
--enable-decoder=pcm_s16le
--enable-decoder=opus
--enable-decoder=aac

View File

@ -5,10 +5,10 @@ cd "$DEPS_DIR"
. common
process_args "$@"
VERSION=2.30.10
VERSION=2.30.9
FILENAME=SDL-$VERSION.tar.gz
PROJECT_DIR=SDL-release-$VERSION
SHA256SUM=35a8b9c4f3635d85762b904ac60ca4e0806bff89faeb269caafbe80860d67168
SHA256SUM=682a055004081e37d81a7d4ce546c3ee3ef2e0e6a675ed2651e430ccd14eb407
cd "$SOURCES_DIR"

View File

@ -46,7 +46,6 @@ src = [
'src/util/acksync.c',
'src/util/audiobuf.c',
'src/util/average.c',
'src/util/env.c',
'src/util/file.c',
'src/util/intmap.c',
'src/util/intr.c',
@ -192,19 +191,19 @@ datadir = get_option('datadir') # by default 'share'
install_man('scrcpy.1')
install_data('data/icon.png',
rename: 'scrcpy.png',
install_dir: datadir / 'icons/hicolor/256x256/apps')
install_dir: join_paths(datadir, 'icons/hicolor/256x256/apps'))
install_data('data/zsh-completion/_scrcpy',
install_dir: datadir / 'zsh/site-functions')
install_dir: join_paths(datadir, 'zsh/site-functions'))
install_data('data/bash-completion/scrcpy',
install_dir: datadir / 'bash-completion/completions')
install_dir: join_paths(datadir, 'bash-completion/completions'))
# Desktop entry file for application launchers
if host_machine.system() == 'linux'
# Install a launcher (ex: /usr/local/share/applications/scrcpy.desktop)
install_data('data/scrcpy.desktop',
install_dir: datadir / 'applications')
install_dir: join_paths(datadir, 'applications'))
install_data('data/scrcpy-console.desktop',
install_dir: datadir / 'applications')
install_dir: join_paths(datadir, 'applications'))
endif
@ -279,9 +278,3 @@ if get_option('buildtype') == 'debug'
test(t[0], exe)
endforeach
endif
if meson.version().version_compare('>= 0.58.0')
devenv = environment()
devenv.set('SCRCPY_ICON_PATH', meson.current_source_dir() / 'data/icon.png')
meson.add_devenv(devenv)
endif

View File

@ -13,7 +13,7 @@ BEGIN
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
VALUE "OriginalFilename", "scrcpy.exe"
VALUE "ProductName", "scrcpy"
VALUE "ProductVersion", "3.1"
VALUE "ProductVersion", "3.0"
END
END
BLOCK "VarFileInfo"

View File

@ -369,12 +369,6 @@ Do not forward mouse hover (mouse motion without any clicks) events.
.B \-\-no\-power\-on
Do not power on the device on start.
.TP
.B \-\-no\-vd\-destroy\-content
Disable virtual display "destroy content on removal" flag.
With this option, when the virtual display is closed, the running apps are moved to the main display rather than being destroyed.
.TP
.B \-\-no\-vd\-system\-decorations
Disable virtual display system decorations flag.
@ -524,15 +518,13 @@ Enable "show touches" on start, restore the initial value on exit.
It only shows physical touches (not clicks from scrcpy).
.TP
.BI "\-\-tcpip\fR[=[+]\fIip\fR[:\fIport\fR]]
Configure and connect the device over TCP/IP.
.BI "\-\-tcpip\fR[=\fIip\fR[:\fIport\fR]]
Configure and reconnect the device over TCP/IP.
If a destination address is provided, then scrcpy connects to this address before starting. The device must listen on the given TCP port (default is 5555).
If no destination address is provided, then scrcpy attempts to find the IP address and adb port of the current device (typically connected over USB), enables TCP/IP mode if necessary, then connects to this address before starting.
Prefix the address with a '+' to force a reconnection.
.TP
.BI "\-\-time\-limit " seconds
Set the maximum mirroring time, in seconds.

View File

@ -4,11 +4,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "adb/adb_device.h"
#include "adb/adb_parser.h"
#include "util/env.h"
#include "adb_device.h"
#include "adb_parser.h"
#include "util/file.h"
#include "util/log.h"
#include "util/process_intr.h"
@ -26,45 +24,15 @@
*/
#define SC_ADB_COMMAND(...) { sc_adb_get_executable(), __VA_ARGS__, NULL }
static char *adb_executable;
bool
sc_adb_init(void) {
adb_executable = sc_get_env("ADB");
if (adb_executable) {
LOGD("Using adb: %s", adb_executable);
return true;
}
#if !defined(PORTABLE) || defined(_WIN32)
adb_executable = strdup("adb");
if (!adb_executable) {
LOG_OOM();
return false;
}
#else
// For portable builds, use the absolute path to the adb executable
// in the same directory as scrcpy (except on Windows, where "adb"
// is sufficient)
adb_executable = sc_file_get_local_path("adb");
if (!adb_executable) {
// Error already logged
return false;
}
LOGD("Using adb (portable): %s", adb_executable);
#endif
return true;
}
void
sc_adb_destroy(void) {
free(adb_executable);
}
static const char *adb_executable;
const char *
sc_adb_get_executable(void) {
if (!adb_executable) {
adb_executable = getenv("ADB");
if (!adb_executable)
adb_executable = "adb";
}
return adb_executable;
}
@ -413,7 +381,7 @@ sc_adb_connect(struct sc_intr *intr, const char *ip_port, unsigned flags) {
// "adb connect" always returns successfully (with exit code 0), even in
// case of failure. As a workaround, check if its output starts with
// "connected" or "already connected".
// "connected".
char buf[128];
ssize_t r = sc_pipe_read_all_intr(intr, pid, pout, buf, sizeof(buf) - 1);
sc_pipe_close(pout);
@ -430,8 +398,7 @@ sc_adb_connect(struct sc_intr *intr, const char *ip_port, unsigned flags) {
assert((size_t) r < sizeof(buf));
buf[r] = '\0';
ok = !strncmp("connected", buf, sizeof("connected") - 1)
|| !strncmp("already connected", buf, sizeof("already connected") - 1);
ok = !strncmp("connected", buf, sizeof("connected") - 1);
if (!ok && !(flags & SC_ADB_NO_STDERR)) {
// "adb connect" also prints errors to stdout. Since we capture it,
// re-print the error to stderr.

View File

@ -6,7 +6,7 @@
#include <stdbool.h>
#include <inttypes.h>
#include "adb/adb_device.h"
#include "adb_device.h"
#include "util/intr.h"
#define SC_ADB_NO_STDOUT (1 << 0)
@ -15,12 +15,6 @@
#define SC_ADB_SILENT (SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR)
bool
sc_adb_init(void);
void
sc_adb_destroy(void);
const char *
sc_adb_get_executable(void);

View File

@ -4,6 +4,7 @@
#include "common.h"
#include <stdbool.h>
#include <stddef.h>
#include "util/vector.h"

View File

@ -3,7 +3,6 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "util/log.h"
#include "util/str.h"

View File

@ -3,9 +3,9 @@
#include "common.h"
#include <stdbool.h>
#include <stddef.h>
#include "adb/adb_device.h"
#include "adb_device.h"
/**
* Parse the available devices from the output of `adb devices`

View File

@ -1,11 +1,11 @@
#include "adb_tunnel.h"
#include <assert.h>
#include <inttypes.h>
#include "adb/adb.h"
#include "adb.h"
#include "util/log.h"
#include "util/net_intr.h"
#include "util/process_intr.h"
static bool
listen_on_port(struct sc_intr *intr, sc_socket socket, uint16_t port) {

View File

@ -3,7 +3,9 @@
#include "common.h"
#include <SDL2/SDL_audio.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include "audio_regulator.h"
#include "trait/frame_sink.h"

View File

@ -1,9 +1,5 @@
#include "audio_regulator.h"
#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>

View File

@ -5,8 +5,6 @@
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libswresample/swresample.h>
#include "util/audiobuf.h"

View File

@ -5,7 +5,6 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "options.h"
@ -14,7 +13,6 @@
#include "util/str.h"
#include "util/strbuf.h"
#include "util/term.h"
#include "util/tick.h"
#define STR_IMPL_(x) #x
#define STR(x) STR_IMPL_(x)
@ -112,7 +110,6 @@ enum {
OPT_CAPTURE_ORIENTATION,
OPT_ANGLE,
OPT_NO_VD_SYSTEM_DECORATIONS,
OPT_NO_VD_DESTROY_CONTENT,
};
struct sc_option {
@ -662,15 +659,6 @@ static const struct sc_option options[] = {
.longopt = "no-power-on",
.text = "Do not power on the device on start.",
},
{
.longopt_id = OPT_NO_VD_DESTROY_CONTENT,
.longopt = "no-vd-destroy-content",
.text = "Disable virtual display \"destroy content on removal\" "
"flag.\n"
"With this option, when the virtual display is closed, the "
"running apps are moved to the main display rather than being "
"destroyed.",
},
{
.longopt_id = OPT_NO_VD_SYSTEM_DECORATIONS,
.longopt = "no-vd-system-decorations",
@ -872,17 +860,16 @@ static const struct sc_option options[] = {
{
.longopt_id = OPT_TCPIP,
.longopt = "tcpip",
.argdesc = "[+]ip[:port]",
.argdesc = "ip[:port]",
.optional_arg = true,
.text = "Configure and connect the device over TCP/IP.\n"
.text = "Configure and reconnect the device over TCP/IP.\n"
"If a destination address is provided, then scrcpy connects to "
"this address before starting. The device must listen on the "
"given TCP port (default is 5555).\n"
"If no destination address is provided, then scrcpy attempts "
"to find the IP address of the current device (typically "
"connected over USB), enables TCP/IP mode, then connects to "
"this address before starting.\n"
"Prefix the address with a '+' to force a reconnection.",
"this address before starting.",
},
{
.longopt_id = OPT_TIME_LIMIT,
@ -2717,11 +2704,8 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
case OPT_ANGLE:
opts->angle = optarg;
break;
case OPT_NO_VD_DESTROY_CONTENT:
opts->vd_destroy_content = false;
break;
case OPT_NO_VD_SYSTEM_DECORATIONS:
opts->vd_system_decorations = false;
opts->vd_system_decorations = optarg;
break;
default:
// getopt prints the error message on stderr

View File

@ -152,10 +152,8 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, uint8_t *buf) {
return 2;
case SC_CONTROL_MSG_TYPE_UHID_CREATE:
sc_write16be(&buf[1], msg->uhid_create.id);
sc_write16be(&buf[3], msg->uhid_create.vendor_id);
sc_write16be(&buf[5], msg->uhid_create.product_id);
size_t index = 7;
size_t index = 3;
index += write_string_tiny(&buf[index], msg->uhid_create.name, 127);
sc_write16be(&buf[index], msg->uhid_create.report_desc_size);
@ -280,13 +278,9 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
// Quote only if name is not null
const char *name = msg->uhid_create.name;
const char *quote = name ? "\"" : "";
LOG_CMSG("UHID create [%" PRIu16 "] %04" PRIx16 ":%04" PRIx16
" name=%s%s%s report_desc_size=%" PRIu16,
msg->uhid_create.id,
msg->uhid_create.vendor_id,
msg->uhid_create.product_id,
quote, name, quote,
msg->uhid_create.report_desc_size);
LOG_CMSG("UHID create [%" PRIu16 "] name=%s%s%s "
"report_desc_size=%" PRIu16, msg->uhid_create.id,
quote, name, quote, msg->uhid_create.report_desc_size);
break;
}
case SC_CONTROL_MSG_TYPE_UHID_INPUT: {

View File

@ -94,8 +94,6 @@ struct sc_control_msg {
} set_display_power;
struct {
uint16_t id;
uint16_t vendor_id;
uint16_t product_id;
const char *name; // pointer to static data
uint16_t report_desc_size;
const uint8_t *report_desc; // pointer to static data

View File

@ -1,9 +1,11 @@
#include "decoder.h"
#include <errno.h>
#include <libavcodec/packet.h>
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/channel_layout.h>
#include "events.h"
#include "trait/frame_sink.h"
#include "util/log.h"
/** Downcast packet_sink to decoder */

View File

@ -3,11 +3,13 @@
#include "common.h"
#include <libavcodec/avcodec.h>
#include "trait/frame_source.h"
#include "trait/packet_sink.h"
#include <stdbool.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
struct sc_decoder {
struct sc_packet_sink packet_sink; // packet sink trait
struct sc_frame_source frame_source; // frame source trait

View File

@ -2,7 +2,9 @@
#include <assert.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include "util/log.h"

View File

@ -4,7 +4,6 @@
#include "common.h"
#include <stdbool.h>
#include <libavutil/frame.h>
#include "clock.h"
#include "trait/frame_source.h"

View File

@ -1,11 +1,14 @@
#include "demuxer.h"
#include <assert.h>
#include <inttypes.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/time.h>
#include <unistd.h>
#include "decoder.h"
#include "events.h"
#include "packet_merger.h"
#include "recorder.h"
#include "util/binary.h"
#include "util/log.h"

View File

@ -4,8 +4,12 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include "trait/packet_source.h"
#include "trait/packet_sink.h"
#include "util/net.h"
#include "util/thread.h"

View File

@ -3,9 +3,9 @@
#include "common.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#define DEVICE_MSG_MAX_SIZE (1 << 18) // 256k
// type: 1 byte; length: 4 bytes

View File

@ -1,8 +1,6 @@
#include "display.h"
#include <assert.h>
#include <inttypes.h>
#include <string.h>
#include <libavutil/pixfmt.h>
#include "util/log.h"

View File

@ -4,8 +4,7 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <libavutil/frame.h>
#include <libavformat/avformat.h>
#include <SDL2/SDL.h>
#include "coords.h"

View File

@ -1,7 +1,5 @@
#include "events.h"
#include <assert.h>
#include "util/log.h"
#include "util/thread.h"

View File

@ -1,11 +1,11 @@
#include "file_pusher.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "adb/adb.h"
#include "util/log.h"
#include "util/process_intr.h"
#define DEFAULT_PUSH_TARGET "/sdcard/Download/"

View File

@ -1,7 +1,6 @@
#include "fps_counter.h"
#include <assert.h>
#include <stdint.h>
#include "util/log.h"

View File

@ -5,9 +5,9 @@
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include "util/thread.h"
#include "util/tick.h"
struct sc_fps_counter {
sc_thread thread;

View File

@ -1,6 +1,8 @@
#include "frame_buffer.h"
#include <assert.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include "util/log.h"

View File

@ -4,7 +4,6 @@
#include "common.h"
#include <stdbool.h>
#include <libavutil/frame.h>
#include "util/thread.h"

View File

@ -3,7 +3,6 @@
#include "common.h"
#include <stddef.h>
#include <stdint.h>
#define SC_HID_MAX_SIZE 15
@ -16,6 +15,7 @@ struct sc_hid_input {
struct sc_hid_open {
uint16_t hid_id;
const char *name; // pointer to static memory
const uint8_t *report_desc; // pointer to static memory
size_t report_desc_size;
};

View File

@ -2,8 +2,6 @@
#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <sys/types.h>
#include "util/binary.h"
#include "util/log.h"
@ -54,10 +52,10 @@ static const uint8_t SC_HID_GAMEPAD_REPORT_DESC[] = {
0x09, 0x30,
// Usage (Y) Left stick y
0x09, 0x31,
// Usage (Rx) Right stick x
0x09, 0x33,
// Usage (Ry) Right stick y
0x09, 0x34,
// Usage (Z) Right stick x
0x09, 0x32,
// Usage (Rz) Right stick y
0x09, 0x35,
// Logical Minimum (0)
0x15, 0x00,
// Logical Maximum (65535)
@ -67,15 +65,15 @@ static const uint8_t SC_HID_GAMEPAD_REPORT_DESC[] = {
0x75, 0x10,
// Report Count (4)
0x95, 0x04,
// Input (Data, Variable, Absolute): 4x2 bytes (X, Y, Z, Rz)
// Input (Data, Variable, Absolute): 4 bytes (X, Y, Z, Rz)
0x81, 0x02,
// Usage Page (Generic Desktop)
0x05, 0x01,
// Usage (Z)
0x09, 0x32,
// Usage (Rz)
0x09, 0x35,
// Usage Page (Simulation Controls)
0x05, 0x02,
// Usage (Brake)
0x09, 0xC5,
// Usage (Accelerator)
0x09, 0xC4,
// Logical Minimum (0)
0x15, 0x00,
// Logical Maximum (32767)
@ -84,7 +82,7 @@ static const uint8_t SC_HID_GAMEPAD_REPORT_DESC[] = {
0x75, 0x10,
// Report Count (2)
0x95, 0x02,
// Input (Data, Variable, Absolute): 2x2 bytes (L2, R2)
// Input (Data, Variable, Absolute): 2 bytes (L2, R2)
0x81, 0x02,
// Usage Page (Buttons)
@ -184,7 +182,7 @@ static const uint8_t SC_HID_GAMEPAD_REPORT_DESC[] = {
* `------------- SC_GAMEPAD_BUTTON_RIGHT_STICK
*
* +---------------+
* byte 14: |0 0 0 0 . . . .| hat switch (dpad) position (0-8)
* byte 14: |0 0 0 . . . . .| hat switch (dpad) position (0-8)
* +---------------+
* 9 possible positions and their values:
* 8 1 2
@ -193,19 +191,16 @@ static const uint8_t SC_HID_GAMEPAD_REPORT_DESC[] = {
* (8 is top-left, 1 is top, 2 is top-right, etc.)
*/
// [-32768 to 32767] -> [0 to 65535]
#define AXIS_RESCALE(V) (uint16_t) (((int32_t) V) + 0x8000)
static void
sc_hid_gamepad_slot_init(struct sc_hid_gamepad_slot *slot,
uint32_t gamepad_id) {
assert(gamepad_id != SC_GAMEPAD_ID_INVALID);
slot->gamepad_id = gamepad_id;
slot->buttons = 0;
slot->axis_left_x = AXIS_RESCALE(0);
slot->axis_left_y = AXIS_RESCALE(0);
slot->axis_right_x = AXIS_RESCALE(0);
slot->axis_right_y = AXIS_RESCALE(0);
slot->axis_left_x = 0;
slot->axis_left_y = 0;
slot->axis_right_x = 0;
slot->axis_right_y = 0;
slot->axis_left_trigger = 0;
slot->axis_right_trigger = 0;
}
@ -248,8 +243,14 @@ sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
sc_hid_gamepad_slot_init(&hid->slots[slot_idx], gamepad_id);
SDL_GameController* game_controller =
SDL_GameControllerFromInstanceID(gamepad_id);
assert(game_controller);
const char *name = SDL_GameControllerName(game_controller);
uint16_t hid_id = sc_hid_gamepad_slot_get_id(slot_idx);
hid_open->hid_id = hid_id;
hid_open->name = name;
hid_open->report_desc = SC_HID_GAMEPAD_REPORT_DESC;
hid_open->report_desc_size = sizeof(SC_HID_GAMEPAD_REPORT_DESC);
@ -422,6 +423,8 @@ sc_hid_gamepad_generate_input_from_axis(struct sc_hid_gamepad *hid,
struct sc_hid_gamepad_slot *slot = &hid->slots[slot_idx];
// [-32768 to 32767] -> [0 to 65535]
#define AXIS_RESCALE(V) (uint16_t) (((int32_t) V) + 0x8000)
switch (event->axis) {
case SC_GAMEPAD_AXIS_LEFTX:
slot->axis_left_x = AXIS_RESCALE(event->value);

View File

@ -4,7 +4,6 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include "hid/hid_event.h"
#include "input_events.h"

View File

@ -1,6 +1,5 @@
#include "hid_keyboard.h"
#include <assert.h>
#include <string.h>
#include "util/log.h"
@ -336,6 +335,7 @@ sc_hid_keyboard_generate_input_from_mods(struct sc_hid_input *hid_input,
void sc_hid_keyboard_generate_open(struct sc_hid_open *hid_open) {
hid_open->hid_id = SC_HID_ID_KEYBOARD;
hid_open->name = NULL; // No name specified after "scrcpy"
hid_open->report_desc = SC_HID_KEYBOARD_REPORT_DESC;
hid_open->report_desc_size = sizeof(SC_HID_KEYBOARD_REPORT_DESC);
}

View File

@ -4,7 +4,6 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include "hid/hid_event.h"
#include "input_events.h"

View File

@ -1,7 +1,5 @@
#include "hid_mouse.h"
#include <stdint.h>
// 1 byte for buttons + padding, 1 byte for X position, 1 byte for Y position,
// 1 byte for wheel motion
#define SC_HID_MOUSE_INPUT_SIZE 4
@ -192,6 +190,7 @@ sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input,
void sc_hid_mouse_generate_open(struct sc_hid_open *hid_open) {
hid_open->hid_id = SC_HID_ID_MOUSE;
hid_open->name = NULL; // No name specified after "scrcpy"
hid_open->report_desc = SC_HID_MOUSE_REPORT_DESC;
hid_open->report_desc_size = sizeof(SC_HID_MOUSE_REPORT_DESC);
}

View File

@ -3,6 +3,8 @@
#include "common.h"
#include <stdbool.h>
#include "hid/hid_event.h"
#include "input_events.h"

View File

@ -2,22 +2,16 @@
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/pixdesc.h>
#include <libavutil/pixfmt.h>
#include <SDL2/SDL.h>
#include "config.h"
#include "util/env.h"
#ifdef PORTABLE
# include "util/file.h"
#endif
#include "compat.h"
#include "util/file.h"
#include "util/log.h"
#include "util/str.h"
#define SCRCPY_PORTABLE_ICON_FILENAME "icon.png"
#define SCRCPY_DEFAULT_ICON_PATH \
@ -25,22 +19,35 @@
static char *
get_icon_path(void) {
char *icon_path = sc_get_env("SCRCPY_ICON_PATH");
if (icon_path) {
#ifdef __WINDOWS__
const wchar_t *icon_path_env = _wgetenv(L"SCRCPY_ICON_PATH");
#else
const char *icon_path_env = getenv("SCRCPY_ICON_PATH");
#endif
if (icon_path_env) {
// if the envvar is set, use it
#ifdef __WINDOWS__
char *icon_path = sc_str_from_wchars(icon_path_env);
#else
char *icon_path = strdup(icon_path_env);
#endif
if (!icon_path) {
LOG_OOM();
return NULL;
}
LOGD("Using SCRCPY_ICON_PATH: %s", icon_path);
return icon_path;
}
#ifndef PORTABLE
LOGD("Using icon: " SCRCPY_DEFAULT_ICON_PATH);
icon_path = strdup(SCRCPY_DEFAULT_ICON_PATH);
char *icon_path = strdup(SCRCPY_DEFAULT_ICON_PATH);
if (!icon_path) {
LOG_OOM();
return NULL;
}
#else
icon_path = sc_file_get_local_path(SCRCPY_PORTABLE_ICON_FILENAME);
char *icon_path = sc_file_get_local_path(SCRCPY_PORTABLE_ICON_FILENAME);
if (!icon_path) {
LOGE("Could not get icon path");
return NULL;

View File

@ -3,7 +3,9 @@
#include "common.h"
#include <SDL2/SDL_surface.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <libavformat/avformat.h>
SDL_Surface *
scrcpy_icon_load(void);

View File

@ -9,6 +9,7 @@
#include <SDL2/SDL_events.h>
#include "coords.h"
#include "options.h"
/* The representation of input events in scrcpy is very close to the SDL API,
* for simplicity.
@ -411,12 +412,18 @@ struct sc_touch_event {
float pressure;
};
enum sc_gamepad_device_event_type {
SC_GAMEPAD_DEVICE_ADDED,
SC_GAMEPAD_DEVICE_REMOVED,
};
// As documented in <https://wiki.libsdl.org/SDL2/SDL_JoystickID>:
// The ID value starts at 0 and increments from there. The value -1 is an
// invalid ID.
#define SC_GAMEPAD_ID_INVALID UINT32_C(-1)
struct sc_gamepad_device_event {
enum sc_gamepad_device_event_type type;
uint32_t gamepad_id;
};
@ -496,6 +503,16 @@ sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
return buttons_state;
}
static inline enum sc_gamepad_device_event_type
sc_gamepad_device_event_type_from_sdl_type(uint32_t type) {
assert(type == SDL_CONTROLLERDEVICEADDED
|| type == SDL_CONTROLLERDEVICEREMOVED);
if (type == SDL_CONTROLLERDEVICEADDED) {
return SC_GAMEPAD_DEVICE_ADDED;
}
return SC_GAMEPAD_DEVICE_REMOVED;
}
static inline enum sc_gamepad_axis
sc_gamepad_axis_from_sdl(uint8_t axis) {
if (axis <= SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {

View File

@ -1,12 +1,8 @@
#include "input_manager.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_keycode.h>
#include "android/input.h"
#include "android/keycodes.h"
#include "input_events.h"
#include "screen.h"
#include "shortcut_mod.h"
@ -912,6 +908,7 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
static void
sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
const SDL_ControllerDeviceEvent *event) {
SDL_JoystickID id;
if (event->type == SDL_CONTROLLERDEVICEADDED) {
SDL_GameController *gc = SDL_GameControllerOpen(event->which);
if (!gc) {
@ -926,12 +923,9 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
return;
}
struct sc_gamepad_device_event evt = {
.gamepad_id = SDL_JoystickInstanceID(joystick),
};
im->gp->ops->process_gamepad_added(im->gp, &evt);
id = SDL_JoystickInstanceID(joystick);
} else if (event->type == SDL_CONTROLLERDEVICEREMOVED) {
SDL_JoystickID id = event->which;
id = event->which;
SDL_GameController *gc = SDL_GameControllerFromInstanceID(id);
if (gc) {
@ -939,15 +933,16 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
} else {
LOGW("Unknown gamepad device removed");
}
struct sc_gamepad_device_event evt = {
.gamepad_id = id,
};
im->gp->ops->process_gamepad_removed(im->gp, &evt);
} else {
// Nothing to do
return;
}
struct sc_gamepad_device_event evt = {
.type = sc_gamepad_device_event_type_from_sdl_type(event->type),
.gamepad_id = id,
};
im->gp->ops->process_gamepad_device(im->gp, &evt);
}
static void

View File

@ -4,12 +4,12 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL.h>
#include "controller.h"
#include "file_pusher.h"
#include "fps_counter.h"
#include "options.h"
#include "trait/gamepad_processor.h"
#include "trait/key_processor.h"

View File

@ -1,13 +1,8 @@
#include "keyboard_sdk.h"
#include <assert.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "android/input.h"
#include "android/keycodes.h"
#include "control_msg.h"
#include "controller.h"
#include "input_events.h"

View File

@ -1,6 +1,9 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <unistd.h>
#include <libavformat/avformat.h>
#ifdef HAVE_V4L2
# include <libavdevice/avdevice.h>
#endif

View File

@ -1,12 +1,12 @@
#include "mouse_sdk.h"
#include <assert.h>
#include <stdint.h>
#include "android/input.h"
#include "control_msg.h"
#include "controller.h"
#include "input_events.h"
#include "util/intmap.h"
#include "util/log.h"
/** Downcast mouse processor to sc_mouse_sdk */

View File

@ -6,6 +6,7 @@
#include <stdbool.h>
#include "controller.h"
#include "screen.h"
#include "trait/mouse_processor.h"
struct sc_mouse_sdk {

View File

@ -2,8 +2,7 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <SDL2/SDL.h>
#include "SDL2/SDL.h"
void
sc_opengl_init(struct sc_opengl *gl) {

View File

@ -1,7 +1,5 @@
#include "options.h"
#include <stddef.h>
const struct scrcpy_options scrcpy_options_default = {
.serial = NULL,
.crop = NULL,
@ -110,7 +108,6 @@ const struct scrcpy_options scrcpy_options_default = {
.new_display = NULL,
.start_app = NULL,
.angle = NULL,
.vd_destroy_content = true,
.vd_system_decorations = true,
};

View File

@ -5,6 +5,7 @@
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "util/tick.h"
@ -309,7 +310,6 @@ struct scrcpy_options {
bool audio_dup;
const char *new_display; // [<width>x<height>][/<dpi>] parsed by the server
const char *start_app;
bool vd_destroy_content;
bool vd_system_decorations;
};

View File

@ -1,9 +1,5 @@
#include "packet_merger.h"
#include <stdlib.h>
#include <string.h>
#include <libavutil/avutil.h>
#include "util/log.h"
void

View File

@ -5,7 +5,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <libavcodec/packet.h>
#include <libavcodec/avcodec.h>
/**
* Config packets (containing the SPS/PPS) are sent in-band. A new config

View File

@ -2,6 +2,7 @@
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <SDL2/SDL_clipboard.h>
#include "device_msg.h"

View File

@ -1,9 +1,6 @@
#include "recorder.h"
#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/time.h>

View File

@ -4,10 +4,9 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h>
#include "coords.h"
#include "options.h"
#include "trait/packet_sink.h"
#include "util/thread.h"

View File

@ -1,11 +1,10 @@
#include "scrcpy.h"
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libavformat/avformat.h>
#include <sys/time.h>
#include <SDL2/SDL.h>
#ifdef _WIN32
@ -38,9 +37,9 @@
#endif
#include "util/acksync.h"
#include "util/log.h"
#include "util/net.h"
#include "util/rand.h"
#include "util/timeout.h"
#include "util/tick.h"
#ifdef HAVE_V4L2
# include "v4l2_sink.h"
#endif
@ -459,7 +458,6 @@ scrcpy(struct scrcpy_options *options) {
.power_on = options->power_on,
.kill_adb_on_close = options->kill_adb_on_close,
.camera_high_speed = options->camera_high_speed,
.vd_destroy_content = options->vd_destroy_content,
.vd_system_decorations = options->vd_system_decorations,
.list = options->list,
};

View File

@ -3,6 +3,7 @@
#include "common.h"
#include <stdbool.h>
#include "options.h"
enum scrcpy_exit_code {

View File

@ -1,14 +1,11 @@
#ifndef SC_SCREEN_H
#define SC_SCREEN_H
#ifndef SCREEN_H
#define SCREEN_H
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL.h>
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
#include <libavutil/pixfmt.h>
#include <libavformat/avformat.h>
#include "controller.h"
#include "coords.h"
@ -17,6 +14,7 @@
#include "frame_buffer.h"
#include "input_manager.h"
#include "mouse_capture.h"
#include "opengl.h"
#include "options.h"
#include "trait/key_processor.h"
#include "trait/frame_sink.h"

View File

@ -1,18 +1,18 @@
#include "server.h"
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_platform.h>
#include "adb/adb.h"
#include "util/env.h"
#include "util/binary.h"
#include "util/file.h"
#include "util/log.h"
#include "util/net_intr.h"
#include "util/process.h"
#include "util/process_intr.h"
#include "util/str.h"
#define SC_SERVER_FILENAME "scrcpy-server"
@ -25,22 +25,35 @@
static char *
get_server_path(void) {
char *server_path = sc_get_env("SCRCPY_SERVER_PATH");
if (server_path) {
#ifdef __WINDOWS__
const wchar_t *server_path_env = _wgetenv(L"SCRCPY_SERVER_PATH");
#else
const char *server_path_env = getenv("SCRCPY_SERVER_PATH");
#endif
if (server_path_env) {
// if the envvar is set, use it
#ifdef __WINDOWS__
char *server_path = sc_str_from_wchars(server_path_env);
#else
char *server_path = strdup(server_path_env);
#endif
if (!server_path) {
LOG_OOM();
return NULL;
}
LOGD("Using SCRCPY_SERVER_PATH: %s", server_path);
return server_path;
}
#ifndef PORTABLE
LOGD("Using server: " SC_SERVER_PATH_DEFAULT);
server_path = strdup(SC_SERVER_PATH_DEFAULT);
char *server_path = strdup(SC_SERVER_PATH_DEFAULT);
if (!server_path) {
LOG_OOM();
return NULL;
}
#else
server_path = sc_file_get_local_path(SC_SERVER_FILENAME);
char *server_path = sc_file_get_local_path(SC_SERVER_FILENAME);
if (!server_path) {
LOGE("Could not get local file path, "
"using " SC_SERVER_FILENAME " from current directory");
@ -376,9 +389,6 @@ execute_server(struct sc_server *server,
VALIDATE_STRING(params->new_display);
ADD_PARAM("new_display=%s", params->new_display);
}
if (!params->vd_destroy_content) {
ADD_PARAM("vd_destroy_content=false");
}
if (!params->vd_system_decorations) {
ADD_PARAM("vd_system_decorations=false");
}
@ -487,21 +497,14 @@ sc_server_init(struct sc_server *server, const struct sc_server_params *params,
// end of the program
server->params = *params;
bool ok = sc_adb_init();
bool ok = sc_mutex_init(&server->mutex);
if (!ok) {
return false;
}
ok = sc_mutex_init(&server->mutex);
if (!ok) {
sc_adb_destroy();
return false;
}
ok = sc_cond_init(&server->cond_stopped);
if (!ok) {
sc_mutex_destroy(&server->mutex);
sc_adb_destroy();
return false;
}
@ -509,7 +512,6 @@ sc_server_init(struct sc_server *server, const struct sc_server_params *params,
if (!ok) {
sc_cond_destroy(&server->cond_stopped);
sc_mutex_destroy(&server->mutex);
sc_adb_destroy();
return false;
}
@ -831,14 +833,11 @@ sc_server_switch_to_tcpip(struct sc_server *server, const char *serial) {
}
static bool
sc_server_connect_to_tcpip(struct sc_server *server, const char *ip_port,
bool disconnect) {
sc_server_connect_to_tcpip(struct sc_server *server, const char *ip_port) {
struct sc_intr *intr = &server->intr;
if (disconnect) {
// Error expected if not connected, do not report any error
sc_adb_disconnect(intr, ip_port, SC_ADB_SILENT);
}
// Error expected if not connected, do not report any error
sc_adb_disconnect(intr, ip_port, SC_ADB_SILENT);
LOGI("Connecting to %s...", ip_port);
@ -854,7 +853,7 @@ sc_server_connect_to_tcpip(struct sc_server *server, const char *ip_port,
static bool
sc_server_configure_tcpip_known_address(struct sc_server *server,
const char *addr, bool disconnect) {
const char *addr) {
// Append ":5555" if no port is present
bool contains_port = strchr(addr, ':');
char *ip_port = contains_port ? strdup(addr)
@ -865,7 +864,7 @@ sc_server_configure_tcpip_known_address(struct sc_server *server,
}
server->serial = ip_port;
return sc_server_connect_to_tcpip(server, ip_port, disconnect);
return sc_server_connect_to_tcpip(server, ip_port);
}
static bool
@ -890,7 +889,7 @@ sc_server_configure_tcpip_unknown_address(struct sc_server *server,
}
server->serial = ip_port;
return sc_server_connect_to_tcpip(server, ip_port, false);
return sc_server_connect_to_tcpip(server, ip_port);
}
static void
@ -977,13 +976,7 @@ run_server(void *data) {
sc_adb_device_destroy(&device);
}
} else {
// If the user passed a '+' (--tcpip=+ip), then disconnect first
const char *tcpip_dst = params->tcpip_dst;
bool plus = tcpip_dst[0] == '+';
if (plus) {
++tcpip_dst;
}
ok = sc_server_configure_tcpip_known_address(server, tcpip_dst, plus);
ok = sc_server_configure_tcpip_known_address(server, params->tcpip_dst);
if (!ok) {
goto error_connection_failed;
}
@ -1160,6 +1153,4 @@ sc_server_destroy(struct sc_server *server) {
sc_intr_destroy(&server->intr);
sc_cond_destroy(&server->cond_stopped);
sc_mutex_destroy(&server->mutex);
sc_adb_destroy();
}

View File

@ -1,17 +1,19 @@
#ifndef SC_SERVER_H
#define SC_SERVER_H
#ifndef SERVER_H
#define SERVER_H
#include "common.h"
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include "adb/adb_tunnel.h"
#include "coords.h"
#include "options.h"
#include "util/intr.h"
#include "util/log.h"
#include "util/net.h"
#include "util/thread.h"
#include "util/tick.h"
#define SC_DEVICE_NAME_FIELD_LENGTH 64
struct sc_server_info {
@ -67,7 +69,6 @@ struct sc_server_params {
bool power_on;
bool kill_adb_on_close;
bool camera_high_speed;
bool vd_destroy_content;
bool vd_system_decorations;
uint8_t list;
};

View File

@ -3,7 +3,6 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL_keycode.h>

View File

@ -1,15 +1,11 @@
#include "util/file.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef __APPLE__
# include <mach-o/dyld.h> // for _NSGetExecutablePath()
#endif
#include "util/log.h"
@ -64,22 +60,11 @@ sc_file_get_executable_path(void) {
}
buf[len] = '\0';
return strdup(buf);
#elif defined(__APPLE__)
char buf[PATH_MAX];
uint32_t bufsize = PATH_MAX;
if (_NSGetExecutablePath(buf, &bufsize) != 0) {
LOGE("Executable path buffer too small; need %u bytes", bufsize);
return NULL;
}
return realpath(buf, NULL);
#else
// "_" is often used to store the full path of the command being executed
char *path = getenv("_");
if (!path) {
LOGE("Could not determine executable path");
return NULL;
}
return strdup(path);
// in practice, we only need this feature for portable builds, only used on
// Windows, so we don't care implementing it for every platform
// (it's useful to have a working version on Linux for debugging though)
return NULL;
#endif
}

View File

@ -4,8 +4,6 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

View File

@ -3,6 +3,7 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <libavcodec/avcodec.h>

View File

@ -1,7 +1,5 @@
#include "frame_source.h"
#include <assert.h>
void
sc_frame_source_init(struct sc_frame_source *source) {
source->sink_count = 0;

View File

@ -3,9 +3,7 @@
#include "common.h"
#include <stdbool.h>
#include "trait/frame_sink.h"
#include "frame_sink.h"
#define SC_FRAME_SOURCE_MAX_SINKS 2

View File

@ -3,6 +3,9 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include "input_events.h"
/**
@ -17,22 +20,13 @@ struct sc_gamepad_processor {
struct sc_gamepad_processor_ops {
/**
* Process a gamepad device added event
* Process a gamepad device added or removed
*
* This function is mandatory.
*/
void
(*process_gamepad_added)(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event);
/**
* Process a gamepad device removed event
*
* This function is mandatory.
*/
void
(*process_gamepad_removed)(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event);
(*process_gamepad_device)(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event);
/**
* Process a gamepad axis event

View File

@ -3,6 +3,7 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include "input_events.h"

View File

@ -3,6 +3,7 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include "input_events.h"

View File

@ -3,6 +3,7 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <libavcodec/avcodec.h>

View File

@ -1,7 +1,5 @@
#include "packet_source.h"
#include <assert.h>
void
sc_packet_source_init(struct sc_packet_source *source) {
source->sink_count = 0;

View File

@ -3,9 +3,7 @@
#include "common.h"
#include <stdbool.h>
#include "trait/packet_sink.h"
#include "packet_sink.h"
#define SC_PACKET_SOURCE_MAX_SINKS 2

View File

@ -1,10 +1,5 @@
#include "gamepad_uhid.h"
#include <assert.h>
#include <inttypes.h>
#include <string.h>
#include <SDL2/SDL_gamecontroller.h>
#include "hid/hid_gamepad.h"
#include "input_events.h"
#include "util/log.h"
@ -12,11 +7,6 @@
/** Downcast gamepad processor to sc_gamepad_uhid */
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_uhid, gamepad_processor)
// Xbox 360
#define SC_GAMEPAD_UHID_VENDOR_ID UINT16_C(0x045e)
#define SC_GAMEPAD_UHID_PRODUCT_ID UINT16_C(0x028e)
#define SC_GAMEPAD_UHID_NAME "Microsoft X-Box 360 Pad"
static void
sc_gamepad_uhid_send_input(struct sc_gamepad_uhid *gamepad,
const struct sc_hid_input *hid_input,
@ -40,9 +30,7 @@ sc_gamepad_uhid_send_open(struct sc_gamepad_uhid *gamepad,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = hid_open->hid_id;
msg.uhid_create.vendor_id = SC_GAMEPAD_UHID_VENDOR_ID;
msg.uhid_create.product_id = SC_GAMEPAD_UHID_PRODUCT_ID;
msg.uhid_create.name = SC_GAMEPAD_UHID_NAME;
msg.uhid_create.name = hid_open->name;
msg.uhid_create.report_desc = hid_open->report_desc;
msg.uhid_create.report_desc_size = hid_open->report_desc_size;
@ -64,39 +52,29 @@ sc_gamepad_uhid_send_close(struct sc_gamepad_uhid *gamepad,
}
static void
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) {
return;
if (event->type == SC_GAMEPAD_DEVICE_ADDED) {
struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) {
return;
}
sc_gamepad_uhid_send_open(gamepad, &hid_open);
} else {
assert(event->type == SC_GAMEPAD_DEVICE_REMOVED);
struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
event->gamepad_id)) {
return;
}
sc_gamepad_uhid_send_close(gamepad, &hid_close);
}
SDL_GameController* game_controller =
SDL_GameControllerFromInstanceID(event->gamepad_id);
assert(game_controller);
const char *name = SDL_GameControllerName(game_controller);
LOGI("Gamepad added: [%" PRIu32 "] %s", event->gamepad_id, name);
sc_gamepad_uhid_send_open(gamepad, &hid_open);
}
static void
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
event->gamepad_id)) {
return;
}
LOGI("Gamepad removed: [%" PRIu32 "]", event->gamepad_id);
sc_gamepad_uhid_send_close(gamepad, &hid_close);
}
static void
@ -136,8 +114,7 @@ sc_gamepad_uhid_init(struct sc_gamepad_uhid *gamepad,
gamepad->controller = controller;
static const struct sc_gamepad_processor_ops ops = {
.process_gamepad_added = sc_gamepad_processor_process_gamepad_added,
.process_gamepad_removed = sc_gamepad_processor_process_gamepad_removed,
.process_gamepad_device = sc_gamepad_processor_process_gamepad_device,
.process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis,
.process_gamepad_button = sc_gamepad_processor_process_gamepad_button,
};

View File

@ -3,6 +3,8 @@
#include "common.h"
#include <stdbool.h>
#include "controller.h"
#include "hid/hid_gamepad.h"
#include "trait/gamepad_processor.h"

View File

@ -1,12 +1,6 @@
#include "keyboard_uhid.h"
#include <assert.h>
#include <string.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_keycode.h>
#include "util/log.h"
#include "util/thread.h"
/** Downcast key processor to keyboard_uhid */
#define DOWNCAST(KP) container_of(KP, struct sc_keyboard_uhid, key_processor)
@ -147,9 +141,7 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = SC_HID_ID_KEYBOARD;
msg.uhid_create.vendor_id = 0;
msg.uhid_create.product_id = 0;
msg.uhid_create.name = NULL;
msg.uhid_create.name = hid_open.name;
msg.uhid_create.report_desc = hid_open.report_desc;
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
if (!sc_controller_push_msg(controller, &msg)) {

View File

@ -1,8 +1,5 @@
#include "mouse_uhid.h"
#include <assert.h>
#include <string.h>
#include "hid/hid_mouse.h"
#include "input_events.h"
#include "util/log.h"
@ -84,9 +81,7 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = SC_HID_ID_MOUSE;
msg.uhid_create.vendor_id = 0;
msg.uhid_create.product_id = 0;
msg.uhid_create.name = NULL;
msg.uhid_create.name = hid_open.name;
msg.uhid_create.report_desc = hid_open.report_desc;
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
if (!sc_controller_push_msg(controller, &msg)) {

View File

@ -1,5 +1,6 @@
#include "uhid_output.h"
#include <assert.h>
#include <inttypes.h>
#include "uhid/keyboard_uhid.h"

View File

@ -3,7 +3,7 @@
#include "common.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
/**

View File

@ -1,16 +1,13 @@
#include "aoa_hid.h"
#include "util/log.h"
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <libusb-1.0/libusb.h>
#include "aoa_hid.h"
#include "events.h"
#include "util/log.h"
#include "util/str.h"
#include "util/tick.h"
#include "util/vector.h"
// See <https://source.android.com/devices/accessories/aoa2#hid-support>.

View File

@ -3,13 +3,16 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdbool.h>
#include <libusb-1.0/libusb.h>
#include "hid/hid_event.h"
#include "usb/usb.h"
#include "usb.h"
#include "util/acksync.h"
#include "util/thread.h"
#include "util/tick.h"
#include "util/vecdeque.h"
enum sc_aoa_event_type {

View File

@ -1,7 +1,5 @@
#include "gamepad_aoa.h"
#include <stdbool.h>
#include "input_events.h"
#include "util/log.h"
@ -9,35 +7,33 @@
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_aoa, gamepad_processor)
static void
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) {
return;
}
if (event->type == SC_GAMEPAD_DEVICE_ADDED) {
struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) {
return;
}
// exit_on_error: false (a gamepad open failure should not exit scrcpy)
if (!sc_aoa_push_open(gamepad->aoa, &hid_open, false)) {
LOGW("Could not push AOA HID open (gamepad)");
}
}
// exit_on_error: false (a gamepad open failure should not exit scrcpy)
if (!sc_aoa_push_open(gamepad->aoa, &hid_open, false)) {
LOGW("Could not push AOA HID open (gamepad)");
}
} else {
assert(event->type == SC_GAMEPAD_DEVICE_REMOVED);
static void
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
event->gamepad_id)) {
return;
}
struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
event->gamepad_id)) {
return;
}
if (!sc_aoa_push_close(gamepad->aoa, &hid_close)) {
LOGW("Could not push AOA HID close (gamepad)");
if (!sc_aoa_push_close(gamepad->aoa, &hid_close)) {
LOGW("Could not push AOA HID close (gamepad)");
}
}
}
@ -80,8 +76,7 @@ sc_gamepad_aoa_init(struct sc_gamepad_aoa *gamepad, struct sc_aoa *aoa) {
sc_hid_gamepad_init(&gamepad->hid);
static const struct sc_gamepad_processor_ops ops = {
.process_gamepad_added = sc_gamepad_processor_process_gamepad_added,
.process_gamepad_removed = sc_gamepad_processor_process_gamepad_removed,
.process_gamepad_device = sc_gamepad_processor_process_gamepad_device,
.process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis,
.process_gamepad_button = sc_gamepad_processor_process_gamepad_button,
};

View File

@ -3,8 +3,10 @@
#include "common.h"
#include <stdbool.h>
#include "aoa_hid.h"
#include "hid/hid_gamepad.h"
#include "usb/aoa_hid.h"
#include "trait/gamepad_processor.h"
struct sc_gamepad_aoa {

View File

@ -5,8 +5,8 @@
#include <stdbool.h>
#include "aoa_hid.h"
#include "hid/hid_keyboard.h"
#include "usb/aoa_hid.h"
#include "trait/key_processor.h"
struct sc_keyboard_aoa {

View File

@ -1,7 +1,6 @@
#include "mouse_aoa.h"
#include <assert.h>
#include <stddef.h>
#include "hid/hid_mouse.h"
#include "input_events.h"

View File

@ -5,7 +5,7 @@
#include <stdbool.h>
#include "usb/aoa_hid.h"
#include "aoa_hid.h"
#include "trait/mouse_processor.h"
struct sc_mouse_aoa {

View File

@ -1,19 +1,10 @@
#include "scrcpy_otg.h"
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#ifdef _WIN32
# include "adb/adb.h"
#endif
#include "adb/adb.h"
#include "events.h"
#include "usb/screen_otg.h"
#include "usb/aoa_hid.h"
#include "usb/gamepad_aoa.h"
#include "usb/keyboard_aoa.h"
#include "usb/mouse_aoa.h"
#include "screen_otg.h"
#include "util/log.h"
struct scrcpy_otg {
@ -104,14 +95,9 @@ scrcpy_otg(struct scrcpy_options *options) {
// On Windows, only one process could open a USB device
// <https://github.com/Genymobile/scrcpy/issues/2773>
LOGI("Killing adb server (if any)...");
if (sc_adb_init()) {
unsigned flags = SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR;
// uninterruptible (intr == NULL), but in practice it's very quick
sc_adb_kill_server(NULL, flags);
sc_adb_destroy();
} else {
LOGW("Could not call adb executable, adb server not killed");
}
unsigned flags = SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR;
// uninterruptible (intr == NULL), but in practice it's very quick
sc_adb_kill_server(NULL, flags);
#endif
static const struct sc_usb_callbacks cbs = {

View File

@ -1,11 +1,7 @@
#include "screen_otg.h"
#include <assert.h>
#include <stddef.h>
#include "icon.h"
#include "options.h"
#include "util/acksync.h"
#include "util/log.h"
static void
@ -179,6 +175,7 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
assert(screen->gamepad);
struct sc_gamepad_processor *gp = &screen->gamepad->gamepad_processor;
SDL_JoystickID id;
if (event->type == SDL_CONTROLLERDEVICEADDED) {
SDL_GameController *gc = SDL_GameControllerOpen(event->which);
if (!gc) {
@ -193,12 +190,9 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
return;
}
struct sc_gamepad_device_event evt = {
.gamepad_id = SDL_JoystickInstanceID(joystick),
};
gp->ops->process_gamepad_added(gp, &evt);
id = SDL_JoystickInstanceID(joystick);
} else if (event->type == SDL_CONTROLLERDEVICEREMOVED) {
SDL_JoystickID id = event->which;
id = event->which;
SDL_GameController *gc = SDL_GameControllerFromInstanceID(id);
if (gc) {
@ -206,12 +200,16 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
} else {
LOGW("Unknown gamepad device removed");
}
struct sc_gamepad_device_event evt = {
.gamepad_id = id,
};
gp->ops->process_gamepad_removed(gp, &evt);
} else {
// Nothing to do
return;
}
struct sc_gamepad_device_event evt = {
.type = sc_gamepad_device_event_type_from_sdl_type(event->type),
.gamepad_id = id,
};
gp->ops->process_gamepad_device(gp, &evt);
}
static void

View File

@ -4,13 +4,12 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL.h>
#include "keyboard_aoa.h"
#include "mouse_aoa.h"
#include "mouse_capture.h"
#include "usb/gamepad_aoa.h"
#include "usb/keyboard_aoa.h"
#include "usb/mouse_aoa.h"
#include "gamepad_aoa.h"
struct sc_screen_otg {
struct sc_keyboard_aoa *keyboard;

View File

@ -1,6 +1,7 @@
#include "acksync.h"
#include <assert.h>
#include "util/log.h"
bool
sc_acksync_init(struct sc_acksync *as) {

View File

@ -3,10 +3,7 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
#include "util/thread.h"
#include "util/tick.h"
#include "thread.h"
#define SC_SEQUENCE_INVALID 0

View File

@ -6,7 +6,6 @@
#include <assert.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**

View File

@ -3,6 +3,9 @@
#include "common.h"
#include <stdbool.h>
#include <stdint.h>
struct sc_average {
// Current average value
float avg;

View File

@ -4,6 +4,7 @@
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
static inline void

Some files were not shown because too many files have changed in this diff Show More