Режим рисования 'GXand' Xlib приводит к неправильным цветам
Мне нужно использовать GXand
режимы записи экранов самолетов, как то так
XSetFunction( display, gc, GXand );
(Это необходимо для эмуляции двухлучевого ЭЛТ.) Он работает точно так, как я и ожидал, за исключением некоторых конкретных комбинаций цветных пикселей AND. В моем последнем приложении я вижу странные редкие артефакты. Анализ снимков экрана показывает, что, скажем, пиксели (0x80, 0x61, 0x20) И, помеченные (0x9f, 0x78, 0x28), дают неправильный (0x9f 0x48 0x28) красноватый пиксель, тогда как 0x79 байт должен быть вместо 0x48.
Наконец, я пишу простой код (ниже) для его глубокого тестирования, и он показывает довольно странные результаты, такие как GXand
Реализация в xlib глючит, или я неправильно использую инструмент.
Я использую Slackware64-current.
Я гарантирую, что правильно работающая функция И даст мне идеальное смешение для всех моих цветов в графическом редакторе.
Где я не прав?
Благодарю.
/* based on various Xlib drawing examples */
// to compile: rm ./test ; gcc -o test xlibtest.c -lX11 ; ./test
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Window
create_simple_window(Display* display, int width, int height, int x, int y)
{
int screen_num = DefaultScreen(display);
int win_border_width = 2;
Window win;
win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
x, y, width, height, win_border_width,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
XMapWindow(display, win);
XFlush(display);
usleep(100000); // NOTE: do not remove! will disappear next elements!
return win;
}
GC
create_gc(Display* display, Window win, int reverse_video)
{
GC gc;
unsigned long valuemask = 0;
XGCValues values;
unsigned int line_width = 1;
int line_style = LineSolid;
int cap_style = CapButt;
int join_style = JoinBevel;
int screen_num = DefaultScreen(display);
gc = XCreateGC(display, win, valuemask, &values);
if (gc < 0) {
fprintf(stderr, "XCreateGC: \n");
}
if (reverse_video) {
XSetForeground(display, gc, WhitePixel(display, screen_num));
XSetBackground(display, gc, BlackPixel(display, screen_num));
}
else {
XSetForeground(display, gc, BlackPixel(display, screen_num));
XSetBackground(display, gc, WhitePixel(display, screen_num));
}
XSetLineAttributes(display, gc,
line_width, line_style, cap_style, join_style);
XSetFillStyle(display, gc, FillSolid);
return gc;
}
int main(int argc, char* argv[])
{
int i;
Display* display;
int screen_num;
Window win;
unsigned int display_width,
display_height;
unsigned int width, height;
char *display_name = getenv("DISPLAY");
GC gcx[256], gcy[256];
XColor xc;
Colormap cm;
display = XOpenDisplay(display_name);
if (display == NULL) {
fprintf(stderr, "%s: cannot connect to X server '%s'\n",
argv[0], display_name);
exit(1);
}
width = (356);
height = (356);
win = create_simple_window(display, width, height, 0, 0);
// gc = create_gc(display, win, 1);
cm = DefaultColormap(display, DefaultScreen(display));
XSync(display, False);
for (i=-128; i<127; i++) {
gcx[i+128] = create_gc(display, win, 0);
XSetFunction( display, gcx[i+128], GXand ); // NOTE 'AND' function!
xc.red = (0x80+(i/4)) * 255;
xc.green = (0x61+(i/4)) * 255;
xc.blue = (0x20+(i/4)) * 255;
XAllocColor(display, cm, &xc);
XSetForeground(display, gcx[i+128], xc.pixel);
XDrawLine(display, win, gcx[i+128], i+50+128, 0, i+50+128, 256+50+50);
}
sleep(2);
for (i=-128; i<127; i++) {
gcy[i+128] = create_gc(display, win, 0);
XSetFunction( display, gcy[i+128], GXand ); // NOTE 'AND' function!
xc.red = (0x9f+(i/4)) * 255;
xc.green = (0x78+(i/4)) * 255;
xc.blue = (0x28+(i/4)) * 255;
XAllocColor(display, cm, &xc);
XSetForeground(display, gcy[i+128], xc.pixel);
XDrawLine(display, win, gcy[i+128], 0, i+50+128, 256+50+50, i+50+128);
}
XFlush(display);
sleep(10);
XCloseDisplay(display);
return(0);
}