Compare commits
1 Commits
buffered_r
...
cmd_macos.
Author | SHA1 | Date | |
---|---|---|---|
f049b6bc1b |
40
README.md
40
README.md
@ -315,26 +315,26 @@ Also see [issue #14].
|
||||
|
||||
## Shortcuts
|
||||
|
||||
| Action | Shortcut |
|
||||
| -------------------------------------- |:---------------------------- |
|
||||
| Switch fullscreen mode | `Ctrl`+`f` |
|
||||
| Resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` |
|
||||
| Resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ |
|
||||
| Click on `HOME` | `Ctrl`+`h` \| _Middle-click_ |
|
||||
| Click on `BACK` | `Ctrl`+`b` \| _Right-click²_ |
|
||||
| Click on `APP_SWITCH` | `Ctrl`+`s` |
|
||||
| Click on `MENU` | `Ctrl`+`m` |
|
||||
| Click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ (`Cmd`+`↑` on macOS) |
|
||||
| Click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ (`Cmd`+`↓` on macOS) |
|
||||
| Click on `POWER` | `Ctrl`+`p` |
|
||||
| Power on | _Right-click²_ |
|
||||
| Turn device screen off (keep mirroring)| `Ctrl`+`o` |
|
||||
| Expand notification panel | `Ctrl`+`n` |
|
||||
| Collapse notification panel | `Ctrl`+`Shift`+`n` |
|
||||
| Copy device clipboard to computer | `Ctrl`+`c` |
|
||||
| Paste computer clipboard to device | `Ctrl`+`v` |
|
||||
| Copy computer clipboard to device | `Ctrl`+`Shift`+`v` |
|
||||
| Enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
|
||||
| Action | Shortcut | Shortcut (macOS)
|
||||
| -------------------------------------- |:----------------------------- |:-----------------------------
|
||||
| Switch fullscreen mode | `Ctrl`+`f` | `Cmd`+`f`
|
||||
| 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_
|
||||
| Click on `BACK` | `Ctrl`+`b` \| _Right-click²_ | `Cmd`+`b` \| _Right-click²_
|
||||
| Click on `APP_SWITCH` | `Ctrl`+`s` | `Cmd`+`s`
|
||||
| Click on `MENU` | `Ctrl`+`m` | `Ctrl`+`m`
|
||||
| Click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ | `Cmd`+`↑` _(up)_
|
||||
| Click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ | `Cmd`+`↓` _(down)_
|
||||
| Click on `POWER` | `Ctrl`+`p` | `Cmd`+`p`
|
||||
| Power on | _Right-click²_ | _Right-click²_
|
||||
| Turn device screen off (keep mirroring)| `Ctrl`+`o` | `Cmd`+`o`
|
||||
| Expand notification panel | `Ctrl`+`n` | `Cmd`+`n`
|
||||
| Collapse notification panel | `Ctrl`+`Shift`+`n` | `Cmd`+`Shift`+`n`
|
||||
| Copy device clipboard to computer | `Ctrl`+`c` | `Cmd`+`c`
|
||||
| Paste computer clipboard to device | `Ctrl`+`v` | `Cmd`+`v`
|
||||
| Copy computer clipboard to device | `Ctrl`+`Shift`+`v` | `Cmd`+`Shift`+`v`
|
||||
| Enable/disable FPS counter (on stdout) | `Ctrl`+`i` | `Cmd`+`i`
|
||||
|
||||
_¹Double-click on black borders to remove them._
|
||||
_²Right-click turns the screen on if it was off, presses BACK otherwise._
|
||||
|
@ -1,6 +1,5 @@
|
||||
src = [
|
||||
'src/main.c',
|
||||
'src/buffered_reader.c',
|
||||
'src/command.c',
|
||||
'src/control_msg.c',
|
||||
'src/controller.c',
|
||||
|
@ -1,72 +0,0 @@
|
||||
#include "buffered_reader.h"
|
||||
|
||||
#include <SDL2/SDL_assert.h>
|
||||
#include "log.h"
|
||||
|
||||
bool
|
||||
buffered_reader_init(struct buffered_reader *reader, socket_t socket,
|
||||
size_t bufsize) {
|
||||
reader->buf = SDL_malloc(bufsize);
|
||||
if (!reader->buf) {
|
||||
LOGC("Could not allocate buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
reader->socket = socket;
|
||||
reader->bufsize = bufsize;
|
||||
reader->offset = 0;
|
||||
reader->len = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
buffered_reader_destroy(struct buffered_reader *reader) {
|
||||
SDL_free(reader->buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
buffered_reader_fill(struct buffered_reader *reader) {
|
||||
SDL_assert(!reader->len);
|
||||
ssize_t r = net_recv(reader->socket, reader->buf, reader->bufsize);
|
||||
if (r > 0) {
|
||||
reader->offset = 0;
|
||||
reader->len = r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
buffered_reader_recv(struct buffered_reader *reader, void *buf, size_t count) {
|
||||
if (!reader->len) {
|
||||
// read from the socket
|
||||
ssize_t r = buffered_reader_fill(reader);
|
||||
if (r <= 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
size_t r = count < reader->len ? count : reader->len;
|
||||
memcpy(buf, reader->buf + reader->offset, r);
|
||||
reader->offset += r;
|
||||
reader->len -= r;
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
buffered_reader_recv_all(struct buffered_reader *reader, void *buf,
|
||||
size_t count) {
|
||||
size_t done = 0;
|
||||
while (done < count) {
|
||||
ssize_t r = buffered_reader_recv(reader, buf, count - done);
|
||||
if (r <= 0) {
|
||||
// if there was some data, return them immediately
|
||||
return done ? done : r;
|
||||
}
|
||||
|
||||
done += r;
|
||||
buf += r;
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#ifndef BUFFERED_READER_H
|
||||
#define BUFFERED_READER_H
|
||||
|
||||
#include "common.h"
|
||||
#include "net.h"
|
||||
|
||||
struct buffered_reader {
|
||||
socket_t socket;
|
||||
void *buf;
|
||||
size_t bufsize;
|
||||
size_t offset;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
bool
|
||||
buffered_reader_init(struct buffered_reader *reader, socket_t socket,
|
||||
size_t bufsize);
|
||||
|
||||
void
|
||||
buffered_reader_destroy(struct buffered_reader *reader);
|
||||
|
||||
ssize_t
|
||||
buffered_reader_recv(struct buffered_reader *reader, void *buf, size_t count);
|
||||
|
||||
ssize_t
|
||||
buffered_reader_recv_all(struct buffered_reader *reader, void *buf,
|
||||
size_t count);
|
||||
|
||||
#endif
|
@ -242,16 +242,27 @@ input_manager_process_key(struct input_manager *input_manager,
|
||||
bool alt = event->keysym.mod & (KMOD_LALT | KMOD_RALT);
|
||||
bool meta = event->keysym.mod & (KMOD_LGUI | KMOD_RGUI);
|
||||
|
||||
// use Cmd on macOS, Ctrl on other platforms
|
||||
#ifdef __APPLE__
|
||||
bool cmd = !ctrl && meta;
|
||||
#else
|
||||
if (meta) {
|
||||
// no shortcuts involve Meta on platforms other than macOS, and it must
|
||||
// not be forwarded to the device
|
||||
return;
|
||||
}
|
||||
bool cmd = ctrl; // && !meta, already guaranteed
|
||||
#endif
|
||||
|
||||
if (alt) {
|
||||
// no shortcut involves Alt or Meta, and they should not be forwarded
|
||||
// to the device
|
||||
// no shortcuts involve Alt, and it must not be forwarded to the device
|
||||
return;
|
||||
}
|
||||
|
||||
struct controller *controller = input_manager->controller;
|
||||
|
||||
// capture all Ctrl events
|
||||
if (ctrl | meta) {
|
||||
if (ctrl || cmd) {
|
||||
SDL_Keycode keycode = event->keysym.sym;
|
||||
bool down = event->type == SDL_KEYDOWN;
|
||||
int action = down ? ACTION_DOWN : ACTION_UP;
|
||||
@ -259,63 +270,59 @@ input_manager_process_key(struct input_manager *input_manager,
|
||||
bool shift = event->keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT);
|
||||
switch (keycode) {
|
||||
case SDLK_h:
|
||||
// Ctrl+h on all platform, since Cmd+h is already captured by
|
||||
// the system on macOS to hide the window
|
||||
if (control && ctrl && !meta && !shift && !repeat) {
|
||||
action_home(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_b: // fall-through
|
||||
case SDLK_BACKSPACE:
|
||||
if (control && ctrl && !meta && !shift && !repeat) {
|
||||
if (control && cmd && !shift && !repeat) {
|
||||
action_back(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_s:
|
||||
if (control && ctrl && !meta && !shift && !repeat) {
|
||||
if (control && cmd && !shift && !repeat) {
|
||||
action_app_switch(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_m:
|
||||
// Ctrl+m on all platform, since Cmd+m is already captured by
|
||||
// the system on macOS to minimize the window
|
||||
if (control && ctrl && !meta && !shift && !repeat) {
|
||||
action_menu(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_p:
|
||||
if (control && ctrl && !meta && !shift && !repeat) {
|
||||
if (control && cmd && !shift && !repeat) {
|
||||
action_power(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_o:
|
||||
if (control && ctrl && !shift && !meta && down) {
|
||||
if (control && cmd && !shift && down) {
|
||||
set_screen_power_mode(controller, SCREEN_POWER_MODE_OFF);
|
||||
}
|
||||
return;
|
||||
case SDLK_DOWN:
|
||||
#ifdef __APPLE__
|
||||
if (control && !ctrl && meta && !shift) {
|
||||
#else
|
||||
if (control && ctrl && !meta && !shift) {
|
||||
#endif
|
||||
if (control && cmd && !shift) {
|
||||
// forward repeated events
|
||||
action_volume_down(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_UP:
|
||||
#ifdef __APPLE__
|
||||
if (control && !ctrl && meta && !shift) {
|
||||
#else
|
||||
if (control && ctrl && !meta && !shift) {
|
||||
#endif
|
||||
if (control && cmd && !shift) {
|
||||
// forward repeated events
|
||||
action_volume_up(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_c:
|
||||
if (control && ctrl && !meta && !shift && !repeat && down) {
|
||||
if (control && cmd && !shift && !repeat && down) {
|
||||
request_device_clipboard(controller);
|
||||
}
|
||||
return;
|
||||
case SDLK_v:
|
||||
if (control && ctrl && !meta && !repeat && down) {
|
||||
if (control && cmd && !repeat && down) {
|
||||
if (shift) {
|
||||
// store the text in the device clipboard
|
||||
set_device_clipboard(controller);
|
||||
@ -326,29 +333,29 @@ input_manager_process_key(struct input_manager *input_manager,
|
||||
}
|
||||
return;
|
||||
case SDLK_f:
|
||||
if (ctrl && !meta && !shift && !repeat && down) {
|
||||
if (!shift && cmd && !repeat && down) {
|
||||
screen_switch_fullscreen(input_manager->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_x:
|
||||
if (ctrl && !meta && !shift && !repeat && down) {
|
||||
if (!shift && cmd && !repeat && down) {
|
||||
screen_resize_to_fit(input_manager->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_g:
|
||||
if (ctrl && !meta && !shift && !repeat && down) {
|
||||
if (!shift && cmd && !repeat && down) {
|
||||
screen_resize_to_pixel_perfect(input_manager->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_i:
|
||||
if (ctrl && !meta && !shift && !repeat && down) {
|
||||
if (!shift && cmd && !repeat && down) {
|
||||
struct fps_counter *fps_counter =
|
||||
input_manager->video_buffer->fps_counter;
|
||||
switch_fps_counter_state(fps_counter);
|
||||
}
|
||||
return;
|
||||
case SDLK_n:
|
||||
if (control && ctrl && !meta && !repeat && down) {
|
||||
if (control && cmd && !repeat && down) {
|
||||
if (shift) {
|
||||
collapse_notification_panel(controller);
|
||||
} else {
|
||||
|
@ -35,6 +35,11 @@ struct args {
|
||||
};
|
||||
|
||||
static void usage(const char *arg0) {
|
||||
#ifdef __APPLE__
|
||||
# define CTRL_OR_CMD "Cmd"
|
||||
#else
|
||||
# define CTRL_OR_CMD "Ctrl"
|
||||
#endif
|
||||
fprintf(stderr,
|
||||
"Usage: %s [options]\n"
|
||||
"\n"
|
||||
@ -115,13 +120,13 @@ static void usage(const char *arg0) {
|
||||
"\n"
|
||||
"Shortcuts:\n"
|
||||
"\n"
|
||||
" Ctrl+f\n"
|
||||
" " CTRL_OR_CMD "+f\n"
|
||||
" switch fullscreen mode\n"
|
||||
"\n"
|
||||
" Ctrl+g\n"
|
||||
" " CTRL_OR_CMD "+g\n"
|
||||
" resize window to 1:1 (pixel-perfect)\n"
|
||||
"\n"
|
||||
" Ctrl+x\n"
|
||||
" " CTRL_OR_CMD "+x\n"
|
||||
" Double-click on black borders\n"
|
||||
" resize window to remove black borders\n"
|
||||
"\n"
|
||||
@ -129,48 +134,48 @@ static void usage(const char *arg0) {
|
||||
" Middle-click\n"
|
||||
" click on HOME\n"
|
||||
"\n"
|
||||
" Ctrl+b\n"
|
||||
" Ctrl+Backspace\n"
|
||||
" " CTRL_OR_CMD "+b\n"
|
||||
" " CTRL_OR_CMD "+Backspace\n"
|
||||
" Right-click (when screen is on)\n"
|
||||
" click on BACK\n"
|
||||
"\n"
|
||||
" Ctrl+s\n"
|
||||
" " CTRL_OR_CMD "+s\n"
|
||||
" click on APP_SWITCH\n"
|
||||
"\n"
|
||||
" Ctrl+m\n"
|
||||
" click on MENU\n"
|
||||
"\n"
|
||||
" Ctrl+Up\n"
|
||||
" " CTRL_OR_CMD "+Up\n"
|
||||
" click on VOLUME_UP\n"
|
||||
"\n"
|
||||
" Ctrl+Down\n"
|
||||
" " CTRL_OR_CMD "+Down\n"
|
||||
" click on VOLUME_DOWN\n"
|
||||
"\n"
|
||||
" Ctrl+p\n"
|
||||
" " CTRL_OR_CMD "+p\n"
|
||||
" click on POWER (turn screen on/off)\n"
|
||||
"\n"
|
||||
" Right-click (when screen is off)\n"
|
||||
" power on\n"
|
||||
"\n"
|
||||
" Ctrl+o\n"
|
||||
" " CTRL_OR_CMD "+o\n"
|
||||
" turn device screen off (keep mirroring)\n"
|
||||
"\n"
|
||||
" Ctrl+n\n"
|
||||
" " CTRL_OR_CMD "+n\n"
|
||||
" expand notification panel\n"
|
||||
"\n"
|
||||
" Ctrl+Shift+n\n"
|
||||
" " CTRL_OR_CMD "+Shift+n\n"
|
||||
" collapse notification panel\n"
|
||||
"\n"
|
||||
" Ctrl+c\n"
|
||||
" " CTRL_OR_CMD "+c\n"
|
||||
" copy device clipboard to computer\n"
|
||||
"\n"
|
||||
" Ctrl+v\n"
|
||||
" " CTRL_OR_CMD "+v\n"
|
||||
" paste computer clipboard to device\n"
|
||||
"\n"
|
||||
" Ctrl+Shift+v\n"
|
||||
" " CTRL_OR_CMD "+Shift+v\n"
|
||||
" copy computer clipboard to device\n"
|
||||
"\n"
|
||||
" Ctrl+i\n"
|
||||
" " CTRL_OR_CMD "+i\n"
|
||||
" enable/disable FPS counter (print frames/second in logs)\n"
|
||||
"\n"
|
||||
" Drag & drop APK file\n"
|
||||
|
@ -297,7 +297,6 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
bool video_buffer_initialized = false;
|
||||
bool file_handler_initialized = false;
|
||||
bool recorder_initialized = false;
|
||||
bool stream_initialized = false;
|
||||
bool stream_started = false;
|
||||
bool controller_initialized = false;
|
||||
bool controller_started = false;
|
||||
@ -359,10 +358,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
|
||||
av_log_set_callback(av_log_callback);
|
||||
|
||||
if (!stream_init(&stream, server.video_socket, dec, rec)) {
|
||||
goto end;
|
||||
}
|
||||
stream_initialized = true;
|
||||
stream_init(&stream, server.video_socket, dec, rec);
|
||||
|
||||
// now we consumed the header values, the socket receives the video stream
|
||||
// start the stream
|
||||
@ -441,9 +437,6 @@ end:
|
||||
if (stream_started) {
|
||||
stream_join(&stream);
|
||||
}
|
||||
if (stream_initialized) {
|
||||
stream_destroy(&stream);
|
||||
}
|
||||
if (controller_started) {
|
||||
controller_join(&controller);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "log.h"
|
||||
#include "recorder.h"
|
||||
|
||||
#define STREAM_BUFSIZE 0x10000
|
||||
#define BUFSIZE 0x10000
|
||||
|
||||
#define HEADER_SIZE 12
|
||||
#define NO_PTS UINT64_C(-1)
|
||||
@ -37,8 +37,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||
// It is followed by <packet_size> bytes containing the packet/frame.
|
||||
|
||||
uint8_t header[HEADER_SIZE];
|
||||
ssize_t r =
|
||||
buffered_reader_recv_all(&stream->buffered_reader, header, HEADER_SIZE);
|
||||
ssize_t r = net_recv_all(stream->socket, header, HEADER_SIZE);
|
||||
if (r < HEADER_SIZE) {
|
||||
return false;
|
||||
}
|
||||
@ -52,7 +51,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r = buffered_reader_recv_all(&stream->buffered_reader, packet->data, len);
|
||||
r = net_recv_all(stream->socket, packet->data, len);
|
||||
if (r < len) {
|
||||
av_packet_unref(packet);
|
||||
return false;
|
||||
@ -268,23 +267,13 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
stream_init(struct stream *stream, socket_t socket,
|
||||
struct decoder *decoder, struct recorder *recorder) {
|
||||
if (!buffered_reader_init(&stream->buffered_reader, socket,
|
||||
STREAM_BUFSIZE)) {
|
||||
return false;
|
||||
}
|
||||
stream->socket = socket;
|
||||
stream->decoder = decoder,
|
||||
stream->recorder = recorder;
|
||||
stream->has_pending = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
stream_destroy(struct stream *stream) {
|
||||
buffered_reader_destroy(&stream->buffered_reader);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -7,14 +7,12 @@
|
||||
#include <SDL2/SDL_atomic.h>
|
||||
#include <SDL2/SDL_thread.h>
|
||||
|
||||
#include "buffered_reader.h"
|
||||
#include "net.h"
|
||||
|
||||
struct video_buffer;
|
||||
|
||||
struct stream {
|
||||
socket_t socket;
|
||||
struct buffered_reader buffered_reader;
|
||||
struct video_buffer *video_buffer;
|
||||
SDL_Thread *thread;
|
||||
struct decoder *decoder;
|
||||
@ -27,13 +25,10 @@ struct stream {
|
||||
AVPacket pending;
|
||||
};
|
||||
|
||||
bool
|
||||
void
|
||||
stream_init(struct stream *stream, socket_t socket,
|
||||
struct decoder *decoder, struct recorder *recorder);
|
||||
|
||||
void
|
||||
stream_destroy(struct stream *stream);
|
||||
|
||||
bool
|
||||
stream_start(struct stream *stream);
|
||||
|
||||
|
Reference in New Issue
Block a user