我正在使用C++中的cairo和xlib进行编程,我的代码如下所示。
我遇到了一些闪烁问题,但通过修改代码,它现在通常可以正常工作。
但是当窗口调整为较小的尺寸(大约在我的笔记本电脑上为600x450)时,它仍然会闪烁。
我该如何解决?
#include <cairo.h>
#include <cairo-xlib.h>
#include <string>
#include <cstdio>
using namespace std;
int main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
cr = cairo_create (surface);
/* Examples are in 1.0 x
* 1.0 coordinate space */
cairo_scale (cr, 800, 600);
cairo_set_source_rgb (cr, 1.0, 0, 0);
cairo_rectangle (cr, 0, 0, 1.0, 1.0);
cairo_fill(cr);
cairo_destroy(cr);
Display *display = XOpenDisplay(NULL);
int default_scr = DefaultScreen(display);
Visual *visual = DefaultVisual(display, default_scr);
Window root_win = RootWindow(display, default_scr);
Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
BlackPixel(display, default_scr), WhitePixel(display, default_scr));
cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, 800, 600);
XSelectInput(display, drawable, ExposureMask | StructureNotifyMask);
XMapWindow(display, drawable);
XFlush(display);
XSync(display, default_scr);
Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, drawable, &wmDeleteMessage, 1);
int height;
int width;
XEvent event;
bool running = true;
while (running)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
cairo_t *x11_cr = cairo_create(x11_sf);
cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
cairo_set_source_surface(x11_cr, surface, 0, 0);
cairo_paint(x11_cr);
cairo_destroy (x11_cr);
}
break;
case ClientMessage:
if (event.xclient.data.l[0] == wmDeleteMessage)
{
running = false;
}
break;
case ConfigureNotify:
width = event.xconfigure.width;
height = event.xconfigure.height;
cairo_xlib_surface_set_size(x11_sf, width, height);
break;
}
}
cairo_surface_destroy (surface);
return 0;
}
我使用cairo_xlib_surface
来绘制一个窗口,它的背景颜色是红色的。我尝试捕获XExpose
事件并重新绘制它。但有时候重新绘制的结果会变得奇怪。
#include <cairo.h>
#include <cairo-xlib.h>
#include <string>
#include <cstdio>
using namespace std;
int main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
cr = cairo_create (surface);
/* Examples are in 1.0 x 1.0 coordinate space */
cairo_scale (cr, 800, 600);
/* Drawing code goes here */
cairo_set_source_rgb (cr, 1.0, 0, 0);
cairo_rectangle (cr, 0, 0, 1.0, 1.0);
cairo_fill(cr);
Display *display = XOpenDisplay(NULL);
int default_scr = DefaultScreen(display);
Visual *visual = DefaultVisual(display, default_scr);
Window root_win = RootWindow(display, default_scr);
Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
BlackPixel(display, default_scr), WhitePixel(display, default_scr));
XSelectInput(display, drawable, ExposureMask);
XMapWindow(display, drawable);
XFlush(display);
XSync(display, default_scr);
int height;
int width;
XEvent event;
while (1)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
width = event.xexpose.width;
height = event.xexpose.height;
cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, width, height);
cairo_t *x11_cr = cairo_create(x11_sf);
cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
cairo_set_source_surface(x11_cr, surface, 0, 0);
cairo_paint(x11_cr);
cairo_destroy (x11_cr);
cairo_surface_destroy (x11_sf);
}
break;
}
}
/* Write output and clean up */
cairo_destroy (cr);
cairo_surface_destroy (surface);
return 0;
}
当我调整窗口大小时,有时会出现以下结果:
![The result window](https://istack.dev59.com/cv1N5.webp)
\pkg-config --cflags --libs x11 cairo\
src.cpp。谢谢!