Итак, у меня есть XImage, и я смог сохранить его в файловой системе, но на нем не было курсора. В дальнейшем, я обнаружил, что XOrg имеет исправление для этого, используя расширение Xfixes.h
Функция XFixesGetCursorImage (display) возвращает структуру 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;
Я полагал, что unsigned long * pixel - это массив, который будет содержать пиксельную информацию по всему изображению (курсора и остальной части фона будет оценен 0).
Затем, используя шаги, приведенные в этой статье, я бы объединил свой оригинальный XImage с курсором (надеюсь, у меня есть правильная идея).
Моя проблема :
Чтобы эффективно делать всю маскирующую вещь, первое, что мне нужно, чтобы все значения пикселей были в XFixesCursorImage. Но я считаю, что в массиве пикселей содержится слишком меньше значений, потому что размер экрана составляет 1366 X 768, поэтому я считаю, что в пиксельном массиве должно быть 1366 * 768 элементов (каждый из которых содержит длинное значение пикселя в ARGB), но когда я использовал GDB и попытался найти последний элемент, это было 21272 (всего 21273 элемента)
Использование 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
Немного больше данных
(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
Я что-то упускаю? Потому что нет элементов не имеет смысла?
Это подводит меня к очень важному вопросу
Как данные структурированы как в XImage-> данных, так и в XFixesCursorImage-> пикселях?
pixels
содержат 32-битную пиксельную pixmap, в вашем случае 24x24 * 4 = 2304 байта.
Из протоколов:
Само изображение курсора возвращается как одно изображение с 32 битами на пиксель с 8 бит альфа в наиболее значительных 8 бит пикселя, за которым следуют 8 бит каждый из красного, зеленого и, наконец, 8 бит синего в наименее значимых 8 битах, Компоненты цвета предварительно умножаются на альфа-компонент.
XFixesCursorImage хранит ТОЛЬКО изображение курсора, а не весь экран. Таким образом, -as Andrey says- вы можете получить доступ к 24х24 беззнаковым длинам.
Вы можете поместить изображение курсора на свой XImage, используя поля x, y в XFixesCursorImage, но помните, что формат пикселя XImage может отличаться от формата XFixesCursorImage, который всегда равен 32 бит на пиксель ARGB.
Обратите внимание, что unsigned long может быть 64 бит при компиляции для x86_64, поэтому ваши преобразования должны использовать unsigned long для переносимости и не предполагать, что это будет 32 бита.
Пример размещения (с отсутствием funcs, но достаточно для объяснения):
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));
}
}
Примечания: img в коде XFixesCursorImage и не доверяет полю 'cursor_serial', чтобы определить, отличаются ли курсоры друг от друга, потому что иногда это поле равно 0. Не знаете, почему.
pixels