سؤال

So, I have an XImage and i was able to store it in the filesystem, but the image didn't have cursor in it. On further reserch, I found that XOrg has a fix for this, using extension Xfixes.h

The function XFixesGetCursorImage(display) returns a structure XFixesCursorImage

typedef struct {
    short           x, y;
    unsigned short  width, height;
    unsigned short  xhot, yhot;
    unsigned long   cursor_serial;
    unsigned long   *pixels;
    #if XFIXES_MAJOR >= 2
    Atom            atom;           /* Version >= 2 only */
    const char      *name;          /* Version >= 2 only */
    #endif
} XFixesCursorImage;

I believed that unsigned long *pixel is an array that will contain pixel by pixel information of the entire image(of the cursor and rest of the background will be valued 0).

Then using the steps given in this article, I would merge my original XImage with that of cursor(I hope, i have the right idea).

My Problem :

To effectively do the entire masking thing, the first thing is i need to have all the pixel values in XFixesCursorImage. But i believe that pixel array contain way too less values, because, my screen size is 1366 X 768 so i believe there should be 1366*768 elements in pixel array (each containng a long value of pixel in ARGB), but when i used GDB and tried to find the last element it was 21272(21273 elements in total)

Using GDB

(gdb) print cursor[0]
$22 = {x = 475, y = 381, width = 24, height = 24, xhot = 11, yhot = 11, 
  cursor_serial = 92, pixels = 0x807f39c, atom = 388, name = 0x807fc9c "xterm"}

(gdb) print cursor[0]
$22 = {x = 475, y = 381, width = 24, height = 24, xhot = 11, yhot = 11, 
  cursor_serial = 92, pixels = 0x807f39c, atom = 388, name = 0x807fc9c "xterm"}

(gdb) print cursor->pixels[21273]
Cannot access memory at address 0x8094000

Few More Data

(gdb) print cursor[0]
$5 = {x = 1028, y = 402, width = 1, height = 1, xhot = 1, yhot = 1, 
  cursor_serial = 120, pixels = 0x807e854, atom = 0, name = 0x807e858 ""}

(gdb) print cursor[0]->pixels[21994]
$8 = 0

(gdb) print cursor[0]->pixels[21995]
Cannot access memory at address 0x8094000

Am i missing something? Because no of elements doesn't make sense?

Which brings me to a very important question

How are data structured in both XImage->data and XFixesCursorImage->pixels?

هل كانت مفيدة؟

المحلول 2

pixels contain 32-bit per pixel pixmap, in your case 24x24*4=2304 bytes.

From protocol docs:

The cursor image itself is returned as a single image at 32 bits per pixel with 8 bits of alpha in the most significant 8 bits of the pixel followed by 8 bits each of red, green and finally 8 bits of blue in the least significant 8 bits. The color components are pre-multiplied with the alpha component.

نصائح أخرى

XFixesCursorImage stores ONLY the cursor image, NOT the entire screen. So -as Andrey says- you can only access 24x24 unsigned longs.

You can place the Cursor Image on your XImage by using the fields x,y on the XFixesCursorImage, but remember that the pixel format of the XImage might differ from that of the XFixesCursorImage, which is always 32 bits per pixel ARGB.

Said that, please note that unsigned long can actually be 64 bits if compiling for x86_64, so your conversions should use unsigned long to be portable and not assume it will be 32 bits.

Placing example (with funcs missing but good enough for the explanation):

unsigned char r,g,b,a;
unsigned short row,col,pos;

for(pos = row = 0;row<img->height; row++)
{
    for(col=0;col < img->width;col++,pos++)
    {
        a = (unsigned char)((img->pixels[pos] >> 24) & 0xff);  
        r = (unsigned char)((img->pixels[pos] >> 16) & 0xff);  
        g = (unsigned char)((img->pixels[pos] >>  8) & 0xff);
        b = (unsigned char)((img->pixels[pos] >>  0) & 0xff);

        put_pixel_in_ximage(img->x+col,img->y+row, convert_to_ximage_pixel(r,g,b,a));
    }
}

Notes: img in the code is the XFixesCursorImage, and do not trust the field 'cursor_serial' in order to determine if cursors are different of each other, because sometimes this field is just 0. Not sure why.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top