当前位置: 首页 > news >正文

外贸网站开发定制温州广厦网页制作

外贸网站开发定制,温州广厦网页制作,搜索引擎是网站吗,知名网站建设托管在 Linux X11 下枚举窗口并获取窗口信息 在 Linux 系统中,X11 是一个非常流行的窗口系统,它提供了丰富的 API 用于管理和操作窗口。在这篇博客中,我们将详细介绍如何使用 X11 枚举当前系统中的窗口,并获取它们的标题、截图、进程…

在 Linux X11 下枚举窗口并获取窗口信息

在 Linux 系统中,X11 是一个非常流行的窗口系统,它提供了丰富的 API 用于管理和操作窗口。在这篇博客中,我们将详细介绍如何使用 X11 枚举当前系统中的窗口,并获取它们的标题、截图、进程路径、进程图标等信息。

环境准备

首先,我们需要安装一些必要的库和工具:

sudo apt-get install libx11-dev libxcomposite-dev libxext-dev

枚举窗口

我们将使用 X11 提供的 XQueryTree 函数来枚举当前系统中的所有窗口。以下是一个简单的示例代码:

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <vector>
#include <string>
#include <iostream>struct WindowInfo {::Window window;std::string title;std::string process_path;std::vector<uint8_t> icon_data;int icon_width;int icon_height;
};std::vector<WindowInfo> enum_windows(Display *display) {std::vector<WindowInfo> windows;::Window root = DefaultRootWindow(display);::Window parent;::Window *children;unsigned int num_children;if (XQueryTree(display, root, &root, &parent, &children, &num_children)) {for (unsigned int i = 0; i < num_children; ++i) {WindowInfo info;info.window = children[i];// 获取窗口标题XTextProperty window_name;if (XGetWMName(display, children[i], &window_name) && window_name.value) {info.title = (char *)window_name.value;XFree(window_name.value);}// 获取进程路径Atom pid_atom = XInternAtom(display, "_NET_WM_PID", True);if (pid_atom != None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop = nullptr;if (XGetWindowProperty(display, children[i], pid_atom, 0, 1, False, XA_CARDINAL,&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success && nitems > 0) {pid_t pid = *(pid_t *)prop;XFree(prop);char path[1024];snprintf(path, sizeof(path), "/proc/%d/exe", pid);char exe_path[1024];ssize_t len = readlink(path, exe_path, sizeof(exe_path) - 1);if (len != -1) {exe_path[len] = '\0';info.process_path = exe_path;}}}// 获取窗口图标Atom icon_atom = XInternAtom(display, "_NET_WM_ICON", True);if (icon_atom != None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop = nullptr;if (XGetWindowProperty(display, children[i], icon_atom, 0, (~0L), False, AnyPropertyType,&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success && nitems > 0) {unsigned long *data = (unsigned long *)prop;info.icon_width = data[0];info.icon_height = data[1];info.icon_data.assign((uint8_t *)(data + 2), (uint8_t *)(data + 2 + info.icon_width * info.icon_height));XFree(prop);}}windows.push_back(info);}XFree(children);}return windows;
}int main() {Display *display = XOpenDisplay(NULL);if (!display) {std::cerr << "Failed to open display" << std::endl;return -1;}std::vector<WindowInfo> windows = enum_windows(display);for (const auto &window : windows) {std::cout << "Window ID: " << window.window << std::endl;std::cout << "Title: " << window.title << std::endl;std::cout << "Process Path: " << window.process_path << std::endl;std::cout << "Icon Size: " << window.icon_width << "x" << window.icon_height << std::endl;std::cout << std::endl;}XCloseDisplay(display);return 0;
}

获取窗口截图

为了获取窗口的截图,我们可以使用 XGetImage 函数。以下是一个示例代码:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <vector>
#include <iostream>
#include <fstream>void save_ximage_to_ppm(const char *filename, XImage *image) {std::ofstream ofs(filename, std::ios::binary);ofs << "P6\n" << image->width << " " << image->height << "\n255\n";for (int y = 0; y < image->height; ++y) {for (int x = 0; x < image->width; ++x) {unsigned long pixel = XGetPixel(image, x, y);unsigned char r = (pixel & image->red_mask) >> 16;unsigned char g = (pixel & image->green_mask) >> 8;unsigned char b = (pixel & image->blue_mask);ofs.put(r).put(g).put(b);}}
}void capture_window(Display *display, ::Window window, const char *filename) {XWindowAttributes attributes;XGetWindowAttributes(display, window, &attributes);XImage *image = XGetImage(display, window, 0, 0, attributes.width, attributes.height, AllPlanes, ZPixmap);if (image) {save_ximage_to_ppm(filename, image);XDestroyImage(image);}
}int main() {Display *display = XOpenDisplay(NULL);if (!display) {std::cerr << "Failed to open display" << std::endl;return -1;}::Window root = DefaultRootWindow(display);capture_window(display, root, "screenshot.ppm");XCloseDisplay(display);return 0;
}

结合所有功能

我们可以将上述功能结合起来,创建一个完整的程序来枚举窗口并获取它们的标题、截图、进程路径、进程图标等信息。

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>struct WindowInfo {::Window window;std::string title;std::string process_path;std::vector<uint8_t> icon_data;int icon_width;int icon_height;
};void save_ximage_to_ppm(const char *filename, XImage *image) {std::ofstream ofs(filename, std::ios::binary);ofs << "P6\n" << image->width << " " << image->height << "\n255\n";for (int y = 0; y < image->height; ++y) {for (int x = 0; x < image->width; ++x) {unsigned long pixel = XGetPixel(image, x, y);unsigned char r = (pixel & image->red_mask) >> 16;unsigned char g = (pixel & image->green_mask) >> 8;unsigned char b = (pixel & image->blue_mask);ofs.put(r).put(g).put(b);}}
}void capture_window(Display *display, ::Window window, const char *filename) {XWindowAttributes attributes;XGetWindowAttributes(display, window, &attributes);XImage *image = XGetImage(display, window, 0, 0, attributes.width, attributes.height, AllPlanes, ZPixmap);if (image) {save_ximage_to_ppm(filename, image);XDestroyImage(image);}
}std::vector<WindowInfo> enum_windows(Display *display) {std::vector<WindowInfo> windows;::Window root = DefaultRootWindow(display);::Window parent;::Window *children;unsigned int num_children;if (XQueryTree(display, root, &root, &parent, &children, &num_children)) {for (unsigned int i = 0; i < num_children; ++i) {WindowInfo info;info.window = children[i];// 获取窗口标题XTextProperty window_name;if (XGetWMName(display, children[i], &window_name) && window_name.value) {info.title = (char *)window_name.value;XFree(window_name.value);}// 获取进程路径Atom pid_atom = XInternAtom(display, "_NET_WM_PID", True);if (pid_atom != None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop = nullptr;if (XGetWindowProperty(display, children[i], pid_atom, 0, 1, False, XA_CARDINAL,&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success && nitems > 0) {pid_t pid = *(pid_t *)prop;XFree(prop);char path[1024];snprintf(path, sizeof(path), "/proc/%d/exe", pid);char exe_path[1024];ssize_t len = readlink(path, exe_path, sizeof(exe_path) - 1);if (len != -1) {exe_path[len] = '\0';info.process_path = exe_path;}}}// 获取窗口图标Atom icon_atom = XInternAtom(display, "_NET_WM_ICON", True);if (icon_atom != None) {Atom actual_type;int actual_format;unsigned long nitems, bytes_after;unsigned char *prop = nullptr;if (XGetWindowProperty(display, children[i], icon_atom, 0, (~0L), False, AnyPropertyType,&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success && nitems > 0) {unsigned long *data = (unsigned long *)prop;info.icon_width = data[0];info.icon_height = data[1];info.icon_data.assign((uint8_t *)(data + 2), (uint8_t *)(data + 2 + info.icon_width * info.icon_height));XFree(prop);}}windows.push_back(info);}XFree(children);}return windows;
}int main() {Display *display = XOpenDisplay(NULL);if (!display) {std::cerr << "Failed to open display" << std::endl;return -1;}std::vector<WindowInfo> windows = enum_windows(display);for (const auto &window : windows) {std::cout << "Window ID: " << window.window << std::endl;std::cout << "Title: " << window.title << std::endl;std::cout << "Process Path: " << window.process_path << std::endl;std::cout << "Icon Size: " << window.icon_width << "x" << window.icon_height << std::endl;// 保存窗口截图std::string screenshot_filename = "screenshot_" + std::to_string(window.window) + ".ppm";capture_window(display, window.window, screenshot_filename.c_str());std::cout << "Screenshot saved to: " << screenshot_filename << std::endl;std::cout << std::endl;}XCloseDisplay(display);return 0;
}

需要注意获取ICON数据时候的特殊处理

get_window_icon 函数中,对于不同架构(32位和64位)的实现有所不同,这是因为在不同架构下,数据的存储方式和处理方式有所不同。以下是对该函数中不同架构实现的原因和方法的详细解释。

原因

  1. 数据存储方式不同

    • 在32位架构下,unsigned long 类型的大小是32位(4字节)。
    • 在64位架构下,unsigned long 类型的大小是64位(8字节),但实际数据只使用了低32位,高32位是填充的。
  2. 数据处理方式不同

    • 在32位架构下,可以直接复制整个内存块,因为数据是连续存储的。
    • 在64位架构下,需要逐个元素处理,因为每个元素是64位的,但实际数据只使用了低32位。

方法

32位架构实现

在32位架构下,直接复制整个内存块,因为数据是连续存储的,且每个元素的大小是32位。

#if defined(TRAA_ARCH_32_BITS)icon_data.assign(prop + 2 * sizeof(unsigned long), prop + nitems * sizeof(unsigned long));
#endif

这里使用 std::vector::assign 方法将图标数据从 prop 中复制到 icon_data 向量中。prop + 2 * sizeof(unsigned long) 跳过了前两个元素(宽度和高度),prop + nitems * sizeof(unsigned long) 表示复制整个内存块。

64位架构实现

在64位架构下,需要逐个元素处理,因为每个元素是64位的,但实际数据只使用了低32位。

#elif defined(TRAA_ARCH_64_BITS)// TODO: this can be optimized by using some SIMD instructions.icon_data.resize(width * height * desktop_frame::bytes_per_pixel);for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {unsigned long pixel = data[2 + y * width + x];icon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 3] = (pixel >> (24)) & 0xff; // Bicon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 2] = (pixel >> (16)) & 0xff; // Gicon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 1] = (pixel >> (8)) & 0xff;  // Ricon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 0] = pixel & 0xff;           // A}}
#endif

这里逐个像素处理,将每个像素的ARGB值提取出来并存储到 icon_data 向量中。具体步骤如下:

  1. 调整 icon_data 的大小

    icon_data.resize(width * height * desktop_frame::bytes_per_pixel);
    

    调整 icon_data 的大小以容纳所有像素数据。

  2. 逐个像素处理

    for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {unsigned long pixel = data[2 + y * width + x];icon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 3] = (pixel >> (24)) & 0xff; // Bicon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 2] = (pixel >> (16)) & 0xff; // Gicon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 1] = (pixel >> (8)) & 0xff;  // Ricon_data[(y * width + x) * desktop_frame::bytes_per_pixel + 0] = pixel & 0xff;           // A}
    }
    

    逐个像素处理,将每个像素的ARGB值提取出来并存储到 icon_data 向量中。

总结

get_window_icon 函数中,对于不同架构的不同实现是为了适应32位和64位架构下数据存储和处理方式的不同。在32位架构下,可以直接复制整个内存块,而在64位架构下,需要逐个元素处理,以确保数据的正确性。

PS

Copilot生成的博客,还算有点乱和抓不住重点细节…感兴趣的去看源码吧还是,细节都在代码里了.

源码传送

traa

http://www.yayakq.cn/news/267831/

相关文章:

  • 做网站怎么改关键词龙采哈尔滨建站公司
  • vps上创建网站广州市企业网站建设
  • 欧美网站模板php做电子商务网站的种类
  • openwrt 网站开发2023年九月份新闻
  • 营销型网站建设主要需要注意什么建设部建设厅报考网站
  • 驻马店网站优化怎么建设淘客自己的网站
  • 焦作网站设计公司家用电脑做网站教程
  • 幻灯片在什么网站做网站可以不进行icp备案吗
  • 同企网站建设做网站查域名的网站
  • 注册外贸网站有哪些问题大牌网页设计
  • 南京网站设计外包网站建设代码流程
  • 制作网站的知识客户关系管理定义
  • o2o网站建设方案pptseo培训赚钱
  • 子目录网站互联网推广方法
  • 网站开发用什么架构湖南建设信息网官网
  • 网站开发工具软件网站开发和网站运营
  • 建设项目从哪个网站可以查富文本编辑器wordpress
  • 厦门 做网站WordPress 镜像同步
  • 三明鑫龙建设工程网站郑州公司建站搭建
  • 公网ip做网站访问不安康seo
  • 单一产品网站如何做seo快速做网站的技术
  • 如何做好网站内更新做一个展示网站多少钱
  • 深圳鼎诚网站建设十大网页设计大全
  • iis 临时网站天津市建设局网站
  • 郑州区块链数字钱包网站开发公司石家庄seo推广
  • 布谷 海南网站建设wp企业网站模板
  • 集团网站手机版学生班级优化大师
  • 用什么网站做动感相册建设网站用户名
  • 做图书网站赚钱吗电脑传奇网站
  • 丹灶网站建设公司c可以做网站吗