T
T
Tolik2014-04-08 20:30:49
linux
Tolik, 2014-04-08 20:30:49

X11 C - how to write a function to find a pixel on the screen?

I want to create an analogue of UOpilot for Linux. At the moment I'm trying to create a normal function to find a pixel of a particular color on the screen. I wandered around the Internet for a bit and riveted the following code:

char *findColor_range(int startX, int startY,
            int endX, int endY,
            int startRed, int endRed, int startGreen, int endGreen, int startBlue, int endBlue) {
  Display *d = XOpenDisplay((char *) NULL);
  XImage *image;
  int x, y;
  XColor c;
  char *res;

  for(x = startX; x <= endX; x++) {
    for(y = startY; y <= endY; y++) {
      image = XGetImage(d, RootWindow(d, DefaultScreen(d)), x, y, 1, 1, AllPlanes, XYPixmap);
      c.pixel = XGetPixel(image, 0, 0);
      XFree(image);
      XQueryColor(d, DefaultColormap(d, DefaultScreen(d)), &c);
      if(c.red / 256 >= startRed && c.red / 256 <= endRed &&
         c.green / 256 >= startGreen && c.green / 256 <= endGreen &&
         c.blue / 256 >= startBlue && c.blue / 256 <= endBlue) {
        asprintf(&res, "%d,%d", x, y);
        return res;
      }
    }
  }
  asprintf(&res, "0");
  return res;
}

The search works here not by a specific color, but by a range of colors. By the name of the variables and the code, I think you will understand. It works (although not very fast, 300x300 combed in 4 seconds). And here is the function where by a specific color, but a different search algorithm:
char *findColor(int startX, int startY,
        int endX, int endY,
        int red, int green, int blue) {
  Display *d = XOpenDisplay((char *) NULL);
  XImage *image;
  int x, y;
  XColor c;
  char *res;

  image = XGetImage(d, RootWindow(d, DefaultScreen(d)), startX, startY, endX - startX, endY - startY, AllPlanes, XYPixmap);

  for(x = startX; x <= endX; x++) {
    for(y = startY; y <= endY; y++) {
      c.pixel = XGetPixel(image, x - startX, y - startY);
      XFree(image);
      XQueryColor(d, DefaultColormap(d, DefaultScreen(d)), &c);
      if(c.red / 256 == red && c.green / 256 == green && c.blue / 256 == blue) {
        asprintf(&res, "%d,%d", x, y);
        return res;
      }
    }
  }
  asprintf(&res, "0");
  return res;
}

Here I wanted to make sure that XGetImage is called only once, and accordingly this "picture" will also need to be searched. Well, on the other hand, you don’t have to take it separately for each pixel each time. So, during the execution of this second function, I have a lot of errors (in general, an addressing error). You can see it below if needed.
*** glibc detected *** ./test01: double free or corruption (top): 0x000000000150dda0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f3d2451eb96]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XFree+0x9)[0x7f3d248a06a9]
./test01[0x400e6b]
./test01[0x400ffe]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f3d244c176d]
./test01[0x4006f9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:06 2224180                            /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
00601000-00602000 r--p 00001000 08:06 2224180                            /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
00602000-00603000 rw-p 00002000 08:06 2224180                            /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
014d6000-01519000 rw-p 00000000 00:00 0                                  [heap]
7f3d23a5f000-7f3d23a74000 r-xp 00000000 08:05 135186                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23a74000-7f3d23c73000 ---p 00015000 08:05 135186                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c73000-7f3d23c74000 r--p 00014000 08:05 135186                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c74000-7f3d23c75000 rw-p 00015000 08:05 135186                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c75000-7f3d23c7a000 r-xp 00000000 08:05 661801                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23c7a000-7f3d23e79000 ---p 00005000 08:05 661801                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e79000-7f3d23e7a000 r--p 00004000 08:05 661801                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e7a000-7f3d23e7b000 rw-p 00005000 08:05 661801                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e7b000-7f3d23e7d000 r-xp 00000000 08:05 661790                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d23e7d000-7f3d2407c000 ---p 00002000 08:05 661790                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407c000-7f3d2407d000 r--p 00001000 08:05 661790                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407d000-7f3d2407e000 rw-p 00002000 08:05 661790                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407e000-7f3d24080000 r-xp 00000000 08:05 135178                     /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24080000-7f3d24280000 ---p 00002000 08:05 135178                     /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24280000-7f3d24281000 r--p 00002000 08:05 135178                     /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24281000-7f3d24282000 rw-p 00003000 08:05 135178                     /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24282000-7f3d2429f000 r-xp 00000000 08:05 662409                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2429f000-7f3d2449e000 ---p 0001d000 08:05 662409                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2449e000-7f3d2449f000 r--p 0001c000 08:05 662409                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2449f000-7f3d244a0000 rw-p 0001d000 08:05 662409                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d244a0000-7f3d24655000 r-xp 00000000 08:05 135165                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24655000-7f3d24855000 ---p 001b5000 08:05 135165                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24855000-7f3d24859000 r--p 001b5000 08:05 135165                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24859000-7f3d2485b000 rw-p 001b9000 08:05 135165                     /lib/x86_64-linux-gnu/libc-2.15.so
7f3d2485b000-7f3d24860000 rw-p 00000000 00:00 0 
7f3d24860000-7f3d24990000 r-xp 00000000 08:05 661788                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24990000-7f3d24b90000 ---p 00130000 08:05 661788                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b90000-7f3d24b91000 r--p 00130000 08:05 661788                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b91000-7f3d24b95000 rw-p 00131000 08:05 661788                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b95000-7f3d24bb7000 r-xp 00000000 08:05 135145                     /lib/x86_64-linux-gnu/ld-2.15.so
7f3d24d05000-7f3d24d4c000 rw-p 00000000 00:00 0 
7f3d24d93000-7f3d24d98000 rw-p 00000000 00:00 0 
7f3d24db3000-7f3d24db7000 rw-p 00000000 00:00 0 
7f3d24db7000-7f3d24db8000 r--p 00022000 08:05 135145                     /lib/x86_64-linux-gnu/ld-2.15.so
7f3d24db8000-7f3d24dba000 rw-p 00023000 08:05 135145                     /lib/x86_64-linux-gnu/ld-2.15.so
7fff24a57000-7fff24a78000 rw-p 00000000 00:00 0                          [stack]
7fff24bd5000-7fff24bd7000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Most likely, the error is somewhere in the algorithm.
PS Called through
printf("%s\n", findColor(1, 1, 300, 300, 255, 255, 255));

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question