mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-02 22:29:25 +00:00
Merge 75ebbc5be4
into ace438e52a
This commit is contained in:
commit
f4cf89d994
6 changed files with 8546 additions and 0 deletions
|
@ -20,6 +20,7 @@ src = [
|
||||||
'src/stream.c',
|
'src/stream.c',
|
||||||
'src/tiny_xpm.c',
|
'src/tiny_xpm.c',
|
||||||
'src/video_buffer.c',
|
'src/video_buffer.c',
|
||||||
|
'src/lodepng.c',
|
||||||
'src/util/net.c',
|
'src/util/net.c',
|
||||||
'src/util/process.c',
|
'src/util/process.c',
|
||||||
'src/util/str_util.c'
|
'src/util/str_util.c'
|
||||||
|
|
|
@ -455,6 +455,11 @@ input_manager_process_key(struct input_manager *im,
|
||||||
screen_switch_fullscreen(im->screen);
|
screen_switch_fullscreen(im->screen);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case SDLK_q:
|
||||||
|
if (!shift && !repeat && down) {
|
||||||
|
im->screen->save_screenshot = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
case SDLK_w:
|
case SDLK_w:
|
||||||
if (!shift && !repeat && down) {
|
if (!shift && !repeat && down) {
|
||||||
screen_resize_to_fit(im->screen);
|
screen_resize_to_fit(im->screen);
|
||||||
|
|
6464
app/src/lodepng.c
Normal file
6464
app/src/lodepng.c
Normal file
File diff suppressed because it is too large
Load diff
1977
app/src/lodepng.h
Normal file
1977
app/src/lodepng.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "icon.xpm"
|
#include "icon.xpm"
|
||||||
#include "scrcpy.h"
|
#include "scrcpy.h"
|
||||||
#include "tiny_xpm.h"
|
#include "tiny_xpm.h"
|
||||||
#include "video_buffer.h"
|
#include "video_buffer.h"
|
||||||
|
#include "lodepng.h"
|
||||||
#include "util/lock.h"
|
#include "util/lock.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
|
@ -468,12 +470,107 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
save_screenshot(struct screen *screen) {
|
||||||
|
char filename[40];
|
||||||
|
struct tm *timenow;
|
||||||
|
SDL_Texture *ren_tex;
|
||||||
|
SDL_Surface *surf;
|
||||||
|
int st;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int format;
|
||||||
|
void *pixels;
|
||||||
|
|
||||||
|
pixels = NULL;
|
||||||
|
surf = NULL;
|
||||||
|
ren_tex = NULL;
|
||||||
|
format = SDL_PIXELFORMAT_RGBA32;
|
||||||
|
|
||||||
|
//Create filename
|
||||||
|
time_t now = time(NULL);
|
||||||
|
timenow = localtime(&now);
|
||||||
|
strftime(filename, sizeof(filename), "screenshot_%Y%m%d%H%M%S.png", timenow);
|
||||||
|
|
||||||
|
// Get information about texture we want to save
|
||||||
|
st = SDL_QueryTexture(screen->texture, NULL, NULL, &w, &h);
|
||||||
|
if (st != 0) {
|
||||||
|
LOGE("Failed querying texture: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ren_tex = SDL_CreateTexture(screen->renderer, format, SDL_TEXTUREACCESS_TARGET, w, h);
|
||||||
|
if (!ren_tex) {
|
||||||
|
LOGE("Failed creating render texture: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize our canvas, then copy texture to a target whose pixel data we
|
||||||
|
// can access
|
||||||
|
|
||||||
|
st = SDL_SetRenderTarget(screen->renderer, ren_tex);
|
||||||
|
if (st != 0) {
|
||||||
|
LOGE("Failed setting render target: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(screen->renderer, 0x00, 0x00, 0x00, 0x00);
|
||||||
|
SDL_RenderClear(screen->renderer);
|
||||||
|
|
||||||
|
st = SDL_RenderCopy(screen->renderer, screen->texture, NULL, NULL);
|
||||||
|
if (st != 0) {
|
||||||
|
LOGE("Failed copying texture data: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create buffer to hold texture data and load it
|
||||||
|
pixels = malloc(w * h * SDL_BYTESPERPIXEL(format));
|
||||||
|
if (!pixels) {
|
||||||
|
LOGE("Failed allocating memory\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
st = SDL_RenderReadPixels(screen->renderer, NULL, format, pixels, w * SDL_BYTESPERPIXEL(format));
|
||||||
|
if (st != 0) {
|
||||||
|
LOGE("Failed reading pixel data: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy pixel data over to surface
|
||||||
|
surf = SDL_CreateRGBSurfaceWithFormatFrom(pixels, w, h, SDL_BITSPERPIXEL(format), w * SDL_BYTESPERPIXEL(format), format);
|
||||||
|
if (!surf) {
|
||||||
|
LOGE("Failed creating new surface: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save result to an image
|
||||||
|
st = lodepng_encode_file(filename, surf->pixels, w, h, LCT_RGBA, 8);
|
||||||
|
if (st != 0) {
|
||||||
|
LOGE("Failed saving image: %s\n", SDL_GetError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGI("Saved screenshot to \"%s\"\n", filename);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
SDL_FreeSurface(surf);
|
||||||
|
free(pixels);
|
||||||
|
SDL_DestroyTexture(ren_tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_render(struct screen *screen, bool update_content_rect) {
|
screen_render(struct screen *screen, bool update_content_rect) {
|
||||||
if (update_content_rect) {
|
if (update_content_rect) {
|
||||||
screen_update_content_rect(screen);
|
screen_update_content_rect(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (screen->save_screenshot) {
|
||||||
|
screen->save_screenshot = false;
|
||||||
|
save_screenshot(screen);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_RenderClear(screen->renderer);
|
SDL_RenderClear(screen->renderer);
|
||||||
if (screen->rotation == 0) {
|
if (screen->rotation == 0) {
|
||||||
SDL_RenderCopy(screen->renderer, screen->texture, NULL, &screen->rect);
|
SDL_RenderCopy(screen->renderer, screen->texture, NULL, &screen->rect);
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct screen {
|
||||||
bool maximized;
|
bool maximized;
|
||||||
bool no_window;
|
bool no_window;
|
||||||
bool mipmaps;
|
bool mipmaps;
|
||||||
|
bool save_screenshot;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCREEN_INITIALIZER { \
|
#define SCREEN_INITIALIZER { \
|
||||||
|
@ -68,6 +69,7 @@ struct screen {
|
||||||
.maximized = false, \
|
.maximized = false, \
|
||||||
.no_window = false, \
|
.no_window = false, \
|
||||||
.mipmaps = false, \
|
.mipmaps = false, \
|
||||||
|
.save_screenshot = false,\
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize default values
|
// initialize default values
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue