Taking screenshot of one window by ID
TODO: iterate over entire tree and take separate screenshots of each window
This commit is contained in:
parent
ee68131914
commit
36cb48c650
|
@ -0,0 +1 @@
|
|||
scrall
|
|
@ -0,0 +1,12 @@
|
|||
CFLAGS += -Wall -Wextra `exec pkg-config --cflags raylib xcb xcb-composite`
|
||||
LDFLAGS := -lm `pkg-config --libs raylib xcb xcb-composite`
|
||||
|
||||
scrall: main.c
|
||||
$(CC) $(CFLAGS) main.c $(LDFLAGS) -o scrall
|
||||
|
||||
|
||||
clean:
|
||||
$(RM) scrall
|
||||
|
||||
run: scrall
|
||||
./scrall
|
|
@ -0,0 +1,85 @@
|
|||
// x-run: make run
|
||||
#include <assert.h>
|
||||
#include <raylib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xproto.h>
|
||||
#include <xcb/composite.h>
|
||||
|
||||
|
||||
Image get_screenshot(xcb_connection_t *conn, xcb_window_t wid);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
xcb_connection_t *xcb = xcb_connect(NULL, NULL);
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_TRANSPARENT);
|
||||
InitWindow(0, 0, "img/scrall");
|
||||
|
||||
|
||||
Image screenshot = get_screenshot(xcb, 50331654);
|
||||
assert(screenshot.width > 0);
|
||||
|
||||
Texture2D screenshot_tex = LoadTextureFromImage(screenshot);
|
||||
SetWindowSize(screenshot.width, screenshot.height);
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
BeginDrawing();
|
||||
ClearBackground(BLANK);
|
||||
DrawTexture(screenshot_tex, 0, 0, WHITE);
|
||||
EndDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
Image get_screenshot(xcb_connection_t *conn, xcb_window_t wid) {
|
||||
xcb_generic_error_t *err = NULL;
|
||||
|
||||
xcb_composite_redirect_window(conn, wid, XCB_COMPOSITE_REDIRECT_AUTOMATIC);
|
||||
|
||||
xcb_get_geometry_cookie_t gg_cookie = xcb_get_geometry(conn, wid);
|
||||
xcb_get_geometry_reply_t *gg_reply = xcb_get_geometry_reply(conn, gg_cookie, &err);
|
||||
|
||||
if (!gg_reply) {
|
||||
fprintf(stderr, "xcb: error: geometry: %d\n", err->error_code);
|
||||
return (Image){
|
||||
.data = err, .width = 0, .height = 0, .format = 0, .mipmaps = 0
|
||||
};
|
||||
}
|
||||
|
||||
int win_w = gg_reply->width;
|
||||
int win_h = gg_reply->height;
|
||||
assert(gg_reply->depth == 32);
|
||||
fprintf(stderr, "width: %d\nheight: %d\n", win_w, win_h);
|
||||
|
||||
free(gg_reply);
|
||||
|
||||
xcb_pixmap_t win_pixmap = xcb_generate_id(conn);
|
||||
xcb_composite_name_window_pixmap(conn, wid, win_pixmap);
|
||||
|
||||
xcb_get_image_cookie_t gi_cookie = xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, win_pixmap, 0, 0, win_w, win_h, (uint32_t)(~0UL));
|
||||
xcb_get_image_reply_t *gi_reply = xcb_get_image_reply(conn, gi_cookie, &err);
|
||||
if (!gi_reply) {
|
||||
fprintf(stderr, "xcb: error: get_image_reply: %d\n", err->error_code);
|
||||
return (Image){
|
||||
.data = err, .width = 0, .height = 0, .format = 0, .mipmaps = 0
|
||||
};
|
||||
}
|
||||
|
||||
int data_len = xcb_get_image_data_length(gi_reply);
|
||||
fprintf(stderr, "data_len: %d\n", data_len);
|
||||
|
||||
uint8_t *data = xcb_get_image_data(gi_reply);
|
||||
|
||||
Image img = GenImageColor(win_w, win_h, BLANK);
|
||||
|
||||
for (int i = 0; i < data_len; i += 4) {
|
||||
((uint8_t *)img.data)[i + 0] = data[i + 2];
|
||||
((uint8_t *)img.data)[i + 1] = data[i + 1];
|
||||
((uint8_t *)img.data)[i + 2] = data[i + 0];
|
||||
((uint8_t *)img.data)[i + 3] = data[i + 3];
|
||||
}
|
||||
|
||||
free(gi_reply);
|
||||
|
||||
return img;
|
||||
}
|
Loading…
Reference in New Issue