Compare commits

..

1 Commits

Author SHA1 Message Date
Romain Vimont
f049b6bc1b Use Cmd instead of Ctrl on macOS when possible
Fixes <https://github.com/Genymobile/scrcpy/issues/642>
2019-08-01 21:29:07 +02:00
7 changed files with 70 additions and 141 deletions

View File

@@ -125,12 +125,12 @@ dist-win64: build-server build-win64 build-win64-noconsole
cp prebuilt-deps/SDL2-2.0.8/x86_64-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
zip-win32: dist-win32
cd "$(DIST)/$(WIN32_TARGET_DIR)"; \
zip -r "../$(WIN32_TARGET)" .
cd "$(DIST)"; \
zip -r "$(WIN32_TARGET)" "$(WIN32_TARGET_DIR)"
zip-win64: dist-win64
cd "$(DIST)/$(WIN64_TARGET_DIR)"; \
zip -r "../$(WIN64_TARGET)" .
cd "$(DIST)"; \
zip -r "$(WIN64_TARGET)" "$(WIN64_TARGET_DIR)"
sums:
cd "$(DIST)"; \

View File

@@ -150,9 +150,6 @@ tests = [
'tests/test_device_msg_deserialize.c',
'src/device_msg.c'
]],
['test_queue', [
'tests/test_queue.c',
]],
['test_strutil', [
'tests/test_strutil.c',
'src/str_util.c'

View File

@@ -6,7 +6,7 @@
#include <unistd.h>
// To define a circular buffer type of 20 ints:
// struct cbuf_int CBUF(int, 20);
// typedef CBUF(int, 20) my_cbuf_t;
//
// data has length CAP + 1 to distinguish empty vs full.
#define CBUF(TYPE, CAP) { \
@@ -35,7 +35,7 @@
(PCBUF)->head = ((PCBUF)->head + 1) % cbuf_size_(PCBUF); \
} \
ok; \
})
}) \
#define cbuf_take(PCBUF, PITEM) \
({ \

View File

@@ -1,74 +0,0 @@
// generic intrusive FIFO queue
#ifndef QUEUE_H
#define QUEUE_H
#include <stdbool.h>
#include <SDL2/SDL_assert.h>
// To define a queue type of "struct foo":
// struct queue_foo QUEUE(struct foo);
#define QUEUE(TYPE) { \
TYPE *first; \
TYPE *last; \
}
#define queue_init(PQ) \
(void) ((PQ)->first = NULL)
#define queue_is_empty(PQ) \
!(PQ)->first
// NEXTFIELD is the field in the ITEM type used for intrusive linked-list
//
// For example:
// struct foo {
// int value;
// struct foo *next;
// };
//
// // define the type "struct my_queue"
// struct my_queue QUEUE(struct foo);
//
// struct my_queue queue;
// queue_init(&queue);
//
// struct foo v1 = { .value = 42 };
// struct foo v2 = { .value = 27 };
//
// queue_push(&queue, next, v1);
// queue_push(&queue, next, v2);
//
// struct foo *foo;
// queue_take(&queue, next, &foo);
// assert(foo->value == 42);
// queue_take(&queue, next, &foo);
// assert(foo->value == 27);
// assert(queue_is_empty(&queue));
//
// push a new item into the queue
#define queue_push(PQ, NEXTFIELD, ITEM) \
(void) ({ \
(ITEM)->NEXTFIELD = NULL; \
if (queue_is_empty(PQ)) { \
(PQ)->first = (PQ)->last = (ITEM); \
} else { \
(PQ)->last->NEXTFIELD = (ITEM); \
(PQ)->last = (ITEM); \
} \
})
// take the next item and remove it from the queue (the queue must not be empty)
// the result is stored in *(PITEM)
// (without typeof(), we could not store a local variable having the correct
// type so that we can "return" it)
#define queue_take(PQ, NEXTFIELD, PITEM) \
(void) ({ \
SDL_assert(!queue_is_empty(PQ)); \
*(PITEM) = (PQ)->first; \
(PQ)->first = (PQ)->first->NEXTFIELD; \
})
// no need to update (PQ)->last if the queue is left empty:
// (PQ)->last is undefined if !(PQ)->first anyway
#endif

View File

@@ -37,6 +37,7 @@ record_packet_new(const AVPacket *packet) {
SDL_free(rec);
return NULL;
}
rec->next = NULL;
return rec;
}
@@ -47,12 +48,59 @@ record_packet_delete(struct record_packet *rec) {
}
static void
recorder_queue_clear(struct recorder_queue *queue) {
while (!queue_is_empty(queue)) {
struct record_packet *rec;
queue_take(queue, next, &rec);
record_packet_delete(rec);
recorder_queue_init(struct recorder_queue *queue) {
queue->first = NULL;
// queue->last is undefined if queue->first == NULL
}
static inline bool
recorder_queue_is_empty(struct recorder_queue *queue) {
return !queue->first;
}
static bool
recorder_queue_push(struct recorder_queue *queue, const AVPacket *packet) {
struct record_packet *rec = record_packet_new(packet);
if (!rec) {
LOGC("Could not allocate record packet");
return false;
}
rec->next = NULL;
if (recorder_queue_is_empty(queue)) {
queue->first = queue->last = rec;
} else {
// chain rec after the (current) last packet
queue->last->next = rec;
// the last packet is now rec
queue->last = rec;
}
return true;
}
static inline struct record_packet *
recorder_queue_take(struct recorder_queue *queue) {
SDL_assert(!recorder_queue_is_empty(queue));
struct record_packet *rec = queue->first;
SDL_assert(rec);
queue->first = rec->next;
// no need to update queue->last if the queue is left empty:
// queue->last is undefined if queue->first == NULL
return rec;
}
static void
recorder_queue_clear(struct recorder_queue *queue) {
struct record_packet *rec = queue->first;
while (rec) {
struct record_packet *current = rec;
rec = rec->next;
record_packet_delete(current);
}
queue->first = NULL;
}
bool
@@ -81,7 +129,7 @@ recorder_init(struct recorder *recorder,
return false;
}
queue_init(&recorder->queue);
recorder_queue_init(&recorder->queue);
recorder->stopped = false;
recorder->failed = false;
recorder->format = format;
@@ -248,20 +296,20 @@ run_recorder(void *data) {
for (;;) {
mutex_lock(recorder->mutex);
while (!recorder->stopped && queue_is_empty(&recorder->queue)) {
while (!recorder->stopped &&
recorder_queue_is_empty(&recorder->queue)) {
cond_wait(recorder->queue_cond, recorder->mutex);
}
// if stopped is set, continue to process the remaining events (to
// finish the recording) before actually stopping
if (recorder->stopped && queue_is_empty(&recorder->queue)) {
if (recorder->stopped && recorder_queue_is_empty(&recorder->queue)) {
mutex_unlock(recorder->mutex);
break;
}
struct record_packet *rec;
queue_take(&recorder->queue, next, &rec);
struct record_packet *rec = recorder_queue_take(&recorder->queue);
mutex_unlock(recorder->mutex);
@@ -321,15 +369,9 @@ recorder_push(struct recorder *recorder, const AVPacket *packet) {
return false;
}
struct record_packet *rec = record_packet_new(packet);
if (!rec) {
LOGC("Could not allocate record packet");
return false;
}
queue_push(&recorder->queue, next, rec);
bool ok = recorder_queue_push(&recorder->queue, packet);
cond_signal(recorder->queue_cond);
mutex_unlock(recorder->mutex);
return true;
return ok;
}

View File

@@ -7,7 +7,6 @@
#include <SDL2/SDL_thread.h>
#include "common.h"
#include "queue.h"
enum recorder_format {
RECORDER_FORMAT_MP4 = 1,
@@ -19,7 +18,10 @@ struct record_packet {
struct record_packet *next;
};
struct recorder_queue QUEUE(struct record_packet);
struct recorder_queue {
struct record_packet *first;
struct record_packet *last; // undefined if first is NULL
};
struct recorder {
char *filename;

View File

@@ -1,38 +0,0 @@
#include <assert.h>
#include <queue.h>
struct foo {
int value;
struct foo *next;
};
static void test_queue(void) {
struct my_queue QUEUE(struct foo) queue;
queue_init(&queue);
assert(queue_is_empty(&queue));
struct foo v1 = { .value = 42 };
struct foo v2 = { .value = 27 };
queue_push(&queue, next, &v1);
queue_push(&queue, next, &v2);
struct foo *foo;
assert(!queue_is_empty(&queue));
queue_take(&queue, next, &foo);
assert(foo->value == 42);
assert(!queue_is_empty(&queue));
queue_take(&queue, next, &foo);
assert(foo->value == 27);
assert(queue_is_empty(&queue));
}
int main(void) {
test_queue();
return 0;
}