Compare commits
22 Commits
v1.3
...
rawkeyeven
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cd1e39766 | ||
|
|
9de332bbe5 | ||
|
|
3b5e54278e | ||
|
|
dd3ba685e4 | ||
|
|
89e0203682 | ||
|
|
536b31829a | ||
|
|
f3f704d1ed | ||
|
|
6581f9feb9 | ||
|
|
359685b1db | ||
|
|
4527be4cde | ||
|
|
92d1aff85f | ||
|
|
66f45f9dae | ||
|
|
aa97eed24b | ||
|
|
2daeb1fd5f | ||
|
|
cde0b3d248 | ||
|
|
6fa209fa82 | ||
|
|
b37c0f6cd6 | ||
|
|
c4a1fc746b | ||
|
|
a3ab92226d | ||
|
|
ec66b3be82 | ||
|
|
f8ef4f1cf7 | ||
|
|
9e683b7dac |
@@ -100,10 +100,10 @@ dist-win32: build-server build-win32 build-win32-noconsole
|
||||
cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp "$(WIN32_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp "$(WIN32_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/scrcpy-noconsole.exe"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
@@ -114,10 +114,10 @@ dist-win64: build-server build-win64 build-win64-noconsole
|
||||
cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp "$(WIN64_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp "$(WIN64_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/scrcpy-noconsole.exe"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
|
||||
24
README.md
24
README.md
@@ -1,4 +1,4 @@
|
||||
# scrcpy (v1.2)
|
||||
# scrcpy (v1.3)
|
||||
|
||||
This application provides display and control of Android devices connected on
|
||||
USB (or [over TCP/IP][article-tcpip]). It does not require any _root_ access.
|
||||
@@ -79,13 +79,13 @@ Two [AUR] packages have been created by users:
|
||||
For Windows, for simplicity, prebuilt archives with all the dependencies
|
||||
(including `adb`) are available:
|
||||
|
||||
- [`scrcpy-win32-v1.2.zip`][direct-win32].
|
||||
_(SHA-256: a1fe1de67ec75dcf970ca5d97a04c26ff0f2d61871f2ef51b6f2f0bf666966b2)_
|
||||
- [`scrcpy-win64-v1.2.zip`][direct-win64].
|
||||
_(SHA-256: 35ae3bcee51771e7c51b8a8be87aef2295c9f267606a7cf83ebb0a4d583ef536)_
|
||||
- [`scrcpy-win32-v1.3.zip`][direct-win32].
|
||||
_(SHA-256: 51a2990e631ed469a7a86ff38107d517a91d313fb3f8327eb7bc71dde40870b5)_
|
||||
- [`scrcpy-win64-v1.3.zip`][direct-win64].
|
||||
_(SHA-256: 0768a80d3d600d0bbcd220ca150ae88a3a58d1fe85c308a8c61f44480b711e43)_
|
||||
|
||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v1.2/scrcpy-win32-v1.2.zip
|
||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.2/scrcpy-win64-v1.2.zip
|
||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v1.3/scrcpy-win32-v1.3.zip
|
||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.3/scrcpy-win64-v1.3.zip
|
||||
|
||||
Instead, you may want to build it manually.
|
||||
|
||||
@@ -247,10 +247,10 @@ Since the server binary, that will be pushed to the Android device, does not
|
||||
depend on your system and architecture, you may want to use the prebuilt binary
|
||||
instead:
|
||||
|
||||
- [`scrcpy-server-v1.2.jar`][direct-scrcpy-server].
|
||||
_(SHA-256: cb39654ed2fda3d30ddff292806950ccc5c394375ea12b974f790c7f38f61f60)_
|
||||
- [`scrcpy-server-v1.3.jar`][direct-scrcpy-server].
|
||||
_(SHA-256: 0f9a5a217f33f0ed7a1498ceb3c0cccf31c53533893aa952e674c1571d2740c1)_
|
||||
|
||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.2/scrcpy-server-v1.2.jar
|
||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.3/scrcpy-server-v1.3.jar
|
||||
|
||||
In that case, the build does not require Java or the Android SDK.
|
||||
|
||||
@@ -338,11 +338,15 @@ To run without installing:
|
||||
| turn screen on | _Right-click²_ |
|
||||
| paste computer clipboard to device | `Ctrl`+`v` |
|
||||
| enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
|
||||
| toggle "raw key events" mode ([#87]) | `Ctrl`+`k` |
|
||||
| install APK from computer | drag & drop APK file |
|
||||
| push file to `/sdcard/` | drag & drop non-APK file |
|
||||
|
||||
_¹Double-click on black borders to remove them._
|
||||
_²Right-click turns the screen on if it was off, presses BACK otherwise._
|
||||
|
||||
[#87]: https://github.com/Genymobile/scrcpy/issues/87
|
||||
|
||||
|
||||
## Why _scrcpy_?
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
src = [
|
||||
'src/main.c',
|
||||
'src/command.c',
|
||||
'src/controlevent.c',
|
||||
'src/control_event.c',
|
||||
'src/controller.c',
|
||||
'src/convert.c',
|
||||
'src/decoder.c',
|
||||
'src/device.c',
|
||||
'src/fpscounter.c',
|
||||
'src/file_handler.c',
|
||||
'src/fps_counter.c',
|
||||
'src/frames.c',
|
||||
'src/inputmanager.c',
|
||||
'src/installer.c',
|
||||
'src/lockutil.c',
|
||||
'src/input_manager.c',
|
||||
'src/lock_util.c',
|
||||
'src/net.c',
|
||||
'src/scrcpy.c',
|
||||
'src/screen.c',
|
||||
'src/server.c',
|
||||
'src/strutil.c',
|
||||
'src/tinyxpm.c',
|
||||
'src/str_util.c',
|
||||
'src/tiny_xpm.c',
|
||||
]
|
||||
|
||||
if not get_option('crossbuild_windows')
|
||||
@@ -147,9 +147,9 @@ executable('scrcpy', src, dependencies: dependencies, include_directories: src_d
|
||||
### TESTS
|
||||
|
||||
tests = [
|
||||
['test_control_event_queue', ['tests/test_control_event_queue.c', 'src/controlevent.c']],
|
||||
['test_control_event_serialize', ['tests/test_control_event_serialize.c', 'src/controlevent.c']],
|
||||
['test_strutil', ['tests/test_strutil.c', 'src/strutil.c']],
|
||||
['test_control_event_queue', ['tests/test_control_event_queue.c', 'src/control_event.c']],
|
||||
['test_control_event_serialize', ['tests/test_control_event_serialize.c', 'src/control_event.c']],
|
||||
['test_strutil', ['tests/test_strutil.c', 'src/str_util.c']],
|
||||
]
|
||||
|
||||
foreach t : tests
|
||||
|
||||
@@ -777,9 +777,6 @@ enum android_input_source {
|
||||
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
|
||||
/** rotary encoder */
|
||||
AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
|
||||
|
||||
/** any */
|
||||
AINPUT_SOURCE_ANY = 0xffffff00,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "controlevent.h"
|
||||
#include "control_event.h"
|
||||
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
static inline void write16(Uint8 *buf, Uint16 value) {
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "controller.h"
|
||||
|
||||
#include "lockutil.h"
|
||||
#include <SDL2/SDL_assert.h>
|
||||
#include "config.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
SDL_bool controller_init(struct controller *controller, socket_t video_socket) {
|
||||
@@ -65,12 +67,8 @@ static int run_controller(void *data) {
|
||||
break;
|
||||
}
|
||||
struct control_event event;
|
||||
#ifdef BUILD_DEBUG
|
||||
bool non_empty = control_event_queue_take(&controller->queue, &event);
|
||||
SDL_bool non_empty = control_event_queue_take(&controller->queue, &event);
|
||||
SDL_assert(non_empty);
|
||||
#else
|
||||
control_event_queue_take(&controller->queue, &event);
|
||||
#endif
|
||||
mutex_unlock(controller->mutex);
|
||||
|
||||
SDL_bool ok = process_event(controller, &event);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CONTROL_H
|
||||
#define CONTROL_H
|
||||
|
||||
#include "controlevent.h"
|
||||
#include "control_event.h"
|
||||
|
||||
#include <SDL2/SDL_mutex.h>
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
|
||||
@@ -70,6 +70,83 @@ static enum android_metastate convert_meta_state(SDL_Keymod mod) {
|
||||
return autocomplete_metastate(metastate);
|
||||
}
|
||||
|
||||
// only used if raw_key_events is enabled
|
||||
static SDL_bool convert_text_keycode(SDL_Keycode from, enum android_keycode *to) {
|
||||
switch (from) {
|
||||
MAP(SDLK_SPACE, AKEYCODE_SPACE);
|
||||
MAP(SDLK_HASH, AKEYCODE_POUND);
|
||||
MAP(SDLK_QUOTE, AKEYCODE_APOSTROPHE);
|
||||
MAP(SDLK_ASTERISK, AKEYCODE_STAR);
|
||||
MAP(SDLK_COMMA, AKEYCODE_COMMA);
|
||||
MAP(SDLK_MINUS, AKEYCODE_MINUS);
|
||||
MAP(SDLK_PERIOD, AKEYCODE_PERIOD);
|
||||
MAP(SDLK_SLASH, AKEYCODE_SLASH);
|
||||
MAP(SDLK_0, AKEYCODE_0);
|
||||
MAP(SDLK_1, AKEYCODE_1);
|
||||
MAP(SDLK_2, AKEYCODE_2);
|
||||
MAP(SDLK_3, AKEYCODE_3);
|
||||
MAP(SDLK_4, AKEYCODE_4);
|
||||
MAP(SDLK_5, AKEYCODE_5);
|
||||
MAP(SDLK_6, AKEYCODE_6);
|
||||
MAP(SDLK_7, AKEYCODE_7);
|
||||
MAP(SDLK_8, AKEYCODE_8);
|
||||
MAP(SDLK_9, AKEYCODE_9);
|
||||
MAP(SDLK_SEMICOLON, AKEYCODE_SEMICOLON);
|
||||
MAP(SDLK_EQUALS, AKEYCODE_EQUALS);
|
||||
MAP(SDLK_AT, AKEYCODE_AT);
|
||||
MAP(SDLK_LEFTBRACKET, AKEYCODE_LEFT_BRACKET);
|
||||
MAP(SDLK_BACKSLASH, AKEYCODE_BACKSLASH);
|
||||
MAP(SDLK_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET);
|
||||
MAP(SDLK_BACKQUOTE, AKEYCODE_GRAVE);
|
||||
MAP(SDLK_a, AKEYCODE_A);
|
||||
MAP(SDLK_b, AKEYCODE_B);
|
||||
MAP(SDLK_c, AKEYCODE_C);
|
||||
MAP(SDLK_d, AKEYCODE_D);
|
||||
MAP(SDLK_e, AKEYCODE_E);
|
||||
MAP(SDLK_f, AKEYCODE_F);
|
||||
MAP(SDLK_g, AKEYCODE_G);
|
||||
MAP(SDLK_h, AKEYCODE_H);
|
||||
MAP(SDLK_i, AKEYCODE_I);
|
||||
MAP(SDLK_j, AKEYCODE_J);
|
||||
MAP(SDLK_k, AKEYCODE_K);
|
||||
MAP(SDLK_l, AKEYCODE_L);
|
||||
MAP(SDLK_m, AKEYCODE_M);
|
||||
MAP(SDLK_n, AKEYCODE_N);
|
||||
MAP(SDLK_o, AKEYCODE_O);
|
||||
MAP(SDLK_p, AKEYCODE_P);
|
||||
MAP(SDLK_q, AKEYCODE_Q);
|
||||
MAP(SDLK_r, AKEYCODE_R);
|
||||
MAP(SDLK_s, AKEYCODE_S);
|
||||
MAP(SDLK_t, AKEYCODE_T);
|
||||
MAP(SDLK_u, AKEYCODE_U);
|
||||
MAP(SDLK_v, AKEYCODE_V);
|
||||
MAP(SDLK_w, AKEYCODE_W);
|
||||
MAP(SDLK_x, AKEYCODE_X);
|
||||
MAP(SDLK_y, AKEYCODE_Y);
|
||||
MAP(SDLK_z, AKEYCODE_Z);
|
||||
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
|
||||
MAP(SDLK_KP_1, AKEYCODE_NUMPAD_1);
|
||||
MAP(SDLK_KP_2, AKEYCODE_NUMPAD_2);
|
||||
MAP(SDLK_KP_3, AKEYCODE_NUMPAD_3);
|
||||
MAP(SDLK_KP_4, AKEYCODE_NUMPAD_4);
|
||||
MAP(SDLK_KP_5, AKEYCODE_NUMPAD_5);
|
||||
MAP(SDLK_KP_6, AKEYCODE_NUMPAD_6);
|
||||
MAP(SDLK_KP_7, AKEYCODE_NUMPAD_7);
|
||||
MAP(SDLK_KP_8, AKEYCODE_NUMPAD_8);
|
||||
MAP(SDLK_KP_9, AKEYCODE_NUMPAD_9);
|
||||
MAP(SDLK_KP_0, AKEYCODE_NUMPAD_0);
|
||||
MAP(SDLK_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE);
|
||||
MAP(SDLK_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY);
|
||||
MAP(SDLK_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT);
|
||||
MAP(SDLK_KP_PLUS, AKEYCODE_NUMPAD_ADD);
|
||||
MAP(SDLK_KP_PERIOD, AKEYCODE_NUMPAD_DOT);
|
||||
MAP(SDLK_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS);
|
||||
MAP(SDLK_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN);
|
||||
MAP(SDLK_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN);
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool convert_keycode(SDL_Keycode from, enum android_keycode *to) {
|
||||
switch (from) {
|
||||
MAP(SDLK_RETURN, AKEYCODE_ENTER);
|
||||
@@ -119,7 +196,8 @@ static enum android_motionevent_buttons convert_mouse_buttons(Uint32 state) {
|
||||
}
|
||||
|
||||
SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
||||
struct control_event *to) {
|
||||
struct control_event *to,
|
||||
SDL_bool raw_key_events) {
|
||||
to->type = CONTROL_EVENT_TYPE_KEYCODE;
|
||||
|
||||
if (!convert_keycode_action(from->type, &to->keycode_event.action)) {
|
||||
@@ -127,7 +205,10 @@ SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
||||
}
|
||||
|
||||
if (!convert_keycode(from->keysym.sym, &to->keycode_event.keycode)) {
|
||||
return SDL_FALSE;
|
||||
if (!raw_key_events ||
|
||||
!convert_text_keycode(from->keysym.sym, &to->keycode_event.keycode)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
to->keycode_event.metastate = convert_meta_state(from->keysym.mod);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
#include <SDL2/SDL_events.h>
|
||||
#include "controlevent.h"
|
||||
#include "control_event.h"
|
||||
|
||||
struct complete_mouse_motion_event {
|
||||
SDL_MouseMotionEvent *mouse_motion_event;
|
||||
@@ -16,7 +16,9 @@ struct complete_mouse_wheel_event {
|
||||
};
|
||||
|
||||
SDL_bool input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
||||
struct control_event *to);
|
||||
struct control_event *to,
|
||||
SDL_bool raw_key_events);
|
||||
|
||||
SDL_bool mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
||||
struct size screen_size,
|
||||
struct control_event *to);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "config.h"
|
||||
#include "events.h"
|
||||
#include "frames.h"
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
#define BUFSIZE 0x10000
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "net.h"
|
||||
|
||||
#define DEVICE_NAME_FIELD_LENGTH 64
|
||||
#define DEVICE_SDCARD_PATH "/sdcard/"
|
||||
|
||||
// name must be at least DEVICE_NAME_FIELD_LENGTH bytes
|
||||
SDL_bool device_read_info(socket_t device_socket, char *name, struct size *frame_size);
|
||||
|
||||
231
app/src/file_handler.c
Normal file
231
app/src/file_handler.c
Normal file
@@ -0,0 +1,231 @@
|
||||
#include "file_handler.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL2/SDL_assert.h>
|
||||
#include "config.h"
|
||||
#include "command.h"
|
||||
#include "device.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
struct request {
|
||||
file_handler_action_t action;
|
||||
const char *file;
|
||||
};
|
||||
|
||||
static struct request *request_new(file_handler_action_t action, const char *file) {
|
||||
struct request *req = SDL_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
return NULL;
|
||||
}
|
||||
req->action = action;
|
||||
req->file = file;
|
||||
return req;
|
||||
}
|
||||
|
||||
static void request_free(struct request *req) {
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
SDL_free((void *) req->file);
|
||||
SDL_free((void *) req);
|
||||
}
|
||||
|
||||
static SDL_bool request_queue_is_empty(const struct request_queue *queue) {
|
||||
return queue->head == queue->tail;
|
||||
}
|
||||
|
||||
static SDL_bool request_queue_is_full(const struct request_queue *queue) {
|
||||
return (queue->head + 1) % REQUEST_QUEUE_SIZE == queue->tail;
|
||||
}
|
||||
|
||||
static SDL_bool request_queue_init(struct request_queue *queue) {
|
||||
queue->head = 0;
|
||||
queue->tail = 0;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void request_queue_destroy(struct request_queue *queue) {
|
||||
int i = queue->tail;
|
||||
while (i != queue->head) {
|
||||
request_free(queue->reqs[i]);
|
||||
i = (i + 1) % REQUEST_QUEUE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool request_queue_push(struct request_queue *queue, struct request *req) {
|
||||
if (request_queue_is_full(queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
queue->reqs[queue->head] = req;
|
||||
queue->head = (queue->head + 1) % REQUEST_QUEUE_SIZE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool request_queue_take(struct request_queue *queue, struct request **req) {
|
||||
if (request_queue_is_empty(queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
// transfer ownership
|
||||
*req = queue->reqs[queue->tail];
|
||||
queue->tail = (queue->tail + 1) % REQUEST_QUEUE_SIZE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool file_handler_init(struct file_handler *file_handler, const char *serial) {
|
||||
|
||||
if (!request_queue_init(&file_handler->queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!(file_handler->mutex = SDL_CreateMutex())) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!(file_handler->event_cond = SDL_CreateCond())) {
|
||||
SDL_DestroyMutex(file_handler->mutex);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (serial) {
|
||||
file_handler->serial = SDL_strdup(serial);
|
||||
if (!file_handler->serial) {
|
||||
LOGW("Cannot strdup serial");
|
||||
SDL_DestroyMutex(file_handler->mutex);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
file_handler->serial = NULL;
|
||||
}
|
||||
|
||||
// lazy initialization
|
||||
file_handler->initialized = SDL_FALSE;
|
||||
|
||||
file_handler->stopped = SDL_FALSE;
|
||||
file_handler->current_process = PROCESS_NONE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void file_handler_destroy(struct file_handler *file_handler) {
|
||||
SDL_DestroyCond(file_handler->event_cond);
|
||||
SDL_DestroyMutex(file_handler->mutex);
|
||||
request_queue_destroy(&file_handler->queue);
|
||||
SDL_free((void *) file_handler->serial);
|
||||
}
|
||||
|
||||
static process_t install_apk(const char *serial, const char *file) {
|
||||
return adb_install(serial, file);
|
||||
}
|
||||
|
||||
static process_t push_file(const char *serial, const char *file) {
|
||||
return adb_push(serial, file, DEVICE_SDCARD_PATH);
|
||||
}
|
||||
|
||||
SDL_bool file_handler_request(struct file_handler *file_handler,
|
||||
file_handler_action_t action,
|
||||
const char *file) {
|
||||
SDL_bool res;
|
||||
|
||||
// start file_handler if it's used for the first time
|
||||
if (!file_handler->initialized) {
|
||||
if (!file_handler_start(file_handler)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
file_handler->initialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
LOGI("Request to %s %s", action == ACTION_INSTALL_APK ? "install" : "push", file);
|
||||
struct request *req = request_new(action, file);
|
||||
if (!req) {
|
||||
LOGE("Could not create request");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
mutex_lock(file_handler->mutex);
|
||||
SDL_bool was_empty = request_queue_is_empty(&file_handler->queue);
|
||||
res = request_queue_push(&file_handler->queue, req);
|
||||
if (was_empty) {
|
||||
cond_signal(file_handler->event_cond);
|
||||
}
|
||||
mutex_unlock(file_handler->mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int run_file_handler(void *data) {
|
||||
struct file_handler *file_handler = data;
|
||||
|
||||
for (;;) {
|
||||
mutex_lock(file_handler->mutex);
|
||||
file_handler->current_process = PROCESS_NONE;
|
||||
while (!file_handler->stopped && request_queue_is_empty(&file_handler->queue)) {
|
||||
cond_wait(file_handler->event_cond, file_handler->mutex);
|
||||
}
|
||||
if (file_handler->stopped) {
|
||||
// stop immediately, do not process further events
|
||||
mutex_unlock(file_handler->mutex);
|
||||
break;
|
||||
}
|
||||
struct request *req;
|
||||
SDL_bool non_empty = request_queue_take(&file_handler->queue, &req);
|
||||
SDL_assert(non_empty);
|
||||
|
||||
process_t process;
|
||||
if (req->action == ACTION_INSTALL_APK) {
|
||||
LOGI("Installing %s...", req->file);
|
||||
process = install_apk(file_handler->serial, req->file);
|
||||
} else {
|
||||
LOGI("Pushing %s...", req->file);
|
||||
process = push_file(file_handler->serial, req->file);
|
||||
}
|
||||
file_handler->current_process = process;
|
||||
mutex_unlock(file_handler->mutex);
|
||||
|
||||
if (req->action == ACTION_INSTALL_APK) {
|
||||
if (process_check_success(process, "adb install")) {
|
||||
LOGI("%s successfully installed", req->file);
|
||||
} else {
|
||||
LOGE("Failed to install %s", req->file);
|
||||
}
|
||||
} else {
|
||||
if (process_check_success(process, "adb push")) {
|
||||
LOGI("%s successfully pushed to /sdcard/", req->file);
|
||||
} else {
|
||||
LOGE("Failed to push %s to /sdcard/", req->file);
|
||||
}
|
||||
}
|
||||
|
||||
request_free(req);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_bool file_handler_start(struct file_handler *file_handler) {
|
||||
LOGD("Starting file_handler thread");
|
||||
|
||||
file_handler->thread = SDL_CreateThread(run_file_handler, "file_handler", file_handler);
|
||||
if (!file_handler->thread) {
|
||||
LOGC("Could not start file_handler thread");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void file_handler_stop(struct file_handler *file_handler) {
|
||||
mutex_lock(file_handler->mutex);
|
||||
file_handler->stopped = SDL_TRUE;
|
||||
cond_signal(file_handler->event_cond);
|
||||
if (file_handler->current_process != PROCESS_NONE) {
|
||||
if (!cmd_terminate(file_handler->current_process)) {
|
||||
LOGW("Cannot terminate install process");
|
||||
}
|
||||
cmd_simple_wait(file_handler->current_process, NULL);
|
||||
file_handler->current_process = PROCESS_NONE;
|
||||
}
|
||||
mutex_unlock(file_handler->mutex);
|
||||
}
|
||||
|
||||
void file_handler_join(struct file_handler *file_handler) {
|
||||
SDL_WaitThread(file_handler->thread, NULL);
|
||||
}
|
||||
44
app/src/file_handler.h
Normal file
44
app/src/file_handler.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef FILE_HANDLER_H
|
||||
#define FILE_HADNELR_H
|
||||
|
||||
#include <SDL2/SDL_mutex.h>
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
#include <SDL2/SDL_thread.h>
|
||||
#include "command.h"
|
||||
|
||||
#define REQUEST_QUEUE_SIZE 16
|
||||
|
||||
typedef enum {
|
||||
ACTION_INSTALL_APK,
|
||||
ACTION_PUSH_FILE,
|
||||
} file_handler_action_t;
|
||||
|
||||
struct request_queue {
|
||||
struct request *reqs[REQUEST_QUEUE_SIZE];
|
||||
int tail;
|
||||
int head;
|
||||
};
|
||||
|
||||
struct file_handler {
|
||||
const char *serial;
|
||||
SDL_Thread *thread;
|
||||
SDL_mutex *mutex;
|
||||
SDL_cond *event_cond;
|
||||
SDL_bool stopped;
|
||||
SDL_bool initialized;
|
||||
process_t current_process;
|
||||
struct request_queue queue;
|
||||
};
|
||||
|
||||
SDL_bool file_handler_init(struct file_handler *file_handler, const char *serial);
|
||||
void file_handler_destroy(struct file_handler *file_handler);
|
||||
|
||||
SDL_bool file_handler_start(struct file_handler *file_handler);
|
||||
void file_handler_stop(struct file_handler *file_handler);
|
||||
void file_handler_join(struct file_handler *file_handler);
|
||||
|
||||
SDL_bool file_handler_request(struct file_handler *file_handler,
|
||||
file_handler_action_t action,
|
||||
const char *file);
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "fpscounter.h"
|
||||
#include "fps_counter.h"
|
||||
|
||||
#include <SDL2/SDL_timer.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
SDL_bool frames_init(struct frames *frames) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fpscounter.h"
|
||||
#include "fps_counter.h"
|
||||
|
||||
// forward declarations
|
||||
typedef struct AVFrame AVFrame;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "inputmanager.h"
|
||||
#include "input_manager.h"
|
||||
|
||||
#include "convert.h"
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
|
||||
// Convert window coordinates (as provided by SDL_GetMouseState() to renderer coordinates (as provided in SDL mouse events)
|
||||
@@ -129,6 +129,10 @@ static void clipboard_paste(struct controller *controller) {
|
||||
|
||||
void input_manager_process_text_input(struct input_manager *input_manager,
|
||||
const SDL_TextInputEvent *event) {
|
||||
if (input_manager->raw_key_events) {
|
||||
// we will forward the raw key events instead
|
||||
return;
|
||||
}
|
||||
struct control_event control_event;
|
||||
control_event.type = CONTROL_EVENT_TYPE_TEXT;
|
||||
control_event.text_event.text = SDL_strdup(event->text);
|
||||
@@ -216,13 +220,21 @@ void input_manager_process_key(struct input_manager *input_manager,
|
||||
switch_fps_counter_state(input_manager->frames);
|
||||
}
|
||||
return;
|
||||
case SDLK_k:
|
||||
if (!repeat && event->type == SDL_KEYDOWN) {
|
||||
input_manager->raw_key_events ^= SDL_TRUE; // toggle
|
||||
LOGI("Raw key events mode %s",
|
||||
input_manager->raw_key_events ? "enabled" : "disabled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct control_event control_event;
|
||||
if (input_key_from_sdl_to_android(event, &control_event)) {
|
||||
SDL_bool raw_key_events = input_manager->raw_key_events;
|
||||
if (input_key_from_sdl_to_android(event, &control_event, raw_key_events)) {
|
||||
if (!controller_push_event(input_manager->controller, &control_event)) {
|
||||
LOGW("Cannot send control event");
|
||||
}
|
||||
@@ -265,7 +277,7 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,
|
||||
}
|
||||
// otherwise, send the click event to the device
|
||||
}
|
||||
};
|
||||
}
|
||||
struct control_event control_event;
|
||||
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) {
|
||||
if (!controller_push_event(input_manager->controller, &control_event)) {
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "controller.h"
|
||||
#include "fpscounter.h"
|
||||
#include "fps_counter.h"
|
||||
#include "frames.h"
|
||||
#include "screen.h"
|
||||
|
||||
@@ -11,6 +11,7 @@ struct input_manager {
|
||||
struct controller *controller;
|
||||
struct frames *frames;
|
||||
struct screen *screen;
|
||||
SDL_bool raw_key_events;
|
||||
};
|
||||
|
||||
void input_manager_process_text_input(struct input_manager *input_manager,
|
||||
@@ -1,180 +0,0 @@
|
||||
#include "installer.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "command.h"
|
||||
#include "lockutil.h"
|
||||
#include "log.h"
|
||||
|
||||
// NOTE(adopi) this can be more generic:
|
||||
// it could be used with a command queue instead of a filename queue
|
||||
// then we would have a generic invoker (useful if we want to handle more async commands)
|
||||
|
||||
SDL_bool apk_queue_is_empty(const struct apk_queue *queue) {
|
||||
return queue->head == queue->tail;
|
||||
}
|
||||
|
||||
SDL_bool apk_queue_is_full(const struct apk_queue *queue) {
|
||||
return (queue->head + 1) % APK_QUEUE_SIZE == queue->tail;
|
||||
}
|
||||
|
||||
SDL_bool apk_queue_init(struct apk_queue *queue) {
|
||||
queue->head = 0;
|
||||
queue->tail = 0;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void apk_queue_destroy(struct apk_queue *queue) {
|
||||
int i = queue->tail;
|
||||
while (i != queue->head) {
|
||||
SDL_free(queue->data[i]);
|
||||
i = (i + 1) % APK_QUEUE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool apk_queue_push(struct apk_queue *queue, const char *apk) {
|
||||
if (apk_queue_is_full(queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
queue->data[queue->head] = SDL_strdup(apk);
|
||||
queue->head = (queue->head + 1) % APK_QUEUE_SIZE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool apk_queue_take(struct apk_queue *queue, char **apk) {
|
||||
if (apk_queue_is_empty(queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
// transfer ownership
|
||||
*apk = queue->data[queue->tail];
|
||||
queue->tail = (queue->tail + 1) % APK_QUEUE_SIZE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool installer_init(struct installer *installer, const char *serial) {
|
||||
|
||||
if (!apk_queue_init(&installer->queue)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!(installer->mutex = SDL_CreateMutex())) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!(installer->event_cond = SDL_CreateCond())) {
|
||||
SDL_DestroyMutex(installer->mutex);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (serial) {
|
||||
installer->serial = SDL_strdup(serial);
|
||||
if (!installer->serial) {
|
||||
LOGW("Cannot strdup serial");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
installer->serial = NULL;
|
||||
}
|
||||
|
||||
// lazy initialization
|
||||
installer->initialized = SDL_FALSE;
|
||||
|
||||
installer->stopped = SDL_FALSE;
|
||||
installer->current_process = PROCESS_NONE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void installer_destroy(struct installer *installer) {
|
||||
SDL_DestroyCond(installer->event_cond);
|
||||
SDL_DestroyMutex(installer->mutex);
|
||||
apk_queue_destroy(&installer->queue);
|
||||
SDL_free((void *) installer->serial);
|
||||
}
|
||||
|
||||
SDL_bool installer_install_apk(struct installer *installer, const char *apk) {
|
||||
SDL_bool res;
|
||||
|
||||
// start installer if it's used for the first time
|
||||
if (!installer->initialized) {
|
||||
if (!installer_start(installer)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
installer->initialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
mutex_lock(installer->mutex);
|
||||
SDL_bool was_empty = apk_queue_is_empty(&installer->queue);
|
||||
res = apk_queue_push(&installer->queue, apk);
|
||||
if (was_empty) {
|
||||
cond_signal(installer->event_cond);
|
||||
}
|
||||
mutex_unlock(installer->mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int run_installer(void *data) {
|
||||
struct installer *installer = data;
|
||||
|
||||
for (;;) {
|
||||
mutex_lock(installer->mutex);
|
||||
while (!installer->stopped && apk_queue_is_empty(&installer->queue)) {
|
||||
cond_wait(installer->event_cond, installer->mutex);
|
||||
}
|
||||
if (installer->stopped) {
|
||||
// stop immediately, do not process further events
|
||||
mutex_unlock(installer->mutex);
|
||||
break;
|
||||
}
|
||||
char *current_apk;
|
||||
#ifdef BUILD_DEBUG
|
||||
bool non_empty = apk_queue_take(&installer->queue, ¤t_apk);
|
||||
SDL_assert(non_empty);
|
||||
#else
|
||||
apk_queue_take(&installer->queue, ¤t_apk);
|
||||
#endif
|
||||
|
||||
LOGI("Installing %s...", current_apk);
|
||||
process_t process = adb_install(installer->serial, current_apk);
|
||||
installer->current_process = process;
|
||||
|
||||
mutex_unlock(installer->mutex);
|
||||
|
||||
if (process_check_success(process, "adb install")) {
|
||||
LOGI("%s installed successfully", current_apk);
|
||||
} else {
|
||||
LOGE("Failed to install %s", current_apk);
|
||||
}
|
||||
SDL_free(current_apk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_bool installer_start(struct installer *installer) {
|
||||
LOGD("Starting installer thread");
|
||||
|
||||
installer->thread = SDL_CreateThread(run_installer, "installer", installer);
|
||||
if (!installer->thread) {
|
||||
LOGC("Could not start installer thread");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void installer_stop(struct installer *installer) {
|
||||
mutex_lock(installer->mutex);
|
||||
installer->stopped = SDL_TRUE;
|
||||
cond_signal(installer->event_cond);
|
||||
if (installer->current_process != PROCESS_NONE) {
|
||||
if (!cmd_terminate(installer->current_process)) {
|
||||
LOGW("Cannot terminate install process");
|
||||
}
|
||||
cmd_simple_wait(installer->current_process, NULL);
|
||||
installer->current_process = PROCESS_NONE;
|
||||
}
|
||||
mutex_unlock(installer->mutex);
|
||||
}
|
||||
|
||||
void installer_join(struct installer *installer) {
|
||||
SDL_WaitThread(installer->thread, NULL);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef APK_INSTALLER_H
|
||||
#define APK_INSTALLER_H
|
||||
|
||||
#include <SDL2/SDL_mutex.h>
|
||||
#include <SDL2/SDL_stdinc.h>
|
||||
#include <SDL2/SDL_thread.h>
|
||||
#include "command.h"
|
||||
|
||||
#define APK_QUEUE_SIZE 16
|
||||
|
||||
// NOTE(AdoPi) apk_queue and control_event can use a generic queue
|
||||
|
||||
struct apk_queue {
|
||||
char *data[APK_QUEUE_SIZE];
|
||||
int tail;
|
||||
int head;
|
||||
};
|
||||
|
||||
struct installer {
|
||||
const char *serial;
|
||||
SDL_Thread *thread;
|
||||
SDL_mutex *mutex;
|
||||
SDL_cond *event_cond;
|
||||
SDL_bool stopped;
|
||||
SDL_bool initialized;
|
||||
process_t current_process;
|
||||
struct apk_queue queue;
|
||||
};
|
||||
|
||||
SDL_bool installer_init(struct installer *installer, const char *serial);
|
||||
void installer_destroy(struct installer *installer);
|
||||
|
||||
SDL_bool installer_start(struct installer *installer);
|
||||
void installer_stop(struct installer *installer);
|
||||
void installer_join(struct installer *installer);
|
||||
|
||||
// install an apk
|
||||
SDL_bool installer_install_apk(struct installer *installer, const char *filename);
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <lock_util.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL2/SDL_mutex.h>
|
||||
|
||||
@@ -13,28 +13,29 @@
|
||||
#include "decoder.h"
|
||||
#include "device.h"
|
||||
#include "events.h"
|
||||
#include "file_handler.h"
|
||||
#include "frames.h"
|
||||
#include "fpscounter.h"
|
||||
#include "inputmanager.h"
|
||||
#include "fps_counter.h"
|
||||
#include "input_manager.h"
|
||||
#include "log.h"
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "net.h"
|
||||
#include "screen.h"
|
||||
#include "server.h"
|
||||
#include "tinyxpm.h"
|
||||
#include "installer.h"
|
||||
#include "tiny_xpm.h"
|
||||
|
||||
static struct server server = SERVER_INITIALIZER;
|
||||
static struct screen screen = SCREEN_INITIALIZER;
|
||||
static struct frames frames;
|
||||
static struct decoder decoder;
|
||||
static struct controller controller;
|
||||
static struct installer installer;
|
||||
static struct file_handler file_handler;
|
||||
|
||||
static struct input_manager input_manager = {
|
||||
.controller = &controller,
|
||||
.frames = &frames,
|
||||
.screen = &screen,
|
||||
.raw_key_events = SDL_FALSE,
|
||||
};
|
||||
|
||||
#if defined(__APPLE__) || defined(__WINDOWS__)
|
||||
@@ -56,7 +57,12 @@ static int event_watcher(void *data, SDL_Event *event) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static void event_loop(void) {
|
||||
static SDL_bool is_apk(const char *file) {
|
||||
const char *ext = strrchr(file, '.');
|
||||
return ext && !strcmp(ext, ".apk");
|
||||
}
|
||||
|
||||
static SDL_bool event_loop(void) {
|
||||
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
||||
SDL_AddEventWatch(event_watcher, NULL);
|
||||
#endif
|
||||
@@ -65,10 +71,10 @@ static void event_loop(void) {
|
||||
switch (event.type) {
|
||||
case EVENT_DECODER_STOPPED:
|
||||
LOGD("Video decoder stopped");
|
||||
return;
|
||||
return SDL_FALSE;
|
||||
case SDL_QUIT:
|
||||
LOGD("User requested to quit");
|
||||
return;
|
||||
return SDL_TRUE;
|
||||
case EVENT_NEW_FRAME:
|
||||
if (!screen.has_frame) {
|
||||
screen.has_frame = SDL_TRUE;
|
||||
@@ -76,7 +82,7 @@ static void event_loop(void) {
|
||||
screen_show_window(&screen);
|
||||
}
|
||||
if (!screen_update_frame(&screen, &frames)) {
|
||||
return;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
@@ -104,11 +110,19 @@ static void event_loop(void) {
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
input_manager_process_mouse_button(&input_manager, &event.button);
|
||||
break;
|
||||
case SDL_DROPFILE:
|
||||
installer_install_apk(&installer, event.drop.file);
|
||||
case SDL_DROPFILE: {
|
||||
file_handler_action_t action;
|
||||
if (is_apk(event.drop.file)) {
|
||||
action = ACTION_INSTALL_APK;
|
||||
} else {
|
||||
action = ACTION_PUSH_FILE;
|
||||
}
|
||||
file_handler_request(&file_handler, action, event.drop.file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static process_t set_show_touches_enabled(const char *serial, SDL_bool enabled) {
|
||||
@@ -174,7 +188,7 @@ SDL_bool scrcpy(const struct scrcpy_options *options) {
|
||||
goto finally_destroy_server;
|
||||
}
|
||||
|
||||
if (!installer_init(&installer, server.serial)) {
|
||||
if (!file_handler_init(&file_handler, server.serial)) {
|
||||
ret = SDL_FALSE;
|
||||
server_stop(&server);
|
||||
goto finally_destroy_frames;
|
||||
@@ -187,7 +201,7 @@ SDL_bool scrcpy(const struct scrcpy_options *options) {
|
||||
if (!decoder_start(&decoder)) {
|
||||
ret = SDL_FALSE;
|
||||
server_stop(&server);
|
||||
goto finally_destroy_installer;
|
||||
goto finally_destroy_file_handler;
|
||||
}
|
||||
|
||||
if (!controller_init(&controller, device_socket)) {
|
||||
@@ -210,7 +224,7 @@ SDL_bool scrcpy(const struct scrcpy_options *options) {
|
||||
show_touches_waited = SDL_TRUE;
|
||||
}
|
||||
|
||||
event_loop();
|
||||
ret = event_loop();
|
||||
LOGD("quit...");
|
||||
|
||||
screen_destroy(&screen);
|
||||
@@ -225,10 +239,10 @@ finally_stop_decoder:
|
||||
// stop the server before decoder_join() to wake up the decoder
|
||||
server_stop(&server);
|
||||
decoder_join(&decoder);
|
||||
finally_destroy_installer:
|
||||
installer_stop(&installer);
|
||||
installer_join(&installer);
|
||||
installer_destroy(&installer);
|
||||
finally_destroy_file_handler:
|
||||
file_handler_stop(&file_handler);
|
||||
file_handler_join(&file_handler);
|
||||
file_handler_destroy(&file_handler);
|
||||
finally_destroy_frames:
|
||||
frames_destroy(&frames);
|
||||
finally_destroy_server:
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "icon.xpm"
|
||||
#include "lockutil.h"
|
||||
#include "lock_util.h"
|
||||
#include "log.h"
|
||||
#include "tinyxpm.h"
|
||||
#include "tiny_xpm.h"
|
||||
|
||||
#define DISPLAY_MARGINS 96
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "strutil.h"
|
||||
#include "str_util.h"
|
||||
|
||||
size_t xstrncpy(char *dest, const char *src, size_t n) {
|
||||
size_t i;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "strutil.h"
|
||||
#include "str_util.h"
|
||||
|
||||
HANDLE cmd_execute(const char *path, const char *const argv[]) {
|
||||
STARTUPINFO si;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "tinyxpm.h"
|
||||
#include "tiny_xpm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -40,15 +40,15 @@ SDL_Surface *read_xpm(char *xpm[]) {
|
||||
// *** No error handling, assume the XPM source is valid ***
|
||||
// (it's in our source repo)
|
||||
// Assertions are only checked in debug
|
||||
Uint32 width = strtol(xpm[0], &endptr, 10);
|
||||
Uint32 height = strtol(endptr + 1, &endptr, 10);
|
||||
Uint32 colors = strtol(endptr + 1, &endptr, 10);
|
||||
Uint32 chars = strtol(endptr + 1, &endptr, 10);
|
||||
int width = strtol(xpm[0], &endptr, 10);
|
||||
int height = strtol(endptr + 1, &endptr, 10);
|
||||
int colors = strtol(endptr + 1, &endptr, 10);
|
||||
int chars = strtol(endptr + 1, &endptr, 10);
|
||||
|
||||
// sanity checks
|
||||
SDL_assert(width < 256);
|
||||
SDL_assert(height < 256);
|
||||
SDL_assert(colors < 256);
|
||||
SDL_assert(0 <= width && width < 256);
|
||||
SDL_assert(0 <= height && height < 256);
|
||||
SDL_assert(0 <= colors && colors < 256);
|
||||
SDL_assert(chars == 1); // this implementation does not support more
|
||||
|
||||
// init index
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "controlevent.h"
|
||||
#include "control_event.h"
|
||||
|
||||
static void test_control_event_queue_empty() {
|
||||
struct control_event_queue queue;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "controlevent.h"
|
||||
#include "control_event.h"
|
||||
|
||||
static void test_serialize_keycode_event() {
|
||||
struct control_event event = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strutil.h"
|
||||
#include "str_util.h"
|
||||
|
||||
static void test_xstrncpy_simple() {
|
||||
char s[] = "xxxxxxxxxx";
|
||||
|
||||
@@ -15,6 +15,6 @@ cpu = 'i686'
|
||||
endian = 'little'
|
||||
|
||||
[properties]
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.0-win32-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.0-win32-dev'
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.0.2-win32-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.0.2-win32-dev'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.8/i686-w64-mingw32'
|
||||
|
||||
@@ -15,6 +15,6 @@ cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
||||
[properties]
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.0-win64-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.0-win64-dev'
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.0.2-win64-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.0.2-win64-dev'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.8/x86_64-w64-mingw32'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
project('scrcpy', 'c', meson_version: '>= 0.37', default_options : 'c_std=c99')
|
||||
project('scrcpy', 'c', meson_version: '>= 0.37', default_options : 'c_std=c11')
|
||||
|
||||
if get_option('build_app')
|
||||
subdir('app')
|
||||
|
||||
@@ -10,24 +10,24 @@ prepare-win32: prepare-sdl2 prepare-ffmpeg-shared-win32 prepare-ffmpeg-dev-win32
|
||||
prepare-win64: prepare-sdl2 prepare-ffmpeg-shared-win64 prepare-ffmpeg-dev-win64 prepare-adb
|
||||
|
||||
prepare-ffmpeg-shared-win32:
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.0-win32-shared.zip \
|
||||
530c92df0ca14c35901b4b681847d62da3c50a0cc9b7ced37b04968f6b5c243d \
|
||||
ffmpeg-4.0-win32-shared
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.0.2-win32-shared.zip \
|
||||
cc190a3a4cf7bfbd4fbaa92609c1501a1de458055e6cfea8b745c1d515013aa8 \
|
||||
ffmpeg-4.0.2-win32-shared
|
||||
|
||||
prepare-ffmpeg-dev-win32:
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.0-win32-dev.zip \
|
||||
e2f5200b5e73c4d0abb9b89c4ffc0438f92a0aadc54c81cf57e18c81a9f11c6b \
|
||||
ffmpeg-4.0-win32-dev
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.0.2-win32-dev.zip \
|
||||
c72c74bad74ac0541f1b43090c26a50017c49041c182a703abd2057bb8cdc238 \
|
||||
ffmpeg-4.0.2-win32-dev
|
||||
|
||||
prepare-ffmpeg-shared-win64:
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.0-win64-shared.zip \
|
||||
8fe2d344463dbefc2db4239a4203a55ed0324faceaae57276a40c4fabda84c37 \
|
||||
ffmpeg-4.0-win64-shared
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.0.2-win64-shared.zip \
|
||||
ede566aca8b5348dff85570f9638c6bad33209f9419f79db7bde7daa37599bff \
|
||||
ffmpeg-4.0.2-win64-shared
|
||||
|
||||
prepare-ffmpeg-dev-win64:
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.0-win64-dev.zip \
|
||||
facced738eabfc53fa92834dea8b24426f64db61298688fed480145945be07fa \
|
||||
ffmpeg-4.0-win64-dev
|
||||
@./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.0.2-win64-dev.zip \
|
||||
23ee994161c51285cb956b98d3caa499d48083dae7b26c1fdf77f22e98df1c5f \
|
||||
ffmpeg-4.0.2-win64-dev
|
||||
|
||||
prepare-sdl2:
|
||||
@./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.8-mingw.tar.gz \
|
||||
@@ -35,6 +35,6 @@ prepare-sdl2:
|
||||
SDL2-2.0.8
|
||||
|
||||
prepare-adb:
|
||||
@./prepare-dep https://dl.google.com/android/repository/platform-tools_r27.0.1-windows.zip \
|
||||
880662adfb0d6911ff250b9e13930ae1a4110fc36d5866afd4f8f56d935f7939 \
|
||||
@./prepare-dep https://dl.google.com/android/repository/platform-tools_r28.0.0-windows.zip \
|
||||
e2c1ec7c8e9b71cf1c8befd3bff91d06b26dd334c3f32b3817e9d46ba260b0e8 \
|
||||
platform-tools
|
||||
|
||||
Reference in New Issue
Block a user