Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add --window-title options with %M and %S variable replacement #606

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions app/src/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@
#include "log.h"

bool
device_read_info(socket_t device_socket, char *device_name, struct size *size) {
unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4];
device_read_info(socket_t device_socket, char *device_name, char *device_serial, struct size *size) {
unsigned char buf[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 4];
int r = net_recv_all(device_socket, buf, sizeof(buf));
if (r < DEVICE_NAME_FIELD_LENGTH + 4) {
if (r < DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 4) {
LOGE("Could not retrieve device information");
return false;
}
// in case the client sends garbage
buf[DEVICE_NAME_FIELD_LENGTH - 1] = '\0';
// strcpy is safe here, since name contains at least
// DEVICE_NAME_FIELD_LENGTH bytes and strlen(buf) < DEVICE_NAME_FIELD_LENGTH
for (int i=1; i<=DEVICE_INFO_FIELD_COUNT; i++)
buf[DEVICE_INFO_FIELD_LENGTH*i - 1] = '\0';
// strcpy is safe here, since name/serial contains at least
// DEVICE_INFO_FIELD_LENGTH bytes and strlen(buf) < DEVICE_INFO_FIELD_LENGTH
strcpy(device_name, (char *) buf);
size->width = (buf[DEVICE_NAME_FIELD_LENGTH] << 8)
| buf[DEVICE_NAME_FIELD_LENGTH + 1];
size->height = (buf[DEVICE_NAME_FIELD_LENGTH + 2] << 8)
| buf[DEVICE_NAME_FIELD_LENGTH + 3];
strcpy(device_serial, (char *) (buf+DEVICE_INFO_FIELD_LENGTH) );
size->width = (buf[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT] << 8)
| buf[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 1];
size->height = (buf[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 2] << 8)
| buf[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 3];
return true;
}
7 changes: 4 additions & 3 deletions app/src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
#include "common.h"
#include "net.h"

#define DEVICE_NAME_FIELD_LENGTH 64
#define DEVICE_INFO_FIELD_LENGTH 64
#define DEVICE_INFO_FIELD_COUNT 2
#define DEVICE_SDCARD_PATH "/sdcard/"

// name must be at least DEVICE_NAME_FIELD_LENGTH bytes
// name and serial must be at least DEVICE_INFO_FIELD_LENGTH bytes
bool
device_read_info(socket_t device_socket, char *device_name, struct size *size);
device_read_info(socket_t device_socket, char *device_name, char *device_serial, struct size *size);

#endif
13 changes: 13 additions & 0 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct args {
const char *serial;
const char *crop;
const char *record_filename;
const char *window_title;
enum recorder_format record_format;
bool fullscreen;
bool no_control;
Expand Down Expand Up @@ -103,6 +104,10 @@ static void usage(const char *arg0) {
" -v, --version\n"
" Print the version of scrcpy.\n"
"\n"
" --window-title text\n"
" Set the Window Title with some text.\n"
" Variables %%M and %%S can be used for replacement.\n"
"\n"
"Shortcuts:\n"
"\n"
" Ctrl+f\n"
Expand Down Expand Up @@ -295,6 +300,7 @@ guess_record_format(const char *filename) {
}

#define OPT_RENDER_EXPIRED_FRAMES 1000
#define OPT_WINDOW_TITLE 1001

static bool
parse_args(struct args *args, int argc, char *argv[]) {
Expand All @@ -316,6 +322,8 @@ parse_args(struct args *args, int argc, char *argv[]) {
{"show-touches", no_argument, NULL, 't'},
{"turn-screen-off", no_argument, NULL, 'S'},
{"version", no_argument, NULL, 'v'},
{"window-title", required_argument, NULL,
OPT_WINDOW_TITLE},
{NULL, 0, NULL, 0 },
};
int c;
Expand Down Expand Up @@ -378,6 +386,9 @@ parse_args(struct args *args, int argc, char *argv[]) {
case OPT_RENDER_EXPIRED_FRAMES:
args->render_expired_frames = true;
break;
case OPT_WINDOW_TITLE:
args->window_title = optarg;
break;
default:
// getopt prints the error message on stderr
return false;
Expand Down Expand Up @@ -429,6 +440,7 @@ main(int argc, char *argv[]) {
.serial = NULL,
.crop = NULL,
.record_filename = NULL,
.window_title = NULL,
.record_format = 0,
.help = false,
.version = false,
Expand Down Expand Up @@ -473,6 +485,7 @@ main(int argc, char *argv[]) {
.crop = args.crop,
.port = args.port,
.record_filename = args.record_filename,
.window_title = args.window_title,
.record_format = args.record_format,
.max_size = args.max_size,
.bit_rate = args.bit_rate,
Expand Down
15 changes: 12 additions & 3 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "screen.h"
#include "server.h"
#include "stream.h"
#include "str_util.h"
#include "tiny_xpm.h"
#include "video_buffer.h"

Expand Down Expand Up @@ -310,13 +311,14 @@ scrcpy(const struct scrcpy_options *options) {
goto end;
}

char device_name[DEVICE_NAME_FIELD_LENGTH];
char device_name[DEVICE_INFO_FIELD_LENGTH];
char device_serial[DEVICE_INFO_FIELD_LENGTH];
struct size frame_size;

// screenrecord does not send frames when the screen content does not
// change therefore, we transmit the screen size before the video stream,
// to be able to init the window immediately
if (!device_read_info(server.video_socket, device_name, &frame_size)) {
if (!device_read_info(server.video_socket, device_name, device_serial, &frame_size)) {
goto end;
}

Expand Down Expand Up @@ -380,7 +382,14 @@ scrcpy(const struct scrcpy_options *options) {
controller_started = true;
}

if (!screen_init_rendering(&screen, device_name, frame_size,
const char *window_title = device_name;
if (options->window_title) {
window_title = options->window_title;
window_title = strrep(window_title, "%M", device_name);
window_title = strrep(window_title, "%S", device_serial);
}

if (!screen_init_rendering(&screen, window_title, frame_size,
options->always_on_top)) {
goto end;
}
Expand Down
1 change: 1 addition & 0 deletions app/src/scrcpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct scrcpy_options {
const char *serial;
const char *crop;
const char *record_filename;
const char *window_title;
enum recorder_format record_format;
uint16_t port;
uint16_t max_size;
Expand Down
4 changes: 2 additions & 2 deletions app/src/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ create_texture(SDL_Renderer *renderer, struct size frame_size) {
}

bool
screen_init_rendering(struct screen *screen, const char *device_name,
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top) {
screen->frame_size = frame_size;

Expand All @@ -152,7 +152,7 @@ screen_init_rendering(struct screen *screen, const char *device_name,
#endif
}

screen->window = SDL_CreateWindow(device_name, SDL_WINDOWPOS_UNDEFINED,
screen->window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
window_size.width, window_size.height,
window_flags);
Expand Down
2 changes: 1 addition & 1 deletion app/src/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ screen_init(struct screen *screen);

// initialize screen, create window, renderer and texture (window is hidden)
bool
screen_init_rendering(struct screen *screen, const char *device_name,
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top);

// show the window
Expand Down
18 changes: 18 additions & 0 deletions app/src/str_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ xstrjoin(char *dst, const char *const tokens[], char sep, size_t n) {
return n;
}

const char *
strrep(const char *src, const char *find, const char *rep) {
char *cmp = strstr(src, find);
if (!cmp) return src;

size_t len_src = strlen(src);
size_t len_find = strlen(find);
size_t len_rep = strlen(rep);
char *tmp = SDL_malloc(len_src - len_find + len_rep + 1);

size_t i = cmp - src;
strncpy(tmp, src, i);
tmp[i]='\0';
strcat(tmp, rep);
strcat(tmp, cmp+len_find);
return tmp;
}

char *
strquote(const char *src) {
size_t len = strlen(src);
Expand Down
5 changes: 5 additions & 0 deletions app/src/str_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ xstrncpy(char *dest, const char *src, size_t n);
size_t
xstrjoin(char *dst, const char *const tokens[], char sep, size_t n);

// search for a string find within a string src and replace with rep
// returns a new string if a replacement is done
const char *
strrep(const char *src, const char *find, const char *rep);

// quote a string
// returns the new allocated string, to be freed by the caller
char *
Expand Down
25 changes: 15 additions & 10 deletions server/src/main/java/com/genymobile/scrcpy/DesktopConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

public final class DesktopConnection implements Closeable {

private static final int DEVICE_NAME_FIELD_LENGTH = 64;
private static final int DEVICE_INFO_FIELD_LENGTH = 64;
private static final int DEVICE_INFO_FIELD_COUNT = 2;

private static final String SOCKET_NAME = "scrcpy";

Expand Down Expand Up @@ -71,7 +72,7 @@ public static DesktopConnection open(Device device, boolean tunnelForward) throw

DesktopConnection connection = new DesktopConnection(videoSocket, controlSocket);
Size videoSize = device.getScreenInfo().getVideoSize();
connection.send(Device.getDeviceName(), videoSize.getWidth(), videoSize.getHeight());
connection.send(Device.getDeviceName(), Device.getDeviceSerial(), videoSize.getWidth(), videoSize.getHeight());
return connection;
}

Expand All @@ -85,18 +86,22 @@ public void close() throws IOException {
}

@SuppressWarnings("checkstyle:MagicNumber")
private void send(String deviceName, int width, int height) throws IOException {
byte[] buffer = new byte[DEVICE_NAME_FIELD_LENGTH + 4];
private void send(String deviceName, String deviceSerial, int width, int height) throws IOException {
byte[] buffer = new byte[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 4];

byte[] deviceNameBytes = deviceName.getBytes(StandardCharsets.UTF_8);
int len = StringUtils.getUtf8TruncationIndex(deviceNameBytes, DEVICE_NAME_FIELD_LENGTH - 1);
System.arraycopy(deviceNameBytes, 0, buffer, 0, len);
int lenName = StringUtils.getUtf8TruncationIndex(deviceNameBytes, DEVICE_INFO_FIELD_LENGTH - 1);
System.arraycopy(deviceNameBytes, 0, buffer, 0, lenName);
// byte[] are always 0-initialized in java, no need to set '\0' explicitly

buffer[DEVICE_NAME_FIELD_LENGTH] = (byte) (width >> 8);
buffer[DEVICE_NAME_FIELD_LENGTH + 1] = (byte) width;
buffer[DEVICE_NAME_FIELD_LENGTH + 2] = (byte) (height >> 8);
buffer[DEVICE_NAME_FIELD_LENGTH + 3] = (byte) height;
byte[] deviceSerialBytes = deviceSerial.getBytes(StandardCharsets.UTF_8);
int lenSerial = StringUtils.getUtf8TruncationIndex(deviceSerialBytes, DEVICE_INFO_FIELD_LENGTH - 1);
System.arraycopy(deviceSerialBytes, 0, buffer, DEVICE_INFO_FIELD_LENGTH, lenSerial);

buffer[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT] = (byte) (width >> 8);
buffer[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 1] = (byte) width;
buffer[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 2] = (byte) (height >> 8);
buffer[DEVICE_INFO_FIELD_LENGTH*DEVICE_INFO_FIELD_COUNT + 3] = (byte) height;
IO.writeFully(videoFd, buffer, 0, buffer.length);
}

Expand Down
3 changes: 3 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Device.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ public static String getDeviceName() {
return Build.MODEL;
}

public static String getDeviceSerial() {
return ( Build.VERSION.SDK_INT >= 26 ? Build.getSerial() : Build.SERIAL );
}
public boolean injectInputEvent(InputEvent inputEvent, int mode) {
return serviceManager.getInputManager().injectInputEvent(inputEvent, mode);
}
Expand Down