C - X11 API: 图形不在 While 循环中工作
C - X11 API: Graphics not Working in a While Loop
我正在尝试动态绘制背景。图形正常工作很好......但是:
int width, height;
GC gc_backcolor;
XGCValues gcv_backcolor;
width = c_values.width;
height = c_values.height;
gcv_backcolor.background = c_values.backcolor;
gcv_backcolor.foreground = c_values.backcolor;
gc_backcolor = XCreateGC(display, canvas, GCBackground | GCForeground, &gcv_backcolor);
int x = 0;
int y = 0;
while (y < height) {
x = 0;
while (x < width) {
XDrawPoint(display, canvas, gc_backcolor, x, y);
x++;
}
y++;
}
x = 0;
y = 0;
...出于某种原因,当我 运行 循环时,它不起作用。如果有人能向我解释为什么它会这样,我将不胜感激。
难道是我在 canvas 暴露事件上调用这个函数?
while(1) {
XNextEvent(display, &event);
if (event.xany.window == canvas) {
if (event.type == Expose) {
Canvas_Draw(display, canvas, c_values);
}
}
}
这是我的主要代码:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include "Canvas.h"
#include "Extensions.h"
int main(int argc, char* argv[])
{
Display* display;
int screen;
Window window;
Window canvas;
XEvent event;
GC gc_canvas;
//Canvas* canvas;
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Error trying to open display\n");
exit(1);
}
screen = DefaultScreen(display);
window = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 640, 480, 1, BlackPixel(display, screen), WhitePixel(display, screen));
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
/* Create Canvas */
XGCValues gcv_canvas;
CanvasValues c_values;
gcv_canvas.foreground = 0xff00ff;
gcv_canvas.background = 0xff00ff;
canvas = XCreateSimpleWindow(display, window, 0, 0, 256, 256, 1, BlackPixel(display, screen), WhitePixel(display, screen));
gc_canvas = XCreateGC(display, canvas, GCForeground | GCBackground, &gcv_canvas);
XSelectInput(display, canvas, ExposureMask | KeyPressMask);
XMapWindow(display, canvas);
Canvas_Create_Content_Field(display, canvas, c_values);
c_values.backcolor = 0x00ff00;
//Canvas_Draw(display, canvas, c_values); this code only appears to work in the expose event
/* Create Canvas */
while(1) {
XNextEvent(display, &event);
if (event.xany.window == canvas) {
if (event.type == Expose) {
Canvas_Draw(display, canvas, c_values);
}
}
}
return 0;
}
您没有在外部 y
循环中重置 x
。试试这个
while (y < height) {
x = 0; // <<--- insert here
while (x < width) {
XDrawPoint(display, canvas, gc_backcolor, x, y);
x++;
}
y++;
}
更新
您还将前景和背景设置为相同的颜色
gcv_backcolor.background = c_values.backcolor;
gcv_backcolor.foreground = c_values.backcolor;
并且返回的背景颜色用于绘制
gc_backcolor = XCreateGC(display, canvas, GCBackground | GCForeground, &gcv_backcolor);
...
XDrawPoint(display, canvas, gc_backcolor, x, y);
为了更好的性能,像XDrawPoint
这样的Xlib函数不会立即将命令发送到X服务器,而是将其添加到Xlib请求缓冲区。当以下情况之一发生时,Xlib 会将请求缓冲区的内容发送到 X 服务器:
- 客户端调用
XFlush()
刷新请求缓冲区并将其全部发送到服务器。
- 客户端调用
XSync()
刷新请求缓冲区并将其全部发送到服务器,然后等待服务器响应它已处理所有请求。
- 请求缓冲区填满,Xlib 刷新当前内容以为新请求腾出空间。
- 客户端调用需要服务器响应的函数 - Xlib 刷新所有请求以便能够发送需要响应的请求。
- 客户端调用事件处理函数,例如
XPending()
, XNextEvent()
, or XWindowEvent()
,客户端发现队列中没有事件需要处理,因此刷新缓冲区,让服务器做一些可能会产生事件的事情。
在您的情况下,您不希望将单独数据包中的每个像素发送到 X 服务器的开销,因此您可能希望在 while (y < height) { ... }
之后放置一个 XFlush()
调用然后循环一次发送所有像素。
对不起...它与图形无关,但宽度和高度整数被设置为 0 由于我创建并在创建数据数组的函数中使用的函数中的错误图片:
int width, height;
width = Window_Get_Width(display, canvas); // Window_Get_Width had some errors and
height = Window_Get_Height(display, canvas); // Window_Get_Height had the exact same errors
c_values->width = width;
c_values->height = height;
int field[width*height];
c_values->field = field;
我修复了错误,现在一切正常! :D
我正在尝试动态绘制背景。图形正常工作很好......但是:
int width, height;
GC gc_backcolor;
XGCValues gcv_backcolor;
width = c_values.width;
height = c_values.height;
gcv_backcolor.background = c_values.backcolor;
gcv_backcolor.foreground = c_values.backcolor;
gc_backcolor = XCreateGC(display, canvas, GCBackground | GCForeground, &gcv_backcolor);
int x = 0;
int y = 0;
while (y < height) {
x = 0;
while (x < width) {
XDrawPoint(display, canvas, gc_backcolor, x, y);
x++;
}
y++;
}
x = 0;
y = 0;
...出于某种原因,当我 运行 循环时,它不起作用。如果有人能向我解释为什么它会这样,我将不胜感激。
难道是我在 canvas 暴露事件上调用这个函数?
while(1) {
XNextEvent(display, &event);
if (event.xany.window == canvas) {
if (event.type == Expose) {
Canvas_Draw(display, canvas, c_values);
}
}
}
这是我的主要代码:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include "Canvas.h"
#include "Extensions.h"
int main(int argc, char* argv[])
{
Display* display;
int screen;
Window window;
Window canvas;
XEvent event;
GC gc_canvas;
//Canvas* canvas;
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Error trying to open display\n");
exit(1);
}
screen = DefaultScreen(display);
window = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 640, 480, 1, BlackPixel(display, screen), WhitePixel(display, screen));
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
/* Create Canvas */
XGCValues gcv_canvas;
CanvasValues c_values;
gcv_canvas.foreground = 0xff00ff;
gcv_canvas.background = 0xff00ff;
canvas = XCreateSimpleWindow(display, window, 0, 0, 256, 256, 1, BlackPixel(display, screen), WhitePixel(display, screen));
gc_canvas = XCreateGC(display, canvas, GCForeground | GCBackground, &gcv_canvas);
XSelectInput(display, canvas, ExposureMask | KeyPressMask);
XMapWindow(display, canvas);
Canvas_Create_Content_Field(display, canvas, c_values);
c_values.backcolor = 0x00ff00;
//Canvas_Draw(display, canvas, c_values); this code only appears to work in the expose event
/* Create Canvas */
while(1) {
XNextEvent(display, &event);
if (event.xany.window == canvas) {
if (event.type == Expose) {
Canvas_Draw(display, canvas, c_values);
}
}
}
return 0;
}
您没有在外部 y
循环中重置 x
。试试这个
while (y < height) {
x = 0; // <<--- insert here
while (x < width) {
XDrawPoint(display, canvas, gc_backcolor, x, y);
x++;
}
y++;
}
更新
您还将前景和背景设置为相同的颜色
gcv_backcolor.background = c_values.backcolor;
gcv_backcolor.foreground = c_values.backcolor;
并且返回的背景颜色用于绘制
gc_backcolor = XCreateGC(display, canvas, GCBackground | GCForeground, &gcv_backcolor);
...
XDrawPoint(display, canvas, gc_backcolor, x, y);
为了更好的性能,像XDrawPoint
这样的Xlib函数不会立即将命令发送到X服务器,而是将其添加到Xlib请求缓冲区。当以下情况之一发生时,Xlib 会将请求缓冲区的内容发送到 X 服务器:
- 客户端调用
XFlush()
刷新请求缓冲区并将其全部发送到服务器。 - 客户端调用
XSync()
刷新请求缓冲区并将其全部发送到服务器,然后等待服务器响应它已处理所有请求。 - 请求缓冲区填满,Xlib 刷新当前内容以为新请求腾出空间。
- 客户端调用需要服务器响应的函数 - Xlib 刷新所有请求以便能够发送需要响应的请求。
- 客户端调用事件处理函数,例如
XPending()
,XNextEvent()
, orXWindowEvent()
,客户端发现队列中没有事件需要处理,因此刷新缓冲区,让服务器做一些可能会产生事件的事情。
在您的情况下,您不希望将单独数据包中的每个像素发送到 X 服务器的开销,因此您可能希望在 while (y < height) { ... }
之后放置一个 XFlush()
调用然后循环一次发送所有像素。
对不起...它与图形无关,但宽度和高度整数被设置为 0 由于我创建并在创建数据数组的函数中使用的函数中的错误图片:
int width, height;
width = Window_Get_Width(display, canvas); // Window_Get_Width had some errors and
height = Window_Get_Height(display, canvas); // Window_Get_Height had the exact same errors
c_values->width = width;
c_values->height = height;
int field[width*height];
c_values->field = field;
我修复了错误,现在一切正常! :D