linux X11窗口开发

13 篇文章 0 订阅

X11 控制窗口

窗口信息查询

检索窗口信息工具 xprop
xprop执行后会出现一个光标,这个光标可以获取到窗口信息
在这里插入图片描述

X11 获取窗口信息,操作窗口

X11 遍历获取当前显示窗口的标题 _NET_WM_NAME, 置顶模拟键盘输入操作

开发依赖

apt install libX11-dev libXtst-dev

头文件

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysysm.h>
#include <X11/extensions/XTest.h>

编译关联

g++ -o main main.cpp -lX11 -lXtst

1.获取当前的显示和根窗口

Display* display = XOpenDisplay(NULL);
if (display == NULL) {
    std::cerr << "Unable to open display" << std::endl;
    return -1;
}
Window root = XDefaultRootWindow(display);
PrintAllWindows(display, root);
XCloseDisplay(display);

2.遍历当前窗口所有的子窗口

void PrintAllWindows(Display* display, Window root) {
    Window parent;
    Window* children;
    unsigned int num_children;
    char* windowName;
    if (XQueryTree(display, root, &root, &parent, &children, &num_children)) {
        for (unsigned int i = 0; i < num_children; i++) {
            PrintWindowInfo(display, children[i]);
            PrintAllWindows(display, children[i]);
        }
        if (children) {
            XFree(children);
        }
    }
}

3.窗口信息查看

void PrintWindowInfo(Display* display, Window window) {
    Atom ca = XInternAtom(display, "_NET_WM_NAME", False);
    Atom actual_type;
    int  actual_format;
    unsigned long nitems, bytes_after;
    unsigned char* prop_return = NULL;
    if (XGetWindowProperty(display, window, ca, 0, (~0L), False, AnyPropertyType,
    &actual_type, &actual_format, &nitems, &bytes_after, &prop_return) == Success) {
        std::string value;
        value.assign((char*)prop_return, nitems);
        std::cout << "atom:" << XGetAtomName(display, ca) << std::endl;
        std::cout << "Value:" << value << std::endl;
        std::cout << "window:" << window << std::endl;
        }
    }
}

4.窗口置顶

void ActivateWindow(Display* display, Window window) {
    XEvent event = { 0 };
    event.xclient.type = ClientMessage;
    event.xclient.message_type = XInternAtom(display, "_NET_ACTIVE_WINDOW", False);
    event.xclient.display = display;
    event.xclient.window = window;
    event.xclient.format = 32;
    event.xclient.data.l[0] = 2;
    event.xclient.data.l[1] = CurrentTime;
    event.xclient.data.l[2] = 0;
    event.xclient.data.l[3] = 0;
    event.xclient.data.l[4] = 0;
    Window root = XDefaultRootWindow(display);
    XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
}

5.模拟键盘按键

unsigned int keycode = XKeysymToKeyCode(display, XK_Page_Down);
XTestFakeKeyEvent(display, keycode, True, 0);
XTestFakeKeyEvent(display, keycode, False, 0);

X11 屏幕抓取转为png base64输出

依赖安装

apt install libpng-dev libX11-dev

编译

g++ -o screen ScreenCap.cpp base64.cpp -lpng -lX11
#include <iostream>
#include <vector>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <png.h>
#include <base64/base64.h>


void userWriteData(png_structp png_ptr, png_bytep data, png_size_t length) {
    std::vector<uint8_t>* p = (std::vector<uint8_t>*) png_get_io_ptr(png_ptr);
    p->insert(p->end(), data, data + length);
}




int main() {
    Display* display = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(display);
    XWindowAttributes gwa;
    XGetWindowAttributes(display, root, &gwa);
    int width = gwa.width;
    int height = gwa.height;


    XImage* image = XGetImage(display, root, 0, 0, width, height, AllPlanes, ZPixmap);


    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    setjmp(png_jmpbuf(png));


    std::vector<uint8_t> buffer;


    png_set_write_fn(png, &buffer, userWriteData, NULL);


    png_set_IHDR(
        png,
        info,
        width, height,
        8,
        PNG_COLOR_TYPE_RGBA,
        PNG_INTERLACE_NONE,
        PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT
    );


    png_write_info(png, info);


    png_bytep row = (png_bytep) malloc(4 * width * sizeof(png_byte));
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            uint32_t pixel = XGetPixel(image, x, y);
            row[x*4] = (pixel >> 16) & 0xFF;
            row[x*4 + 1] = (pixel >> 8) & 0xFF;
            row[x*4 + 2] = pixel & 0xFF;
            row[x*4 + 3] = 0xFF;
        }
        png_write_row(png, row);
    }
    png_write_end(png, NULL);


    png_destroy_write_struct(&png, &info);
    free(row);
    XFree(image);
    XCloseDisplay(display);


    std::string b64_data = base64_encode(buffer.data(), buffer.size(), false);


    std::cout << b64_data << std::endl;


    return 0;
}
  • 21
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

frankz61

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值