Compare commits
7 Commits
v1.20
...
windows_in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cb14b5166 | ||
|
|
9cb8766220 | ||
|
|
fd4ec784e0 | ||
|
|
52cebe1597 | ||
|
|
6a27062f48 | ||
|
|
739ff9dce0 | ||
|
|
65b023ac6d |
6
BUILD.md
6
BUILD.md
@@ -270,10 +270,10 @@ install` must be run as root)._
|
|||||||
|
|
||||||
#### Option 2: Use prebuilt server
|
#### Option 2: Use prebuilt server
|
||||||
|
|
||||||
- [`scrcpy-server-v1.19`][direct-scrcpy-server]
|
- [`scrcpy-server-v1.20`][direct-scrcpy-server]
|
||||||
_(SHA-256: 876f9322182e6aac6a58db1334f4225855ef3a17eaebc80aab6601d9d1ecb867)_
|
_(SHA-256: b20aee4951f99b060c4a44000ba94de973f9604758ef62beb253b371aad3df34)_
|
||||||
|
|
||||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.19/scrcpy-server-v1.19
|
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.20/scrcpy-server-v1.20
|
||||||
|
|
||||||
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:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# scrcpy (v1.19)
|
# scrcpy (v1.20)
|
||||||
|
|
||||||
<img src="data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
<img src="data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
||||||
|
|
||||||
@@ -101,10 +101,10 @@ process][BUILD_simple]).
|
|||||||
For Windows, for simplicity, a prebuilt archive with all the dependencies
|
For Windows, for simplicity, a prebuilt archive with all the dependencies
|
||||||
(including `adb`) is available:
|
(including `adb`) is available:
|
||||||
|
|
||||||
- [`scrcpy-win64-v1.19.zip`][direct-win64]
|
- [`scrcpy-win64-v1.20.zip`][direct-win64]
|
||||||
_(SHA-256: 383d6483f25ac0092d4bb9fef6c967351ecd50fc248e0c82932db97d6d32f11b)_
|
_(SHA-256: 548532b616288bcaeceff6881ad5e6f0928e5ae2b48c380385f03627401cfdba)_
|
||||||
|
|
||||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.19/scrcpy-win64-v1.19.zip
|
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.20/scrcpy-win64-v1.20.zip
|
||||||
|
|
||||||
It is also available in [Chocolatey]:
|
It is also available in [Chocolatey]:
|
||||||
|
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ free_ctx:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !SDL_VERSION_ATLEAST(2, 0, 10)
|
||||||
|
// SDL_PixelFormatEnum has been introduced in SDL 2.0.10. Use int for older SDL
|
||||||
|
// versions.
|
||||||
|
typedef int SDL_PixelFormatEnum;
|
||||||
|
#endif
|
||||||
|
|
||||||
static SDL_PixelFormatEnum
|
static SDL_PixelFormatEnum
|
||||||
to_sdl_pixel_format(enum AVPixelFormat fmt) {
|
to_sdl_pixel_format(enum AVPixelFormat fmt) {
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
@@ -172,7 +178,9 @@ to_sdl_pixel_format(enum AVPixelFormat fmt) {
|
|||||||
case AV_PIX_FMT_BGR565BE: return SDL_PIXELFORMAT_BGR565;
|
case AV_PIX_FMT_BGR565BE: return SDL_PIXELFORMAT_BGR565;
|
||||||
case AV_PIX_FMT_BGR555BE: return SDL_PIXELFORMAT_BGR555;
|
case AV_PIX_FMT_BGR555BE: return SDL_PIXELFORMAT_BGR555;
|
||||||
case AV_PIX_FMT_RGB444BE: return SDL_PIXELFORMAT_RGB444;
|
case AV_PIX_FMT_RGB444BE: return SDL_PIXELFORMAT_RGB444;
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||||
case AV_PIX_FMT_BGR444BE: return SDL_PIXELFORMAT_BGR444;
|
case AV_PIX_FMT_BGR444BE: return SDL_PIXELFORMAT_BGR444;
|
||||||
|
#endif
|
||||||
case AV_PIX_FMT_PAL8: return SDL_PIXELFORMAT_INDEX8;
|
case AV_PIX_FMT_PAL8: return SDL_PIXELFORMAT_INDEX8;
|
||||||
default: return SDL_PIXELFORMAT_UNKNOWN;
|
default: return SDL_PIXELFORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,12 @@ connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay) {
|
|||||||
|
|
||||||
net_close(socket);
|
net_close(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sc_intr_is_interrupted(&server->intr)) {
|
||||||
|
// Stop immediately
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (attempts) {
|
if (attempts) {
|
||||||
sc_mutex_lock(&server->mutex);
|
sc_mutex_lock(&server->mutex);
|
||||||
sc_tick deadline = sc_tick_now() + delay;
|
sc_tick deadline = sc_tick_now() + delay;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
// <https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873>
|
||||||
|
#define _WIN32_WINNT 0x0600 // For extended process API
|
||||||
|
|
||||||
#include "util/process.h"
|
#include "util/process.h"
|
||||||
|
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -26,6 +31,9 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
|
|||||||
HANDLE *pin, HANDLE *pout, HANDLE *perr) {
|
HANDLE *pin, HANDLE *pout, HANDLE *perr) {
|
||||||
enum sc_process_result ret = SC_PROCESS_ERROR_GENERIC;
|
enum sc_process_result ret = SC_PROCESS_ERROR_GENERIC;
|
||||||
|
|
||||||
|
// Add 1 per non-NULL pointer
|
||||||
|
unsigned handle_count = !!pin + !!pout + !!perr;
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
sa.lpSecurityDescriptor = NULL;
|
sa.lpSecurityDescriptor = NULL;
|
||||||
@@ -65,45 +73,94 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STARTUPINFOW si;
|
STARTUPINFOEXW si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.StartupInfo.cb = sizeof(si);
|
||||||
if (pin || pout || perr) {
|
HANDLE handles[3];
|
||||||
si.dwFlags = STARTF_USESTDHANDLES;
|
|
||||||
|
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList = NULL;
|
||||||
|
if (handle_count) {
|
||||||
|
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||||
if (pin) {
|
if (pin) {
|
||||||
si.hStdInput = stdin_read_handle;
|
si.StartupInfo.hStdInput = stdin_read_handle;
|
||||||
}
|
}
|
||||||
if (pout) {
|
if (pout) {
|
||||||
si.hStdOutput = stdout_write_handle;
|
si.StartupInfo.hStdOutput = stdout_write_handle;
|
||||||
}
|
}
|
||||||
if (perr) {
|
if (perr) {
|
||||||
si.hStdError = stderr_write_handle;
|
si.StartupInfo.hStdError = stderr_write_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SIZE_T size;
|
||||||
|
// Call it once to know the required buffer size
|
||||||
|
BOOL ok =
|
||||||
|
InitializeProcThreadAttributeList(NULL, 1, 0, &size)
|
||||||
|
|| GetLastError() == ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
if (!ok) {
|
||||||
|
goto error_close_stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpAttributeList = malloc(size);
|
||||||
|
if (!lpAttributeList) {
|
||||||
|
goto error_close_stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = InitializeProcThreadAttributeList(lpAttributeList, 1, 0, &size);
|
||||||
|
if (!ok) {
|
||||||
|
free(lpAttributeList);
|
||||||
|
goto error_close_stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly pass the HANDLEs that must be inherited
|
||||||
|
unsigned i = 0;
|
||||||
|
if (pin) {
|
||||||
|
handles[i++] = stdin_read_handle;
|
||||||
|
}
|
||||||
|
if (pout) {
|
||||||
|
handles[i++] = stdout_write_handle;
|
||||||
|
}
|
||||||
|
if (perr) {
|
||||||
|
handles[i++] = stderr_write_handle;
|
||||||
|
}
|
||||||
|
ok = UpdateProcThreadAttribute(lpAttributeList, 0,
|
||||||
|
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
|
||||||
|
handles, handle_count * sizeof(HANDLE),
|
||||||
|
NULL, NULL);
|
||||||
|
if (!ok) {
|
||||||
|
goto error_free_attribute_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
si.lpAttributeList = lpAttributeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cmd = malloc(CMD_MAX_LEN);
|
char *cmd = malloc(CMD_MAX_LEN);
|
||||||
if (!cmd || !build_cmd(cmd, CMD_MAX_LEN, argv)) {
|
if (!cmd || !build_cmd(cmd, CMD_MAX_LEN, argv)) {
|
||||||
*handle = NULL;
|
goto error_free_attribute_list;
|
||||||
goto error_close_stderr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *wide = sc_str_to_wchars(cmd);
|
wchar_t *wide = sc_str_to_wchars(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
if (!wide) {
|
if (!wide) {
|
||||||
LOGC("Could not allocate wide char string");
|
LOGC("Could not allocate wide char string");
|
||||||
goto error_close_stderr;
|
goto error_free_attribute_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateProcessW(NULL, wide, NULL, NULL, TRUE, 0, NULL, NULL, &si,
|
BOOL bInheritHandles = handle_count > 0;
|
||||||
&pi)) {
|
DWORD dwCreationFlags = handle_count > 0 ? EXTENDED_STARTUPINFO_PRESENT : 0;
|
||||||
free(wide);
|
BOOL ok = CreateProcessW(NULL, wide, NULL, NULL, bInheritHandles,
|
||||||
*handle = NULL;
|
dwCreationFlags, NULL, NULL, &si.StartupInfo, &pi);
|
||||||
|
free(wide);
|
||||||
|
if (!ok) {
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||||
ret = SC_PROCESS_ERROR_MISSING_BINARY;
|
ret = SC_PROCESS_ERROR_MISSING_BINARY;
|
||||||
}
|
}
|
||||||
goto error_close_stderr;
|
goto error_free_attribute_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpAttributeList) {
|
||||||
|
DeleteProcThreadAttributeList(lpAttributeList);
|
||||||
|
free(lpAttributeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// These handles are used by the child process, close them for this process
|
// These handles are used by the child process, close them for this process
|
||||||
@@ -117,11 +174,15 @@ sc_process_execute_p(const char *const argv[], HANDLE *handle,
|
|||||||
CloseHandle(stderr_write_handle);
|
CloseHandle(stderr_write_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(wide);
|
|
||||||
*handle = pi.hProcess;
|
*handle = pi.hProcess;
|
||||||
|
|
||||||
return SC_PROCESS_SUCCESS;
|
return SC_PROCESS_SUCCESS;
|
||||||
|
|
||||||
|
error_free_attribute_list:
|
||||||
|
if (lpAttributeList) {
|
||||||
|
DeleteProcThreadAttributeList(lpAttributeList);
|
||||||
|
free(lpAttributeList);
|
||||||
|
}
|
||||||
error_close_stderr:
|
error_close_stderr:
|
||||||
if (perr) {
|
if (perr) {
|
||||||
CloseHandle(*perr);
|
CloseHandle(*perr);
|
||||||
@@ -168,7 +229,7 @@ sc_process_close(HANDLE handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
sc_read_pipe(HANDLE pipe, char *data, size_t len) {
|
sc_pipe_read(HANDLE pipe, char *data, size_t len) {
|
||||||
DWORD r;
|
DWORD r;
|
||||||
if (!ReadFile(pipe, data, len, &r, NULL)) {
|
if (!ReadFile(pipe, data, len, &r, NULL)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -177,7 +238,7 @@ sc_read_pipe(HANDLE pipe, char *data, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_close_pipe(HANDLE pipe) {
|
sc_pipe_close(HANDLE pipe) {
|
||||||
if (!CloseHandle(pipe)) {
|
if (!CloseHandle(pipe)) {
|
||||||
LOGW("Cannot close pipe");
|
LOGW("Cannot close pipe");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
BUILDDIR=build-auto
|
BUILDDIR=build-auto
|
||||||
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v1.19/scrcpy-server-v1.19
|
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v1.20/scrcpy-server-v1.20
|
||||||
PREBUILT_SERVER_SHA256=876f9322182e6aac6a58db1334f4225855ef3a17eaebc80aab6601d9d1ecb867
|
PREBUILT_SERVER_SHA256=b20aee4951f99b060c4a44000ba94de973f9604758ef62beb253b371aad3df34
|
||||||
|
|
||||||
echo "[scrcpy] Downloading prebuilt server..."
|
echo "[scrcpy] Downloading prebuilt server..."
|
||||||
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
||||||
|
|||||||
Reference in New Issue
Block a user