I’m trying to make a C++ Program for ubuntu which gets the rgb values of the Pixel hovered by the Mouse. To do that I need the XGetImage()
function but it always returns an Error code (Badmatch).
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
int main(int, char**) {
XColor c;
Display *display = XOpenDisplay((char *) NULL);
Window root = XRootWindow(display, XDefaultScreen(display));
XWindowAttributes attr;
XGetWindowAttributes(display, root, &attr);
XMapRaised(display, root);
unsigned int width = attr.width;
unsigned int height = attr.height;
root = attr.root;
/*
XQueryPointer(display, win, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask_return);
std::printf("root_x: %dtroot_y: %dnchild_x: %dtchild_y: %dn",
root_x,
root_y,
win_x,
win_y
);*/
XMapRaised(display, root);
XImage *image = XGetImage(display, root, 0, 0, 100, 100, AllPlanes, ZPixmap);
c.pixel = XGetPixel(image, 0, 0);
std::cout << c.red << std::endl;
XFree(image);
XQueryColor(display, XDefaultColormap(display, XDefaultScreen(display)), &c);
std::cout << c.red << " " << c.green << " " << c.blue << std::endl;
XCloseDisplay(display);
return 0;
}
Edit 1
I tested the minimal Example given below but it still throws an Error. So I decided to query all child Windows and tried to iterate through them backwards. But the first child already caused an error as well.
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
int main(int, char**) {
//XColor c;
Display *display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
Window root_root, parent;
Window *children;
unsigned int returned_children;
XQueryTree(display, root, &root_root, &parent, &children, &returned_children);
for (int i = returned_children -1; i >= 0; i--) {
std::cout << i << std::endl;
XImage *image = XGetImage(display, root, 0, 0, 100, 100, AllPlanes, ZPixmap);
if (image) {
std::printf("%d %d (%p)n", image->width, image->height, image->data);
}
}
}
2
Answers
It turns out that
XGetImage()
needs a Window that is currently visible on the screen. I solved the Problem by passing the child Window queried from the functionXQueryPointer()
.The following code works on my system (Arch, Gnome, Dual Screen, Nvidia, No Xinerama – root window size 3840×1080 – correct values from
XGetWindowAttributes
and same image size fromXGetImage
):Compilation:
Output:
From XGetImage:
As a conclusion, test the minimal code above. If you still get errors, query the tree and test the subsequent windows.