X11中“Invalidate Rect”/“WM_PAINT”的等效

我将一些代码从Windows移植到XLib。 在Windows代码中,我可以通过调用InvalidateRect强制重绘,然后处理相应的WM_PAINT消息。 但是,我很难find如何在X11 / XLib中做到这一点。 我看到有一个Expose消息,但不知道这是否是一回事。

如果重要的话,我需要这样做来强制窗口以一定的帧速率渲染一个基于OpenGL的程序。

Solutions Collecting From Web of "X11中“Invalidate Rect”/“WM_PAINT”的等效"

您需要处理Expose事件。 本教程通过一个示例说明如何处理Expose事件:

 #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xos.h> #include <X11/Xatom.h> #include <X11/keysym.h> /*Linux users will need to add -ldl to the Makefile to compile *this example. */ Display *dis; Window win; XEvent report; GC green_gc; XColor green_col; Colormap colormap; /* Try changing the green[] = below to a different color. The color can also be from /usr/X11R6/lib/X11/rgb.txt, such as RoyalBlue4. A # (number sign) is only needed when using hexadecimal colors. */ char green[] = "#00FF00"; int main() { dis = XOpenDisplay(NULL); win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0, BlackPixel (dis, 0), BlackPixel(dis, 0)); XMapWindow(dis, win); colormap = DefaultColormap(dis, 0); green_gc = XCreateGC(dis, win, 0, 0); XParseColor(dis, colormap, green, &green_col); XAllocColor(dis, colormap, &green_col); XSetForeground(dis, green_gc, green_col.pixel); XSelectInput(dis, win, ExposureMask | KeyPressMask | ButtonPressMask); XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497); XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398); XFlush(dis); while (1) { XNextEvent(dis, &report); switch (report.type) { case Expose: fprintf(stdout, "I have been exposed.\n"); XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497); XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398); XFlush(dis); break; case KeyPress: /*Close the program if q is pressed.*/ if (XLookupKeysym(&report.xkey, 0) == XK_q) { exit(0); } break; } } return 0; } 

我可能误解了这个问题。 如果您想在应用程序中创建Expose事件,则可以创建并设置公开事件 ,并使用XSendEvent发送它。

要稍微扩大BЈЈвћ给出的有用答案,

使用原始Xlib,您可以随时在单个线程中绘制,因为每个Xlib函数都会指定完整的显示,窗口和上下文。 AFAIK,多线程的所有投注都关闭。

您还必须拥有Expose事件处理程序,并选择这些事件(如果您处于桌面环境中)。 即使你正在编写一个全屏的程序,也不会有伤害。

大多数工具包不够灵活,只能在指定的事件处理程序中绘制(但在许多其他方面使用得更好),并具有一些与Windows InvalidateRect等效的功能。 在原始的Xlib中,你可以通过发送一个Expose事件来获得相同的效果。 这样做不会导致任何真正的性能问题,并使代码更容易被其他程序员理解,并且更容易移植,所以你也可以。

还有XClearArea和XClearWindow函数会为您生成Expose事件,但是它们会首先用背景颜色擦除部分/全部,这可能会导致闪烁。

有了OpenGL,它会变得更复杂,因为你也必须使用GLX。 我在http://cs.anu.edu.au/~hugh.fisher/3dteach/上有一个非常简单的OpenGL / Xlib程序,这可能是一个很好的例子。