Compare commits
5 Commits
rotate
...
gamepad_fi
Author | SHA1 | Date | |
---|---|---|---|
309d0371eb | |||
a582c0cc1b | |||
696295f66d | |||
347169aab6 | |||
75bdd0c831 |
@ -2,7 +2,7 @@
|
|||||||
source for the project. Do not download releases from random websites, even if
|
source for the project. Do not download releases from random websites, even if
|
||||||
their name contains `scrcpy`.**
|
their name contains `scrcpy`.**
|
||||||
|
|
||||||
# scrcpy (v3.1)
|
# scrcpy (v3.0.2)
|
||||||
|
|
||||||
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
||||||
|
|
||||||
|
@ -57,7 +57,6 @@ _scrcpy() {
|
|||||||
--no-mipmaps
|
--no-mipmaps
|
||||||
--no-mouse-hover
|
--no-mouse-hover
|
||||||
--no-power-on
|
--no-power-on
|
||||||
--no-vd-destroy-content
|
|
||||||
--no-vd-system-decorations
|
--no-vd-system-decorations
|
||||||
--no-video
|
--no-video
|
||||||
--no-video-playback
|
--no-video-playback
|
||||||
|
@ -63,7 +63,6 @@ arguments=(
|
|||||||
'--no-mipmaps[Disable the generation of mipmaps]'
|
'--no-mipmaps[Disable the generation of mipmaps]'
|
||||||
'--no-mouse-hover[Do not forward mouse hover events]'
|
'--no-mouse-hover[Do not forward mouse hover events]'
|
||||||
'--no-power-on[Do not power on the device on start]'
|
'--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-vd-system-decorations[Disable virtual display system decorations flag]'
|
||||||
'--no-video[Disable video forwarding]'
|
'--no-video[Disable video forwarding]'
|
||||||
'--no-video-playback[Disable video playback]'
|
'--no-video-playback[Disable video playback]'
|
||||||
|
@ -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
|
|
@ -40,14 +40,16 @@ else
|
|||||||
export LDFLAGS='-static-libgcc -static'
|
export LDFLAGS='-static-libgcc -static'
|
||||||
elif [[ "$HOST" == "macos" ]]
|
elif [[ "$HOST" == "macos" ]]
|
||||||
then
|
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"
|
export PKG_CONFIG_PATH="/opt/homebrew/opt/zlib/lib/pkgconfig"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PKG_CONFIG_PATH="$INSTALL_DIR/$DIRNAME/lib/pkgconfig:$PKG_CONFIG_PATH"
|
|
||||||
|
|
||||||
conf=(
|
conf=(
|
||||||
--prefix="$INSTALL_DIR/$DIRNAME"
|
--prefix="$INSTALL_DIR/$DIRNAME"
|
||||||
--pkg-config-flags="--static"
|
|
||||||
--extra-cflags="-O2 -fPIC"
|
--extra-cflags="-O2 -fPIC"
|
||||||
--disable-programs
|
--disable-programs
|
||||||
--disable-doc
|
--disable-doc
|
||||||
@ -60,11 +62,9 @@ else
|
|||||||
--disable-vaapi
|
--disable-vaapi
|
||||||
--disable-vdpau
|
--disable-vdpau
|
||||||
--enable-swresample
|
--enable-swresample
|
||||||
--enable-libdav1d
|
|
||||||
--enable-decoder=h264
|
--enable-decoder=h264
|
||||||
--enable-decoder=hevc
|
--enable-decoder=hevc
|
||||||
--enable-decoder=av1
|
--enable-decoder=av1
|
||||||
--enable-decoder=libdav1d
|
|
||||||
--enable-decoder=pcm_s16le
|
--enable-decoder=pcm_s16le
|
||||||
--enable-decoder=opus
|
--enable-decoder=opus
|
||||||
--enable-decoder=aac
|
--enable-decoder=aac
|
||||||
|
@ -5,10 +5,10 @@ cd "$DEPS_DIR"
|
|||||||
. common
|
. common
|
||||||
process_args "$@"
|
process_args "$@"
|
||||||
|
|
||||||
VERSION=2.30.10
|
VERSION=2.30.9
|
||||||
FILENAME=SDL-$VERSION.tar.gz
|
FILENAME=SDL-$VERSION.tar.gz
|
||||||
PROJECT_DIR=SDL-release-$VERSION
|
PROJECT_DIR=SDL-release-$VERSION
|
||||||
SHA256SUM=35a8b9c4f3635d85762b904ac60ca4e0806bff89faeb269caafbe80860d67168
|
SHA256SUM=682a055004081e37d81a7d4ce546c3ee3ef2e0e6a675ed2651e430ccd14eb407
|
||||||
|
|
||||||
cd "$SOURCES_DIR"
|
cd "$SOURCES_DIR"
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ BEGIN
|
|||||||
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
||||||
VALUE "OriginalFilename", "scrcpy.exe"
|
VALUE "OriginalFilename", "scrcpy.exe"
|
||||||
VALUE "ProductName", "scrcpy"
|
VALUE "ProductName", "scrcpy"
|
||||||
VALUE "ProductVersion", "3.1"
|
VALUE "ProductVersion", "3.0.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -369,12 +369,6 @@ Do not forward mouse hover (mouse motion without any clicks) events.
|
|||||||
.B \-\-no\-power\-on
|
.B \-\-no\-power\-on
|
||||||
Do not power on the device on start.
|
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
|
.TP
|
||||||
.B \-\-no\-vd\-system\-decorations
|
.B \-\-no\-vd\-system\-decorations
|
||||||
Disable virtual display system decorations flag.
|
Disable virtual display system decorations flag.
|
||||||
|
@ -110,7 +110,6 @@ enum {
|
|||||||
OPT_CAPTURE_ORIENTATION,
|
OPT_CAPTURE_ORIENTATION,
|
||||||
OPT_ANGLE,
|
OPT_ANGLE,
|
||||||
OPT_NO_VD_SYSTEM_DECORATIONS,
|
OPT_NO_VD_SYSTEM_DECORATIONS,
|
||||||
OPT_NO_VD_DESTROY_CONTENT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
@ -660,15 +659,6 @@ static const struct sc_option options[] = {
|
|||||||
.longopt = "no-power-on",
|
.longopt = "no-power-on",
|
||||||
.text = "Do not power on the device on start.",
|
.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_id = OPT_NO_VD_SYSTEM_DECORATIONS,
|
||||||
.longopt = "no-vd-system-decorations",
|
.longopt = "no-vd-system-decorations",
|
||||||
@ -2715,11 +2705,8 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
case OPT_ANGLE:
|
case OPT_ANGLE:
|
||||||
opts->angle = optarg;
|
opts->angle = optarg;
|
||||||
break;
|
break;
|
||||||
case OPT_NO_VD_DESTROY_CONTENT:
|
|
||||||
opts->vd_destroy_content = false;
|
|
||||||
break;
|
|
||||||
case OPT_NO_VD_SYSTEM_DECORATIONS:
|
case OPT_NO_VD_SYSTEM_DECORATIONS:
|
||||||
opts->vd_system_decorations = false;
|
opts->vd_system_decorations = optarg;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
|
@ -15,6 +15,9 @@ struct sc_hid_input {
|
|||||||
|
|
||||||
struct sc_hid_open {
|
struct sc_hid_open {
|
||||||
uint16_t hid_id;
|
uint16_t hid_id;
|
||||||
|
uint16_t vendor_id;
|
||||||
|
uint16_t product_id;
|
||||||
|
const char *name; // pointer to static memory
|
||||||
const uint8_t *report_desc; // pointer to static memory
|
const uint8_t *report_desc; // pointer to static memory
|
||||||
size_t report_desc_size;
|
size_t report_desc_size;
|
||||||
};
|
};
|
||||||
|
@ -236,7 +236,9 @@ sc_hid_gamepad_slot_get_id(size_t slot_idx) {
|
|||||||
bool
|
bool
|
||||||
sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
|
sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
|
||||||
struct sc_hid_open *hid_open,
|
struct sc_hid_open *hid_open,
|
||||||
uint32_t gamepad_id) {
|
uint32_t gamepad_id,
|
||||||
|
uint16_t vendor_id,
|
||||||
|
uint16_t product_id) {
|
||||||
assert(gamepad_id != SC_GAMEPAD_ID_INVALID);
|
assert(gamepad_id != SC_GAMEPAD_ID_INVALID);
|
||||||
ssize_t slot_idx = sc_hid_gamepad_slot_find(hid, SC_GAMEPAD_ID_INVALID);
|
ssize_t slot_idx = sc_hid_gamepad_slot_find(hid, SC_GAMEPAD_ID_INVALID);
|
||||||
if (slot_idx == -1) {
|
if (slot_idx == -1) {
|
||||||
@ -246,8 +248,16 @@ sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
|
|||||||
|
|
||||||
sc_hid_gamepad_slot_init(&hid->slots[slot_idx], gamepad_id);
|
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);
|
uint16_t hid_id = sc_hid_gamepad_slot_get_id(slot_idx);
|
||||||
hid_open->hid_id = hid_id;
|
hid_open->hid_id = hid_id;
|
||||||
|
hid_open->vendor_id = vendor_id;
|
||||||
|
hid_open->product_id = product_id;
|
||||||
|
hid_open->name = name;
|
||||||
hid_open->report_desc = SC_HID_GAMEPAD_REPORT_DESC;
|
hid_open->report_desc = SC_HID_GAMEPAD_REPORT_DESC;
|
||||||
hid_open->report_desc_size = sizeof(SC_HID_GAMEPAD_REPORT_DESC);
|
hid_open->report_desc_size = sizeof(SC_HID_GAMEPAD_REPORT_DESC);
|
||||||
|
|
||||||
|
@ -33,7 +33,9 @@ sc_hid_gamepad_init(struct sc_hid_gamepad *hid);
|
|||||||
bool
|
bool
|
||||||
sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
|
sc_hid_gamepad_generate_open(struct sc_hid_gamepad *hid,
|
||||||
struct sc_hid_open *hid_open,
|
struct sc_hid_open *hid_open,
|
||||||
uint32_t gamepad_id);
|
uint32_t gamepad_id,
|
||||||
|
uint16_t vendor_id,
|
||||||
|
uint16_t product_id);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_hid_gamepad_generate_close(struct sc_hid_gamepad *hid,
|
sc_hid_gamepad_generate_close(struct sc_hid_gamepad *hid,
|
||||||
|
@ -335,6 +335,9 @@ 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) {
|
void sc_hid_keyboard_generate_open(struct sc_hid_open *hid_open) {
|
||||||
hid_open->hid_id = SC_HID_ID_KEYBOARD;
|
hid_open->hid_id = SC_HID_ID_KEYBOARD;
|
||||||
|
hid_open->vendor_id = 0;
|
||||||
|
hid_open->product_id = 0;
|
||||||
|
hid_open->name = NULL; // No name specified after "scrcpy"
|
||||||
hid_open->report_desc = SC_HID_KEYBOARD_REPORT_DESC;
|
hid_open->report_desc = SC_HID_KEYBOARD_REPORT_DESC;
|
||||||
hid_open->report_desc_size = sizeof(SC_HID_KEYBOARD_REPORT_DESC);
|
hid_open->report_desc_size = sizeof(SC_HID_KEYBOARD_REPORT_DESC);
|
||||||
}
|
}
|
||||||
|
@ -190,6 +190,9 @@ 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) {
|
void sc_hid_mouse_generate_open(struct sc_hid_open *hid_open) {
|
||||||
hid_open->hid_id = SC_HID_ID_MOUSE;
|
hid_open->hid_id = SC_HID_ID_MOUSE;
|
||||||
|
hid_open->vendor_id = 0;
|
||||||
|
hid_open->product_id = 0;
|
||||||
|
hid_open->name = NULL; // No name specified after "scrcpy"
|
||||||
hid_open->report_desc = SC_HID_MOUSE_REPORT_DESC;
|
hid_open->report_desc = SC_HID_MOUSE_REPORT_DESC;
|
||||||
hid_open->report_desc_size = sizeof(SC_HID_MOUSE_REPORT_DESC);
|
hid_open->report_desc_size = sizeof(SC_HID_MOUSE_REPORT_DESC);
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,11 @@ struct sc_touch_event {
|
|||||||
// invalid ID.
|
// invalid ID.
|
||||||
#define SC_GAMEPAD_ID_INVALID UINT32_C(-1)
|
#define SC_GAMEPAD_ID_INVALID UINT32_C(-1)
|
||||||
|
|
||||||
struct sc_gamepad_device_event {
|
struct sc_gamepad_added_event {
|
||||||
|
uint32_t gamepad_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_gamepad_removed_event {
|
||||||
uint32_t gamepad_id;
|
uint32_t gamepad_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -922,7 +922,7 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_gamepad_device_event evt = {
|
struct sc_gamepad_added_event evt = {
|
||||||
.gamepad_id = SDL_JoystickInstanceID(joystick),
|
.gamepad_id = SDL_JoystickInstanceID(joystick),
|
||||||
};
|
};
|
||||||
im->gp->ops->process_gamepad_added(im->gp, &evt);
|
im->gp->ops->process_gamepad_added(im->gp, &evt);
|
||||||
@ -936,7 +936,7 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
|
|||||||
LOGW("Unknown gamepad device removed");
|
LOGW("Unknown gamepad device removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_gamepad_device_event evt = {
|
struct sc_gamepad_removed_event evt = {
|
||||||
.gamepad_id = id,
|
.gamepad_id = id,
|
||||||
};
|
};
|
||||||
im->gp->ops->process_gamepad_removed(im->gp, &evt);
|
im->gp->ops->process_gamepad_removed(im->gp, &evt);
|
||||||
|
@ -108,7 +108,6 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||||||
.new_display = NULL,
|
.new_display = NULL,
|
||||||
.start_app = NULL,
|
.start_app = NULL,
|
||||||
.angle = NULL,
|
.angle = NULL,
|
||||||
.vd_destroy_content = true,
|
|
||||||
.vd_system_decorations = true,
|
.vd_system_decorations = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -310,7 +310,6 @@ struct scrcpy_options {
|
|||||||
bool audio_dup;
|
bool audio_dup;
|
||||||
const char *new_display; // [<width>x<height>][/<dpi>] parsed by the server
|
const char *new_display; // [<width>x<height>][/<dpi>] parsed by the server
|
||||||
const char *start_app;
|
const char *start_app;
|
||||||
bool vd_destroy_content;
|
|
||||||
bool vd_system_decorations;
|
bool vd_system_decorations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -458,7 +458,6 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
.power_on = options->power_on,
|
.power_on = options->power_on,
|
||||||
.kill_adb_on_close = options->kill_adb_on_close,
|
.kill_adb_on_close = options->kill_adb_on_close,
|
||||||
.camera_high_speed = options->camera_high_speed,
|
.camera_high_speed = options->camera_high_speed,
|
||||||
.vd_destroy_content = options->vd_destroy_content,
|
|
||||||
.vd_system_decorations = options->vd_system_decorations,
|
.vd_system_decorations = options->vd_system_decorations,
|
||||||
.list = options->list,
|
.list = options->list,
|
||||||
};
|
};
|
||||||
|
@ -377,9 +377,6 @@ execute_server(struct sc_server *server,
|
|||||||
VALIDATE_STRING(params->new_display);
|
VALIDATE_STRING(params->new_display);
|
||||||
ADD_PARAM("new_display=%s", 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) {
|
if (!params->vd_system_decorations) {
|
||||||
ADD_PARAM("vd_system_decorations=false");
|
ADD_PARAM("vd_system_decorations=false");
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,6 @@ struct sc_server_params {
|
|||||||
bool power_on;
|
bool power_on;
|
||||||
bool kill_adb_on_close;
|
bool kill_adb_on_close;
|
||||||
bool camera_high_speed;
|
bool camera_high_speed;
|
||||||
bool vd_destroy_content;
|
|
||||||
bool vd_system_decorations;
|
bool vd_system_decorations;
|
||||||
uint8_t list;
|
uint8_t list;
|
||||||
};
|
};
|
||||||
|
@ -20,22 +20,22 @@ struct sc_gamepad_processor {
|
|||||||
struct sc_gamepad_processor_ops {
|
struct sc_gamepad_processor_ops {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a gamepad device added event
|
* Process a gamepad device added
|
||||||
*
|
*
|
||||||
* This function is mandatory.
|
* This function is mandatory.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
(*process_gamepad_added)(struct sc_gamepad_processor *gp,
|
(*process_gamepad_added)(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event);
|
const struct sc_gamepad_added_event *event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a gamepad device removed event
|
* Process a gamepad device removed
|
||||||
*
|
*
|
||||||
* This function is mandatory.
|
* This function is mandatory.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
(*process_gamepad_removed)(struct sc_gamepad_processor *gp,
|
(*process_gamepad_removed)(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event);
|
const struct sc_gamepad_removed_event *event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a gamepad axis event
|
* Process a gamepad axis event
|
||||||
|
@ -7,10 +7,8 @@
|
|||||||
/** Downcast gamepad processor to sc_gamepad_uhid */
|
/** Downcast gamepad processor to sc_gamepad_uhid */
|
||||||
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_uhid, gamepad_processor)
|
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_uhid, gamepad_processor)
|
||||||
|
|
||||||
// Xbox 360
|
#define SC_GAMEPAD_UHID_VENDOR_ID 0
|
||||||
#define SC_GAMEPAD_UHID_VENDOR_ID UINT16_C(0x045e)
|
#define SC_GAMEPAD_UHID_PRODUCT_ID 0
|
||||||
#define SC_GAMEPAD_UHID_PRODUCT_ID UINT16_C(0x028e)
|
|
||||||
#define SC_GAMEPAD_UHID_NAME "Microsoft X-Box 360 Pad"
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_gamepad_uhid_send_input(struct sc_gamepad_uhid *gamepad,
|
sc_gamepad_uhid_send_input(struct sc_gamepad_uhid *gamepad,
|
||||||
@ -35,9 +33,9 @@ sc_gamepad_uhid_send_open(struct sc_gamepad_uhid *gamepad,
|
|||||||
struct sc_control_msg msg;
|
struct sc_control_msg msg;
|
||||||
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
||||||
msg.uhid_create.id = hid_open->hid_id;
|
msg.uhid_create.id = hid_open->hid_id;
|
||||||
msg.uhid_create.vendor_id = SC_GAMEPAD_UHID_VENDOR_ID;
|
msg.uhid_create.vendor_id = hid_open->vendor_id;
|
||||||
msg.uhid_create.product_id = SC_GAMEPAD_UHID_PRODUCT_ID;
|
msg.uhid_create.product_id = hid_open->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 = hid_open->report_desc;
|
||||||
msg.uhid_create.report_desc_size = hid_open->report_desc_size;
|
msg.uhid_create.report_desc_size = hid_open->report_desc_size;
|
||||||
|
|
||||||
@ -60,27 +58,23 @@ sc_gamepad_uhid_send_close(struct sc_gamepad_uhid *gamepad,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
|
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event) {
|
const struct sc_gamepad_added_event *event) {
|
||||||
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
|
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
|
||||||
|
|
||||||
struct sc_hid_open hid_open;
|
struct sc_hid_open hid_open;
|
||||||
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
|
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
|
||||||
event->gamepad_id)) {
|
event->gamepad_id,
|
||||||
|
SC_GAMEPAD_UHID_VENDOR_ID,
|
||||||
|
SC_GAMEPAD_UHID_PRODUCT_ID)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
sc_gamepad_uhid_send_open(gamepad, &hid_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
|
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event) {
|
const struct sc_gamepad_removed_event *event) {
|
||||||
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
|
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
|
||||||
|
|
||||||
struct sc_hid_close hid_close;
|
struct sc_hid_close hid_close;
|
||||||
@ -89,8 +83,6 @@ sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Gamepad removed: [%" PRIu32 "]", event->gamepad_id);
|
|
||||||
|
|
||||||
sc_gamepad_uhid_send_close(gamepad, &hid_close);
|
sc_gamepad_uhid_send_close(gamepad, &hid_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,9 +141,9 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb,
|
|||||||
struct sc_control_msg msg;
|
struct sc_control_msg msg;
|
||||||
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
||||||
msg.uhid_create.id = SC_HID_ID_KEYBOARD;
|
msg.uhid_create.id = SC_HID_ID_KEYBOARD;
|
||||||
msg.uhid_create.vendor_id = 0;
|
msg.uhid_create.vendor_id = hid_open.vendor_id;
|
||||||
msg.uhid_create.product_id = 0;
|
msg.uhid_create.product_id = hid_open.product_id;
|
||||||
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 = hid_open.report_desc;
|
||||||
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
|
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
|
||||||
if (!sc_controller_push_msg(controller, &msg)) {
|
if (!sc_controller_push_msg(controller, &msg)) {
|
||||||
|
@ -81,9 +81,9 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
|
|||||||
struct sc_control_msg msg;
|
struct sc_control_msg msg;
|
||||||
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
||||||
msg.uhid_create.id = SC_HID_ID_MOUSE;
|
msg.uhid_create.id = SC_HID_ID_MOUSE;
|
||||||
msg.uhid_create.vendor_id = 0;
|
msg.uhid_create.vendor_id = hid_open.vendor_id;
|
||||||
msg.uhid_create.product_id = 0;
|
msg.uhid_create.product_id = hid_open.product_id;
|
||||||
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 = hid_open.report_desc;
|
||||||
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
|
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
|
||||||
if (!sc_controller_push_msg(controller, &msg)) {
|
if (!sc_controller_push_msg(controller, &msg)) {
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
|
sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event) {
|
const struct sc_gamepad_added_event *event) {
|
||||||
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
|
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
|
||||||
|
|
||||||
struct sc_hid_open hid_open;
|
struct sc_hid_open hid_open;
|
||||||
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
|
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
|
||||||
event->gamepad_id)) {
|
event->gamepad_id, 0, 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
|
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
|
||||||
const struct sc_gamepad_device_event *event) {
|
const struct sc_gamepad_removed_event *event) {
|
||||||
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
|
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
|
||||||
|
|
||||||
struct sc_hid_close hid_close;
|
struct sc_hid_close hid_close;
|
||||||
|
@ -189,7 +189,7 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_gamepad_device_event evt = {
|
struct sc_gamepad_added_event evt = {
|
||||||
.gamepad_id = SDL_JoystickInstanceID(joystick),
|
.gamepad_id = SDL_JoystickInstanceID(joystick),
|
||||||
};
|
};
|
||||||
gp->ops->process_gamepad_added(gp, &evt);
|
gp->ops->process_gamepad_added(gp, &evt);
|
||||||
@ -203,7 +203,7 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
|
|||||||
LOGW("Unknown gamepad device removed");
|
LOGW("Unknown gamepad device removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_gamepad_device_event evt = {
|
struct sc_gamepad_removed_event evt = {
|
||||||
.gamepad_id = id,
|
.gamepad_id = id,
|
||||||
};
|
};
|
||||||
gp->ops->process_gamepad_removed(gp, &evt);
|
gp->ops->process_gamepad_removed(gp, &evt);
|
||||||
|
@ -233,10 +233,10 @@ install` must be run as root)._
|
|||||||
|
|
||||||
#### Option 2: Use prebuilt server
|
#### Option 2: Use prebuilt server
|
||||||
|
|
||||||
- [`scrcpy-server-v3.1`][direct-scrcpy-server]
|
- [`scrcpy-server-v3.0.2`][direct-scrcpy-server]
|
||||||
<sub>SHA-256: `958f0944a62f23b1f33a16e9eb14844c1a04b882ca175a738c16d23cb22b86c0`</sub>
|
<sub>SHA-256: `e19fe024bfa3367809494407ad6ca809a6f6e77dac95e99f85ba75144e0ba35d`</sub>
|
||||||
|
|
||||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-server-v3.1
|
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-server-v3.0.2
|
||||||
|
|
||||||
Download the prebuilt server somewhere, and specify its path during the Meson
|
Download the prebuilt server somewhere, and specify its path during the Meson
|
||||||
configuration:
|
configuration:
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
Download a static build of the [latest release]:
|
Download a static build of the [latest release]:
|
||||||
|
|
||||||
- [`scrcpy-linux-x86_64-v3.1.tar.gz`][direct-linux-x86_64] (x86_64)
|
- [`scrcpy-linux-x86_64-v3.0.2.tar.gz`][direct-linux-x86_64] (x86_64)
|
||||||
<sub>SHA-256: `37dba54092ed9ec6b2f8f95432f61b8ea124aec9f1e9f2b3d22d4b10bb04c59a`</sub>
|
<sub>SHA-256: `20b69dcd379bb7d7208bf1e4858cf04162fc856697be0e6c03863d7b3c1e734a`</sub>
|
||||||
|
|
||||||
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
||||||
[direct-linux-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-linux-x86_64-v3.1.tar.gz
|
[direct-linux-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-linux-x86_64-v3.0.2.tar.gz
|
||||||
|
|
||||||
and extract it.
|
and extract it.
|
||||||
|
|
||||||
|
12
doc/macos.md
12
doc/macos.md
@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
Download a static build of the [latest release]:
|
Download a static build of the [latest release]:
|
||||||
|
|
||||||
- [`scrcpy-macos-aarch64-v3.1.tar.gz`][direct-macos-aarch64] (aarch64)
|
- [`scrcpy-macos-aarch64-v3.0.2.tar.gz`][direct-macos-aarch64] (aarch64)
|
||||||
<sub>SHA-256: `478618d940421e5f57942f5479d493ecbb38210682937a200f712aee5f235daf`</sub>
|
<sub>SHA-256: `811ba2f4e856146bdd161e24c3490d78efbec2339ca783fac791d041c0aecfb6`</sub>
|
||||||
|
|
||||||
- [`scrcpy-macos-x86_64-v3.1.tar.gz`][direct-macos-x86_64] (x86_64)
|
- [`scrcpy-macos-x86_64-v3.0.2.tar.gz`][direct-macos-x86_64] (x86_64)
|
||||||
<sub>SHA-256: `acde98e29c273710ffa469371dbca4a728a44c41c380381f8a54e5b5301b9e87`</sub>
|
<sub>SHA-256: `8effff54dca3a3e46eaaec242771a13a7f81af2e18670b3d0d8ed6b461bb4f79`</sub>
|
||||||
|
|
||||||
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
||||||
[direct-macos-aarch64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-macos-aarch64-v3.1.tar.gz
|
[direct-macos-aarch64]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-macos-aarch64-v3.0.2.tar.gz
|
||||||
[direct-macos-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-macos-x86_64-v3.1.tar.gz
|
[direct-macos-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-macos-x86_64-v3.0.2.tar.gz
|
||||||
|
|
||||||
and extract it.
|
and extract it.
|
||||||
|
|
||||||
|
@ -50,14 +50,3 @@ any default launcher UI available in virtual displays.
|
|||||||
|
|
||||||
Note that if no app is started, no content will be rendered, so no video frame
|
Note that if no app is started, no content will be rendered, so no video frame
|
||||||
will be produced at all.
|
will be produced at all.
|
||||||
|
|
||||||
|
|
||||||
## Destroy on close
|
|
||||||
|
|
||||||
By default, when the virtual display is closed, the running apps are destroyed.
|
|
||||||
|
|
||||||
To move them to the main display instead, use:
|
|
||||||
|
|
||||||
```
|
|
||||||
scrcpy --new-display --no-vd-destroy-content
|
|
||||||
```
|
|
||||||
|
@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
Download the [latest release]:
|
Download the [latest release]:
|
||||||
|
|
||||||
- [`scrcpy-win64-v3.1.zip`][direct-win64] (64-bit)
|
- [`scrcpy-win64-v3.0.2.zip`][direct-win64] (64-bit)
|
||||||
<sub>SHA-256: `0c05ea395d95cfe36bee974eeb435a3db87ea5594ff738370d5dc3068a9538ca`</sub>
|
<sub>SHA-256: `f0de59f5d46127c87cd822d39d6665e016b86db4cd048101b262f6adb6766832`</sub>
|
||||||
- [`scrcpy-win32-v3.1.zip`][direct-win32] (32-bit)
|
- [`scrcpy-win32-v3.0.2.zip`][direct-win32] (32-bit)
|
||||||
<sub>SHA-256: `2b4674ef76719680ac5a9b482d1943bdde3fa25821ad2e98f3c40c347d00d560`</sub>
|
<sub>SHA-256: `8db8d4984d642012c55802de71f507f8ff9f68a8cfed456d7a1982d47e065f64`</sub>
|
||||||
|
|
||||||
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
||||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-win64-v3.1.zip
|
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-win64-v3.0.2.zip
|
||||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-win32-v3.1.zip
|
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-win32-v3.0.2.zip
|
||||||
|
|
||||||
and extract it.
|
and extract it.
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
BUILDDIR=build-auto
|
BUILDDIR=build-auto
|
||||||
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-server-v3.1
|
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v3.0.2/scrcpy-server-v3.0.2
|
||||||
PREBUILT_SERVER_SHA256=958f0944a62f23b1f33a16e9eb14844c1a04b882ca175a738c16d23cb22b86c0
|
PREBUILT_SERVER_SHA256=e19fe024bfa3367809494407ad6ca809a6f6e77dac95e99f85ba75144e0ba35d
|
||||||
|
|
||||||
echo "[scrcpy] Downloading prebuilt server..."
|
echo "[scrcpy] Downloading prebuilt server..."
|
||||||
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
project('scrcpy', 'c',
|
project('scrcpy', 'c',
|
||||||
version: '3.1',
|
version: '3.0.2',
|
||||||
meson_version: '>= 0.48',
|
meson_version: '>= 0.48',
|
||||||
default_options: [
|
default_options: [
|
||||||
'c_std=c11',
|
'c_std=c11',
|
||||||
|
@ -15,7 +15,6 @@ LINUX_BUILD_DIR="$WORK_DIR/build-linux-$ARCH"
|
|||||||
|
|
||||||
app/deps/adb_linux.sh
|
app/deps/adb_linux.sh
|
||||||
app/deps/sdl.sh linux native static
|
app/deps/sdl.sh linux native static
|
||||||
app/deps/dav1d.sh linux native static
|
|
||||||
app/deps/ffmpeg.sh linux native static
|
app/deps/ffmpeg.sh linux native static
|
||||||
app/deps/libusb.sh linux native static
|
app/deps/libusb.sh linux native static
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ MACOS_BUILD_DIR="$WORK_DIR/build-macos-$ARCH"
|
|||||||
|
|
||||||
app/deps/adb_macos.sh
|
app/deps/adb_macos.sh
|
||||||
app/deps/sdl.sh macos native static
|
app/deps/sdl.sh macos native static
|
||||||
app/deps/dav1d.sh macos native static
|
|
||||||
app/deps/ffmpeg.sh macos native static
|
app/deps/ffmpeg.sh macos native static
|
||||||
app/deps/libusb.sh macos native static
|
app/deps/libusb.sh macos native static
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ WINXX_BUILD_DIR="$WORK_DIR/build-$WINXX"
|
|||||||
|
|
||||||
app/deps/adb_windows.sh
|
app/deps/adb_windows.sh
|
||||||
app/deps/sdl.sh $WINXX cross shared
|
app/deps/sdl.sh $WINXX cross shared
|
||||||
app/deps/dav1d.sh $WINXX cross shared
|
|
||||||
app/deps/ffmpeg.sh $WINXX cross shared
|
app/deps/ffmpeg.sh $WINXX cross shared
|
||||||
app/deps/libusb.sh $WINXX cross shared
|
app/deps/libusb.sh $WINXX cross shared
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ android {
|
|||||||
applicationId "com.genymobile.scrcpy"
|
applicationId "com.genymobile.scrcpy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode 30100
|
versionCode 30002
|
||||||
versionName "3.1"
|
versionName "3.0.2"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
SCRCPY_DEBUG=false
|
SCRCPY_DEBUG=false
|
||||||
SCRCPY_VERSION_NAME=3.1
|
SCRCPY_VERSION_NAME=3.0.2
|
||||||
|
|
||||||
PLATFORM=${ANDROID_PLATFORM:-35}
|
PLATFORM=${ANDROID_PLATFORM:-35}
|
||||||
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-35.0.0}
|
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-35.0.0}
|
||||||
|
@ -6,8 +6,6 @@ import com.genymobile.scrcpy.util.Settings;
|
|||||||
import com.genymobile.scrcpy.util.SettingsException;
|
import com.genymobile.scrcpy.util.SettingsException;
|
||||||
|
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.system.ErrnoException;
|
|
||||||
import android.system.Os;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -26,7 +24,6 @@ public final class CleanUp {
|
|||||||
private boolean pendingRestoreDisplayPower;
|
private boolean pendingRestoreDisplayPower;
|
||||||
|
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private boolean interrupted;
|
|
||||||
|
|
||||||
private CleanUp(Options options) {
|
private CleanUp(Options options) {
|
||||||
thread = new Thread(() -> runCleanUp(options), "cleanup");
|
thread = new Thread(() -> runCleanUp(options), "cleanup");
|
||||||
@ -37,10 +34,8 @@ public final class CleanUp {
|
|||||||
return new CleanUp(options);
|
return new CleanUp(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void interrupt() {
|
public void interrupt() {
|
||||||
// Do not use thread.interrupt() because only the wait() call must be interrupted, not Command.exec()
|
thread.interrupt();
|
||||||
interrupted = true;
|
|
||||||
notify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join() throws InterruptedException {
|
public void join() throws InterruptedException {
|
||||||
@ -102,13 +97,15 @@ public final class CleanUp {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout);
|
run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Ln.e("Clean up I/O exception", e);
|
Ln.e("Clean up I/O exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen, int restoreScreenOffTimeout)
|
private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen, int restoreScreenOffTimeout)
|
||||||
throws IOException {
|
throws IOException, InterruptedException {
|
||||||
String[] cmd = {
|
String[] cmd = {
|
||||||
"app_process",
|
"app_process",
|
||||||
"/",
|
"/",
|
||||||
@ -129,15 +126,8 @@ public final class CleanUp {
|
|||||||
int localPendingChanges;
|
int localPendingChanges;
|
||||||
boolean localPendingRestoreDisplayPower;
|
boolean localPendingRestoreDisplayPower;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
while (!interrupted && pendingChanges == 0) {
|
while (pendingChanges == 0) {
|
||||||
try {
|
wait();
|
||||||
wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new AssertionError("Clean up thread MUST NOT be interrupted");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (interrupted) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
localPendingChanges = pendingChanges;
|
localPendingChanges = pendingChanges;
|
||||||
localPendingRestoreDisplayPower = pendingRestoreDisplayPower;
|
localPendingRestoreDisplayPower = pendingRestoreDisplayPower;
|
||||||
@ -165,12 +155,6 @@ public final class CleanUp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
try {
|
|
||||||
// Start a new session to avoid being terminated along with the server process on some devices
|
|
||||||
Os.setsid();
|
|
||||||
} catch (ErrnoException e) {
|
|
||||||
Ln.e("setsid() failed", e);
|
|
||||||
}
|
|
||||||
unlinkSelf();
|
unlinkSelf();
|
||||||
|
|
||||||
int displayId = Integer.parseInt(args[0]);
|
int displayId = Integer.parseInt(args[0]);
|
||||||
|
@ -60,7 +60,6 @@ public class Options {
|
|||||||
private boolean powerOn = true;
|
private boolean powerOn = true;
|
||||||
|
|
||||||
private NewDisplay newDisplay;
|
private NewDisplay newDisplay;
|
||||||
private boolean vdDestroyContent = true;
|
|
||||||
private boolean vdSystemDecorations = true;
|
private boolean vdSystemDecorations = true;
|
||||||
|
|
||||||
private Orientation.Lock captureOrientationLock = Orientation.Lock.Unlocked;
|
private Orientation.Lock captureOrientationLock = Orientation.Lock.Unlocked;
|
||||||
@ -234,10 +233,6 @@ public class Options {
|
|||||||
return captureOrientationLock;
|
return captureOrientationLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getVDDestroyContent() {
|
|
||||||
return vdDestroyContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getVDSystemDecorations() {
|
public boolean getVDSystemDecorations() {
|
||||||
return vdSystemDecorations;
|
return vdSystemDecorations;
|
||||||
}
|
}
|
||||||
@ -471,9 +466,6 @@ public class Options {
|
|||||||
case "new_display":
|
case "new_display":
|
||||||
options.newDisplay = parseNewDisplay(value);
|
options.newDisplay = parseNewDisplay(value);
|
||||||
break;
|
break;
|
||||||
case "vd_destroy_content":
|
|
||||||
options.vdDestroyContent = Boolean.parseBoolean(value);
|
|
||||||
break;
|
|
||||||
case "vd_system_decorations":
|
case "vd_system_decorations":
|
||||||
options.vdSystemDecorations = Boolean.parseBoolean(value);
|
options.vdSystemDecorations = Boolean.parseBoolean(value);
|
||||||
break;
|
break;
|
||||||
|
@ -174,7 +174,7 @@ public final class UhidManager {
|
|||||||
ByteBuffer buf = ByteBuffer.allocate(280 + reportDesc.length).order(ByteOrder.nativeOrder());
|
ByteBuffer buf = ByteBuffer.allocate(280 + reportDesc.length).order(ByteOrder.nativeOrder());
|
||||||
buf.putInt(UHID_CREATE2);
|
buf.putInt(UHID_CREATE2);
|
||||||
|
|
||||||
String actualName = name.isEmpty() ? "scrcpy" : name;
|
String actualName = name.isEmpty() ? "scrcpy" : "scrcpy: " + name;
|
||||||
byte[] utf8Name = actualName.getBytes(StandardCharsets.UTF_8);
|
byte[] utf8Name = actualName.getBytes(StandardCharsets.UTF_8);
|
||||||
int len = StringUtils.getUtf8TruncationIndex(utf8Name, 127);
|
int len = StringUtils.getUtf8TruncationIndex(utf8Name, 127);
|
||||||
assert len <= 127;
|
assert len <= 127;
|
||||||
|
@ -206,10 +206,6 @@ public final class Device {
|
|||||||
|
|
||||||
// restore auto-rotate if necessary
|
// restore auto-rotate if necessary
|
||||||
if (accelerometerRotation) {
|
if (accelerometerRotation) {
|
||||||
if (displayId == 0) {
|
|
||||||
// HACK: rotation on the main display often fail on recent Android devices if thawRotation() is called immediately
|
|
||||||
SystemClock.sleep(10);
|
|
||||||
}
|
|
||||||
wm.thawRotation(displayId);
|
wm.thawRotation(displayId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||||||
private final boolean captureOrientationLocked;
|
private final boolean captureOrientationLocked;
|
||||||
private final Orientation captureOrientation;
|
private final Orientation captureOrientation;
|
||||||
private final float angle;
|
private final float angle;
|
||||||
private final boolean vdDestroyContent;
|
|
||||||
private final boolean vdSystemDecorations;
|
private final boolean vdSystemDecorations;
|
||||||
|
|
||||||
private VirtualDisplay virtualDisplay;
|
private VirtualDisplay virtualDisplay;
|
||||||
@ -74,7 +73,6 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||||||
this.captureOrientation = options.getCaptureOrientation();
|
this.captureOrientation = options.getCaptureOrientation();
|
||||||
assert captureOrientation != null;
|
assert captureOrientation != null;
|
||||||
this.angle = options.getAngle();
|
this.angle = options.getAngle();
|
||||||
this.vdDestroyContent = options.getVDDestroyContent();
|
|
||||||
this.vdSystemDecorations = options.getVDSystemDecorations();
|
this.vdSystemDecorations = options.getVDSystemDecorations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,10 +167,8 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||||||
int flags = VIRTUAL_DISPLAY_FLAG_PUBLIC
|
int flags = VIRTUAL_DISPLAY_FLAG_PUBLIC
|
||||||
| VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
|
| VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
|
||||||
| VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
|
| VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
|
||||||
| VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
|
| VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
|
||||||
if (vdDestroyContent) {
|
| VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
|
||||||
flags |= VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
|
|
||||||
}
|
|
||||||
if (vdSystemDecorations) {
|
if (vdSystemDecorations) {
|
||||||
flags |= VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
flags |= VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
||||||
}
|
}
|
||||||
|
@ -124,9 +124,15 @@ public class ScreenCapture extends SurfaceCapture {
|
|||||||
inputSize = videoSize;
|
inputSize = videoSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int virtualDisplayId;
|
||||||
|
PositionMapper positionMapper;
|
||||||
try {
|
try {
|
||||||
virtualDisplay = ServiceManager.getDisplayManager()
|
virtualDisplay = ServiceManager.getDisplayManager()
|
||||||
.createVirtualDisplay("scrcpy", inputSize.getWidth(), inputSize.getHeight(), displayId, surface);
|
.createVirtualDisplay("scrcpy", inputSize.getWidth(), inputSize.getHeight(), displayId, surface);
|
||||||
|
virtualDisplayId = virtualDisplay.getDisplay().getDisplayId();
|
||||||
|
|
||||||
|
// The positions are relative to the virtual display, not the original display (so use inputSize, not deviceSize!)
|
||||||
|
positionMapper = PositionMapper.create(videoSize, transform, inputSize);
|
||||||
Ln.d("Display: using DisplayManager API");
|
Ln.d("Display: using DisplayManager API");
|
||||||
} catch (Exception displayManagerException) {
|
} catch (Exception displayManagerException) {
|
||||||
try {
|
try {
|
||||||
@ -134,7 +140,11 @@ public class ScreenCapture extends SurfaceCapture {
|
|||||||
|
|
||||||
Size deviceSize = displayInfo.getSize();
|
Size deviceSize = displayInfo.getSize();
|
||||||
int layerStack = displayInfo.getLayerStack();
|
int layerStack = displayInfo.getLayerStack();
|
||||||
|
|
||||||
setDisplaySurface(display, surface, deviceSize.toRect(), inputSize.toRect(), layerStack);
|
setDisplaySurface(display, surface, deviceSize.toRect(), inputSize.toRect(), layerStack);
|
||||||
|
virtualDisplayId = displayId;
|
||||||
|
|
||||||
|
positionMapper = PositionMapper.create(videoSize, transform, deviceSize);
|
||||||
Ln.d("Display: using SurfaceControl API");
|
Ln.d("Display: using SurfaceControl API");
|
||||||
} catch (Exception surfaceControlException) {
|
} catch (Exception surfaceControlException) {
|
||||||
Ln.e("Could not create display using DisplayManager", displayManagerException);
|
Ln.e("Could not create display using DisplayManager", displayManagerException);
|
||||||
@ -144,18 +154,6 @@ public class ScreenCapture extends SurfaceCapture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vdListener != null) {
|
if (vdListener != null) {
|
||||||
int virtualDisplayId;
|
|
||||||
PositionMapper positionMapper;
|
|
||||||
if (virtualDisplay == null || displayId == 0) {
|
|
||||||
// Surface control or main display: send all events to the original display, relative to the device size
|
|
||||||
Size deviceSize = displayInfo.getSize();
|
|
||||||
positionMapper = PositionMapper.create(videoSize, transform, deviceSize);
|
|
||||||
virtualDisplayId = displayId;
|
|
||||||
} else {
|
|
||||||
// The positions are relative to the virtual display, not the original display (so use inputSize, not deviceSize!)
|
|
||||||
positionMapper = PositionMapper.create(videoSize, transform, inputSize);
|
|
||||||
virtualDisplayId = virtualDisplay.getDisplay().getDisplayId();
|
|
||||||
}
|
|
||||||
vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper);
|
vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import com.genymobile.scrcpy.util.Ln;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.system.Os;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@ -22,9 +21,7 @@ public final class DisplayControl {
|
|||||||
Class<?> classLoaderFactoryClass = Class.forName("com.android.internal.os.ClassLoaderFactory");
|
Class<?> classLoaderFactoryClass = Class.forName("com.android.internal.os.ClassLoaderFactory");
|
||||||
Method createClassLoaderMethod = classLoaderFactoryClass.getDeclaredMethod("createClassLoader", String.class, String.class, String.class,
|
Method createClassLoaderMethod = classLoaderFactoryClass.getDeclaredMethod("createClassLoader", String.class, String.class, String.class,
|
||||||
ClassLoader.class, int.class, boolean.class, String.class);
|
ClassLoader.class, int.class, boolean.class, String.class);
|
||||||
|
ClassLoader classLoader = (ClassLoader) createClassLoaderMethod.invoke(null, "/system/framework/services.jar", null, null,
|
||||||
String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
|
|
||||||
ClassLoader classLoader = (ClassLoader) createClassLoaderMethod.invoke(null, systemServerClasspath, null, null,
|
|
||||||
ClassLoader.getSystemClassLoader(), 0, true, null);
|
ClassLoader.getSystemClassLoader(), 0, true, null);
|
||||||
|
|
||||||
displayControlClass = classLoader.loadClass("com.android.server.display.DisplayControl");
|
displayControlClass = classLoader.loadClass("com.android.server.display.DisplayControl");
|
||||||
|
@ -322,8 +322,6 @@ public class ControlMessageReaderTest {
|
|||||||
DataOutputStream dos = new DataOutputStream(bos);
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
dos.writeByte(ControlMessage.TYPE_UHID_CREATE);
|
dos.writeByte(ControlMessage.TYPE_UHID_CREATE);
|
||||||
dos.writeShort(42); // id
|
dos.writeShort(42); // id
|
||||||
dos.writeShort(0x1234); // vendorId
|
|
||||||
dos.writeShort(0x5678); // productId
|
|
||||||
dos.writeByte(3); // name size
|
dos.writeByte(3); // name size
|
||||||
dos.write("ABC".getBytes(StandardCharsets.US_ASCII));
|
dos.write("ABC".getBytes(StandardCharsets.US_ASCII));
|
||||||
byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||||
@ -337,8 +335,6 @@ public class ControlMessageReaderTest {
|
|||||||
ControlMessage event = reader.read();
|
ControlMessage event = reader.read();
|
||||||
Assert.assertEquals(ControlMessage.TYPE_UHID_CREATE, event.getType());
|
Assert.assertEquals(ControlMessage.TYPE_UHID_CREATE, event.getType());
|
||||||
Assert.assertEquals(42, event.getId());
|
Assert.assertEquals(42, event.getId());
|
||||||
Assert.assertEquals(0x1234, event.getVendorId());
|
|
||||||
Assert.assertEquals(0x5678, event.getProductId());
|
|
||||||
Assert.assertEquals("ABC", event.getText());
|
Assert.assertEquals("ABC", event.getText());
|
||||||
Assert.assertArrayEquals(data, event.getData());
|
Assert.assertArrayEquals(data, event.getData());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user