Redessin des fenêtres GEM suite à un message WM_REDRAW

La gestion des redraws des fenêtres est relativement simple sur GEM et répétitive et peut se découper en actions élémentaires comme suit:

  1. On a obtenu un message du système de type WM_REDRAW, dans le buffer on obtient alors la zone totale à redessinner et le numéro de la fenêtre concernée.

  2. Réservation de l'écran pour éviter que 2 applications n'écrivent à l'écran en même temps (wind_update())

  3. Effacement de la souris (graf_mouse())

  4. Recherche du premier rectangle de redessin pour la fenetre (wind_get())

  5. Intersection de ce rectangle avec la zone à dessiner (rc_intersect())

  6. Clipping sur le rectangle calculé par surreté (vs_clip())

  7. Redessin dans le rectangle calculé par le programmeur

  8. Boucle de recherche des autres rectangles de la fenêtre jusqu'a ce qu'il n'y en ai plus

    1. Recherche d'un autre rectangle de la fenêtre
    2. Intersection de ce rectangle avec la zone à dessiner (rc_intersect())
    3. Clipping sur le rectangle calculé par surreté (vs_clip())
    4. Redessin dans le rectangle calculé par le programmeur
  9. Réapparition de la souris (graf_mouse())

  10. Restitution de l'écran (wind_update())

Comme un exemple vaut mieux qu'un long discours, vous pouvez voir ci dessous un petit exemple en C de gestion de ces redessins.

int area[4], nowhere, x, y, w, h;
while(!wind_update(BEG_UPDATE)); /* Réservation de l'écran
si wind_update renvoi 0 c'est qu'il y a une autre application en train de
faire du resssin, BEG_UPDATE=1 */
graf_mouse(M_OFF,&nowhere); /* suppression de la souris, M_OFF=256 */
if(wind_get(handle,WF_FIRSTXYWH,&x,&y,&w,&h))  /* recherche
du premier rectangle, WF_FIRSTXYWH=11 */
{
  area[0]=x;
  area[1]=y;
  area[2]=w;
  area[3]=h;
  if(rc_intersect(inside,area))&&(w!=0)&&(h!=0))  /*
calcul de l'intersection entre inside le rectangle donné par WM_REDRAW
et area, le résultat est recopié dans area */
  {
    vs_clip(vdihandle,area);  /* clipping pour le VDI si on
l'utilise c'est plus prudent */
    /* mettre ici votre procedure de redessin */
  }
}
while((w!=0)&&(h!=0))
{
  if(wind_get(handle,WF_NEXTXYWH,&x,&y,&w,&h)) /* recherche
du prochain rectangle, WF_NEXTXYWH=12 */
  {
    area[0]=x;
    area[1]=y;
    area[2]=w;
    area[3]=h;
   
if(rc_intersect(inside,area))&&(w!=0)&&(h!=0))  /* calcul
de l'intersection entre inside le rectangle donné par WM_REDRAW et
area, le résultat est recopié dans area */
    {
      vs_clip(vdihandle,area);  /* clipping pour le VDI
si on l'utilise c'est plus prudent */
      /* mettre ici votre procedure de redessin */
    }
  }
}
graf_mouse(M_ON,&nowhere); /* Réapparition de la souris, M_ON=257
*/
wind_update(END_UPDATE); /* Fin de la réservation de l'écran
END_UPDATE=0 */

Olivier Landemarre