Misc #204: Add glx_take_screenshot() & others
- Add glx_take_screenshot() for taking a screenshot. With ImageMagick the output data could be viewed in this way: display -size [SCREEN-WIDTH]x[SCREEN-HEIGHT] -depth 8 -flip rgb:[PATH] (#204) - Add D-Bus command `opts_get string:paint_on_overlay_id` to get X Composite overlay window ID. (#204) - Code cleanup.
This commit is contained in:
parent
c5f45c8e3c
commit
8c88b4d6f1
25
src/common.h
25
src/common.h
|
@ -2208,6 +2208,9 @@ glx_render_(session_t *ps, const glx_texture_t *ptex,
|
||||||
void
|
void
|
||||||
glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg);
|
glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg);
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
glx_take_screenshot(session_t *ps, int *out_length);
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
GLuint
|
GLuint
|
||||||
glx_create_shader(GLenum shader_type, const char *shader_str);
|
glx_create_shader(GLenum shader_type, const char *shader_str);
|
||||||
|
@ -2484,6 +2487,28 @@ c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dump the given data to a file.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
write_binary_data(const char *path, const unsigned char *data, int length) {
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
FILE *f = fopen(path, "wb");
|
||||||
|
if (!f) {
|
||||||
|
printf_errf("(\"%s\"): Failed to open file for writing.", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int wrote_len = fwrite(data, sizeof(unsigned char), length, f);
|
||||||
|
fclose(f);
|
||||||
|
if (wrote_len != length) {
|
||||||
|
printf_errf("(\"%s\"): Failed to write all blocks: %d / %d", path,
|
||||||
|
wrote_len, length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dump raw bytes in HEX format.
|
* @brief Dump raw bytes in HEX format.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1411,6 +1411,20 @@ xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORK-IN-PROGRESS!
|
||||||
|
static void
|
||||||
|
xr_take_screenshot(session_t *ps) {
|
||||||
|
XImage *img = XGetImage(ps->dpy, get_tgt_window(ps), 0, 0,
|
||||||
|
ps->root_width, ps->root_height, AllPlanes, XYPixmap);
|
||||||
|
if (!img) {
|
||||||
|
printf_errf("(): Failed to get XImage.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
assert(0 == img->xoffset);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blur the background of a window.
|
* Blur the background of a window.
|
||||||
*/
|
*/
|
||||||
|
@ -7530,6 +7544,16 @@ session_destroy(session_t *ps) {
|
||||||
ps_g = NULL;
|
ps_g = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static inline void
|
||||||
|
dump_img(session_t *ps) {
|
||||||
|
int len = 0;
|
||||||
|
unsigned char *d = glx_take_screenshot(ps, &len);
|
||||||
|
write_binary_data("/tmp/dump.raw", d, len);
|
||||||
|
free(d);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the actual work.
|
* Do the actual work.
|
||||||
*
|
*
|
||||||
|
|
|
@ -901,6 +901,11 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
|
||||||
cdbus_m_opts_get_do(fork_after_register, cdbus_reply_bool);
|
cdbus_m_opts_get_do(fork_after_register, cdbus_reply_bool);
|
||||||
cdbus_m_opts_get_do(detect_rounded_corners, cdbus_reply_bool);
|
cdbus_m_opts_get_do(detect_rounded_corners, cdbus_reply_bool);
|
||||||
cdbus_m_opts_get_do(paint_on_overlay, cdbus_reply_bool);
|
cdbus_m_opts_get_do(paint_on_overlay, cdbus_reply_bool);
|
||||||
|
// paint_on_overlay_id: Get ID of the X composite overlay window
|
||||||
|
if (!strcmp("paint_on_overlay_id", target)) {
|
||||||
|
cdbus_reply_uint32(ps, msg, ps->overlay);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
cdbus_m_opts_get_do(unredir_if_possible, cdbus_reply_bool);
|
cdbus_m_opts_get_do(unredir_if_possible, cdbus_reply_bool);
|
||||||
cdbus_m_opts_get_do(unredir_if_possible_delay, cdbus_reply_int32);
|
cdbus_m_opts_get_do(unredir_if_possible_delay, cdbus_reply_int32);
|
||||||
cdbus_m_opts_get_do(redirected_force, cdbus_reply_enum);
|
cdbus_m_opts_get_do(redirected_force, cdbus_reply_enum);
|
||||||
|
|
26
src/opengl.c
26
src/opengl.c
|
@ -1754,6 +1754,32 @@ glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg) {
|
||||||
cxfree(rects);
|
cxfree(rects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tightly packed RGB888 data from GL front buffer.
|
||||||
|
*
|
||||||
|
* Don't expect any sort of decent performance.
|
||||||
|
*
|
||||||
|
* @returns tightly packed RGB888 data of the size of the screen,
|
||||||
|
* to be freed with `free()`
|
||||||
|
*/
|
||||||
|
unsigned char *
|
||||||
|
glx_take_screenshot(session_t *ps, int *out_length) {
|
||||||
|
int length = 3 * ps->root_width * ps->root_height;
|
||||||
|
GLint unpack_align_old = 0;
|
||||||
|
glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_align_old);
|
||||||
|
assert(unpack_align_old > 0);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
unsigned char *buf = cmalloc(length, unsigned char);
|
||||||
|
glReadBuffer(GL_FRONT);
|
||||||
|
glReadPixels(0, 0, ps->root_width, ps->root_height, GL_RGB,
|
||||||
|
GL_UNSIGNED_BYTE, buf);
|
||||||
|
glReadBuffer(GL_BACK);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_align_old);
|
||||||
|
if (out_length)
|
||||||
|
*out_length = sizeof(unsigned char) * length;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
GLuint
|
GLuint
|
||||||
glx_create_shader(GLenum shader_type, const char *shader_str) {
|
glx_create_shader(GLenum shader_type, const char *shader_str) {
|
||||||
|
|
Loading…
Reference in New Issue