mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-03-19 18:44:26 +01:00
Compare commits
7 Commits
client_rot
...
threadwait
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb10385a2b | ||
|
|
3603939475 | ||
|
|
d76c7c3029 | ||
|
|
f2f032a494 | ||
|
|
728b976aae | ||
|
|
ff583bdde8 | ||
|
|
429153abfb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,4 +2,3 @@ build/
|
||||
/dist/
|
||||
.idea/
|
||||
.gradle/
|
||||
/x/
|
||||
|
||||
@@ -491,8 +491,6 @@ Also see [issue #14].
|
||||
| Action | Shortcut | Shortcut (macOS)
|
||||
| -------------------------------------- |:----------------------------- |:-----------------------------
|
||||
| Switch fullscreen mode | `Ctrl`+`f` | `Cmd`+`f`
|
||||
| Rotate window left | `Ctrl`+`←` _(left)_ | `Cmd`+`←` _(left)_
|
||||
| Rotate window right | `Ctrl`+`→` _(right)_ | `Cmd`+`→` _(right)_
|
||||
| Resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` | `Cmd`+`g`
|
||||
| Resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ | `Cmd`+`x` \| _Double-click¹_
|
||||
| Click on `HOME` | `Ctrl`+`h` \| _Middle-click_ | `Ctrl`+`h` \| _Middle-click_
|
||||
|
||||
@@ -166,14 +166,6 @@ Default is 0 (automatic).\n
|
||||
.B Ctrl+f
|
||||
switch fullscreen mode
|
||||
|
||||
.TP
|
||||
.B Ctrl+Left
|
||||
rotate window left
|
||||
|
||||
.TP
|
||||
.B Ctrl+Right
|
||||
rotate window right
|
||||
|
||||
.TP
|
||||
.B Ctrl+g
|
||||
resize window to 1:1 (pixel\-perfect)
|
||||
|
||||
@@ -145,12 +145,6 @@ scrcpy_print_usage(const char *arg0) {
|
||||
" " CTRL_OR_CMD "+f\n"
|
||||
" switch fullscreen mode\n"
|
||||
"\n"
|
||||
" " CTRL_OR_CMD "+Left\n"
|
||||
" rotate window left\n"
|
||||
"\n"
|
||||
" " CTRL_OR_CMD "+Right\n"
|
||||
" rotate window right\n"
|
||||
"\n"
|
||||
" " CTRL_OR_CMD "+g\n"
|
||||
" resize window to 1:1 (pixel-perfect)\n"
|
||||
"\n"
|
||||
|
||||
@@ -221,18 +221,6 @@ rotate_device(struct controller *controller) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_client_left(struct screen *screen) {
|
||||
unsigned new_rotation = (screen->rotation + 3) % 4;
|
||||
screen_set_rotation(screen, new_rotation);
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_client_right(struct screen *screen) {
|
||||
unsigned new_rotation = (screen->rotation + 1) % 4;
|
||||
screen_set_rotation(screen, new_rotation);
|
||||
}
|
||||
|
||||
void
|
||||
input_manager_process_text_input(struct input_manager *im,
|
||||
const SDL_TextInputEvent *event) {
|
||||
@@ -363,16 +351,6 @@ input_manager_process_key(struct input_manager *im,
|
||||
action_volume_up(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_LEFT:
|
||||
if (cmd && !shift && down) {
|
||||
rotate_client_left(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_RIGHT:
|
||||
if (cmd && !shift && down) {
|
||||
rotate_client_right(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_c:
|
||||
if (control && cmd && !shift && !repeat && down) {
|
||||
request_device_clipboard(controller);
|
||||
|
||||
132
app/src/screen.c
132
app/src/screen.c
@@ -15,19 +15,6 @@
|
||||
|
||||
#define DISPLAY_MARGINS 96
|
||||
|
||||
static inline struct size
|
||||
get_rotated_size(struct size size, int rotation) {
|
||||
struct size rotated_size;
|
||||
if (rotation & 1) {
|
||||
rotated_size.width = size.height;
|
||||
rotated_size.height = size.width;
|
||||
} else {
|
||||
rotated_size.width = size.width;
|
||||
rotated_size.height = size.height;
|
||||
}
|
||||
return rotated_size;
|
||||
}
|
||||
|
||||
// get the window size in a struct size
|
||||
static struct size
|
||||
get_window_size(SDL_Window *window) {
|
||||
@@ -93,8 +80,8 @@ get_preferred_display_bounds(struct size *bounds) {
|
||||
// - it keeps the aspect ratio
|
||||
// - it scales down to make it fit in the display_size
|
||||
static struct size
|
||||
get_optimal_size(struct size current_size, struct size content_size) {
|
||||
if (content_size.width == 0 || content_size.height == 0) {
|
||||
get_optimal_size(struct size current_size, struct size frame_size) {
|
||||
if (frame_size.width == 0 || frame_size.height == 0) {
|
||||
// avoid division by 0
|
||||
return current_size;
|
||||
}
|
||||
@@ -113,14 +100,14 @@ get_optimal_size(struct size current_size, struct size content_size) {
|
||||
h = MIN(current_size.height, display_size.height);
|
||||
}
|
||||
|
||||
bool keep_width = content_size.width * h > content_size.height * w;
|
||||
bool keep_width = frame_size.width * h > frame_size.height * w;
|
||||
if (keep_width) {
|
||||
// remove black borders on top and bottom
|
||||
h = content_size.height * w / content_size.width;
|
||||
h = frame_size.height * w / frame_size.width;
|
||||
} else {
|
||||
// remove black borders on left and right (or none at all if it already
|
||||
// fits)
|
||||
w = content_size.width * h / content_size.height;
|
||||
w = frame_size.width * h / frame_size.height;
|
||||
}
|
||||
|
||||
// w and h must fit into 16 bits
|
||||
@@ -130,33 +117,33 @@ get_optimal_size(struct size current_size, struct size content_size) {
|
||||
|
||||
// same as get_optimal_size(), but read the current size from the window
|
||||
static inline struct size
|
||||
get_optimal_window_size(const struct screen *screen, struct size content_size) {
|
||||
get_optimal_window_size(const struct screen *screen, struct size frame_size) {
|
||||
struct size windowed_size = get_windowed_window_size(screen);
|
||||
return get_optimal_size(windowed_size, content_size);
|
||||
return get_optimal_size(windowed_size, frame_size);
|
||||
}
|
||||
|
||||
// initially, there is no current size, so use the frame size as current size
|
||||
// req_width and req_height, if not 0, are the sizes requested by the user
|
||||
static inline struct size
|
||||
get_initial_optimal_size(struct size content_size, uint16_t req_width,
|
||||
get_initial_optimal_size(struct size frame_size, uint16_t req_width,
|
||||
uint16_t req_height) {
|
||||
struct size window_size;
|
||||
if (!req_width && !req_height) {
|
||||
window_size = get_optimal_size(content_size, content_size);
|
||||
window_size = get_optimal_size(frame_size, frame_size);
|
||||
} else {
|
||||
if (req_width) {
|
||||
window_size.width = req_width;
|
||||
} else {
|
||||
// compute from the requested height
|
||||
window_size.width = (uint32_t) req_height * content_size.width
|
||||
/ content_size.height;
|
||||
window_size.width = (uint32_t) req_height * frame_size.width
|
||||
/ frame_size.height;
|
||||
}
|
||||
if (req_height) {
|
||||
window_size.height = req_height;
|
||||
} else {
|
||||
// compute from the requested width
|
||||
window_size.height = (uint32_t) req_width * content_size.height
|
||||
/ content_size.width;
|
||||
window_size.height = (uint32_t) req_width * frame_size.height
|
||||
/ frame_size.width;
|
||||
}
|
||||
}
|
||||
return window_size;
|
||||
@@ -180,11 +167,9 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
||||
int16_t window_x, int16_t window_y, uint16_t window_width,
|
||||
uint16_t window_height, bool window_borderless) {
|
||||
screen->frame_size = frame_size;
|
||||
struct size content_size =
|
||||
get_rotated_size(frame_size, screen->rotation);
|
||||
|
||||
struct size window_size =
|
||||
get_initial_optimal_size(content_size, window_width, window_height);
|
||||
get_initial_optimal_size(frame_size, window_width, window_height);
|
||||
uint32_t window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||
#ifdef HIDPI_SUPPORT
|
||||
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
@@ -221,8 +206,8 @@ screen_init_rendering(struct screen *screen, const char *window_title,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_RenderSetLogicalSize(screen->renderer, content_size.width,
|
||||
content_size.height)) {
|
||||
if (SDL_RenderSetLogicalSize(screen->renderer, frame_size.width,
|
||||
frame_size.height)) {
|
||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
||||
screen_destroy(screen);
|
||||
return false;
|
||||
@@ -268,51 +253,13 @@ screen_destroy(struct screen *screen) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
screen_set_rotation(struct screen *screen, unsigned rotation) {
|
||||
assert(rotation < 4);
|
||||
if (rotation == screen->rotation) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct size old_content_size =
|
||||
get_rotated_size(screen->frame_size, screen->rotation);
|
||||
struct size new_content_size =
|
||||
get_rotated_size(screen->frame_size, rotation);
|
||||
|
||||
if (SDL_RenderSetLogicalSize(screen->renderer,
|
||||
new_content_size.width,
|
||||
new_content_size.height)) {
|
||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
struct size windowed_size = get_windowed_window_size(screen);
|
||||
struct size target_size = {
|
||||
.width = (uint32_t) windowed_size.width * new_content_size.width
|
||||
/ old_content_size.width,
|
||||
.height = (uint32_t) windowed_size.height * new_content_size.height
|
||||
/ old_content_size.height,
|
||||
};
|
||||
target_size = get_optimal_size(target_size, new_content_size);
|
||||
set_window_size(screen, target_size);
|
||||
|
||||
screen->rotation = rotation;
|
||||
LOGI("Client rotation set to %u", rotation);
|
||||
|
||||
screen_render(screen);
|
||||
}
|
||||
|
||||
// recreate the texture and resize the window if the frame size has changed
|
||||
static bool
|
||||
prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
||||
if (screen->frame_size.width != new_frame_size.width
|
||||
|| screen->frame_size.height != new_frame_size.height) {
|
||||
struct size new_content_size =
|
||||
get_rotated_size(new_frame_size, screen->rotation);
|
||||
if (SDL_RenderSetLogicalSize(screen->renderer,
|
||||
new_content_size.width,
|
||||
new_content_size.height)) {
|
||||
if (SDL_RenderSetLogicalSize(screen->renderer, new_frame_size.width,
|
||||
new_frame_size.height)) {
|
||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
@@ -320,16 +267,14 @@ prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
||||
// frame dimension changed, destroy texture
|
||||
SDL_DestroyTexture(screen->texture);
|
||||
|
||||
struct size content_size =
|
||||
get_rotated_size(screen->frame_size, screen->rotation);
|
||||
struct size windowed_size = get_windowed_window_size(screen);
|
||||
struct size target_size = {
|
||||
(uint32_t) windowed_size.width * new_content_size.width
|
||||
/ content_size.width,
|
||||
(uint32_t) windowed_size.height * new_content_size.height
|
||||
/ content_size.height,
|
||||
(uint32_t) windowed_size.width * new_frame_size.width
|
||||
/ screen->frame_size.width,
|
||||
(uint32_t) windowed_size.height * new_frame_size.height
|
||||
/ screen->frame_size.height,
|
||||
};
|
||||
target_size = get_optimal_size(target_size, new_content_size);
|
||||
target_size = get_optimal_size(target_size, new_frame_size);
|
||||
set_window_size(screen, target_size);
|
||||
|
||||
screen->frame_size = new_frame_size;
|
||||
@@ -374,27 +319,7 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
|
||||
void
|
||||
screen_render(struct screen *screen) {
|
||||
SDL_RenderClear(screen->renderer);
|
||||
if (screen->rotation == 0) {
|
||||
SDL_RenderCopy(screen->renderer, screen->texture, NULL, NULL);
|
||||
} else {
|
||||
double angle = 90 * screen->rotation;
|
||||
|
||||
SDL_Rect *dstrect = NULL;
|
||||
SDL_Rect rect;
|
||||
if (screen->rotation & 1) {
|
||||
struct size size =
|
||||
get_rotated_size(screen->frame_size, screen->rotation);
|
||||
rect.x = (size.width - size.height) / 2;
|
||||
rect.y = (size.height - size.width) / 2;
|
||||
rect.w = size.height;
|
||||
rect.h = size.width;
|
||||
dstrect = ▭
|
||||
}
|
||||
|
||||
// rotation in RenderCopyEx() is clockwise
|
||||
SDL_RenderCopyEx(screen->renderer, screen->texture, NULL, dstrect,
|
||||
angle, NULL, 0);
|
||||
}
|
||||
SDL_RenderCopy(screen->renderer, screen->texture, NULL, NULL);
|
||||
SDL_RenderPresent(screen->renderer);
|
||||
}
|
||||
|
||||
@@ -424,10 +349,8 @@ screen_resize_to_fit(struct screen *screen) {
|
||||
screen->maximized = false;
|
||||
}
|
||||
|
||||
struct size content_size =
|
||||
get_rotated_size(screen->frame_size, screen->rotation);
|
||||
struct size optimal_size =
|
||||
get_optimal_window_size(screen, content_size);
|
||||
get_optimal_window_size(screen, screen->frame_size);
|
||||
SDL_SetWindowSize(screen->window, optimal_size.width, optimal_size.height);
|
||||
LOGD("Resized to optimal size");
|
||||
}
|
||||
@@ -443,9 +366,8 @@ screen_resize_to_pixel_perfect(struct screen *screen) {
|
||||
screen->maximized = false;
|
||||
}
|
||||
|
||||
struct size content_size =
|
||||
get_rotated_size(screen->frame_size, screen->rotation);
|
||||
SDL_SetWindowSize(screen->window, content_size.width, content_size.height);
|
||||
SDL_SetWindowSize(screen->window, screen->frame_size.width,
|
||||
screen->frame_size.height);
|
||||
LOGD("Resized to pixel-perfect");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ struct screen {
|
||||
// Since we receive the event SIZE_CHANGED before MAXIMIZED, we must be
|
||||
// able to revert the size to its non-maximized value.
|
||||
struct size windowed_window_size_backup;
|
||||
// client rotation: 0, 1, 2 or 3 (x90 degrees clockwise)
|
||||
unsigned rotation;
|
||||
bool has_frame;
|
||||
bool fullscreen;
|
||||
bool maximized;
|
||||
@@ -46,7 +44,6 @@ struct screen {
|
||||
.width = 0, \
|
||||
.height = 0, \
|
||||
}, \
|
||||
.rotation = 0, \
|
||||
.has_frame = false, \
|
||||
.fullscreen = false, \
|
||||
.maximized = false, \
|
||||
@@ -93,10 +90,6 @@ screen_resize_to_fit(struct screen *screen);
|
||||
void
|
||||
screen_resize_to_pixel_perfect(struct screen *screen);
|
||||
|
||||
// change the client rotation (0, 1, 2 or 3, x90 degrees clockwise)
|
||||
void
|
||||
screen_set_rotation(struct screen *screen, unsigned rotation);
|
||||
|
||||
// react to window events
|
||||
void
|
||||
screen_handle_window_event(struct screen *screen, const SDL_WindowEvent *event);
|
||||
|
||||
@@ -397,7 +397,6 @@ error2:
|
||||
atomic_flag_test_and_set(&server->server_socket_closed);
|
||||
// the thread is not started, the flag could not be already set
|
||||
assert(!was_closed);
|
||||
(void) was_closed;
|
||||
close_socket(server->server_socket);
|
||||
}
|
||||
disable_tunnel(server);
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
33
gradlew
vendored
33
gradlew
vendored
@@ -125,8 +125,8 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
@@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,9 +175,14 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
3
gradlew.bat
vendored
3
gradlew.bat
vendored
@@ -29,9 +29,6 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user