Équivalent de “Invalidate Rect” / “WM_PAINT” dans X11

Je porte du code de Windows vers XLib. Dans le code Windows, je peux forcer une nouvelle mise à jour en appelant InvalidateRect , puis en traitant le message WM_PAINT correspondant. Cependant, j’ai du mal à trouver comment faire cela dans X11 / XLib. Je vois qu’il y a un message Expose mais je ne sais pas si c’est la même chose.

Si cela est important, je dois le faire pour forcer la fenêtre à afficher à une certaine fréquence d’images pour un programme basé sur OpenGL.

Vous devez gérer les événements Expose. Ce tutoriel explique par un exemple comment gérer les événements Expose:

 #include  #include  #include  #include  #include  #include  #include  /*Linux users will need to add -ldl to the Makefile to comstack *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; } 

J’ai peut-être mal compris la question. Si vous souhaitez créer des événements Expose dans votre application, vous pouvez créer et définir des événements d’exposition et les envoyer à l’aide de XSendEvent .

Pour développer légèrement les réponses utiles données par BЈовић,

Avec raw Xlib, vous pouvez dessiner à tout moment dans un seul thread, car chaque fonction Xlib spécifie l’affichage complet, la fenêtre et le contexte. AFAIK, avec le multithreading, tous les paris sont désactivés.

Vous devez également disposer d’un gestionnaire d’événements Expose et sélectionner ces événements si vous êtes dans un environnement de bureau. Et il ne sera pas mal d’avoir un même si vous écrivez un programme en plein écran.

La plupart des toolkits ne sont pas aussi flexibles et ne font que dessiner un gestionnaire d’événements désigné (mais beaucoup plus agréable à utiliser de nombreuses autres manières) et en ont un équivalent à Windows InvalidateRect. Dans raw Xlib, vous obtenez le même effet en vous envoyant un événement Expose. Cela ne conduira pas à de véritables problèmes de performances et rendra le code plus compréhensible par les autres programmeurs, et plus facile à transférer.

Il existe également des fonctions XClearArea et XClearWindow qui génèrent des événements d’exposition pour vous, mais ils effacent tout d’abord la partie / tout avec la couleur d’arrière-plan, ce qui peut entraîner un scintillement.

Avec OpenGL, cela devient un peu plus compliqué car vous devez également travailler avec GLX. J’ai un programme OpenGL / Xlib très simple en ligne sur http://cs.anu.edu.au/~hugh.fisher/3dteach/ qui pourrait être utile à titre d’exemple.