Correction de text2.c

/* affichage d'un texte long */

#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>

GC      gc; 
Display *display; 
int     screen; 
Window  win, root, wbidon; 
unsigned long white_pixel, black_pixel; 
Font police1, police2;
int larg_win, haut_win, bidon;
char *texte = "Ceci est un assez long texte. Assez long pour ne pas figurer \
sur une ligne, voire ne pas rentre totalement dans la petite fenetre. Fin";
void affiche();
 
main() { 
  display = XOpenDisplay ("");
  gc = DefaultGC (display, screen); 
  screen = DefaultScreen (display); 
  root = RootWindow (display, screen); 
  white_pixel = WhitePixel (display, screen); 
  black_pixel = BlackPixel (display, screen); 
  police1 = XLoadFont (display,
     "-adobe-times-medium-i-normal--10-100-75-75-p-52-iso8859-1");
  XSetFont (display, gc, police1);
  police2 = XLoadFont (display, "8x13");
  larg_win = haut_win = 80 ;
  win = XCreateSimpleWindow (display, root, 0, 0, larg_win, haut_win, 2, 
			     black_pixel, white_pixel); 
  XSelectInput (display, win, ExposureMask | StructureNotifyMask | 
		ButtonPressMask); 
  XStoreName (display, win, "text2"); 
  XMapWindow (display, win); 
      
  for (;;) { 
    XEvent ev;
 
    XNextEvent (display, &ev); 
    switch (ev.type) { 
    case Expose : 
      affiche();
      break; 
    case ButtonPress : 
      if (ev.xbutton.button == Button1)
	XSetFont (display, gc, police1);
      if (ev.xbutton.button == Button3)
	XSetFont (display, gc, police2);
      break; 
    case ConfigureNotify :
      XGetGeometry (display, win, &wbidon, &bidon, &bidon,
		    &larg_win, &haut_win, &bidon, &bidon);
      affiche();
      break; 
    default : 
      break;            
    } 
  } 
} 

void affiche() {
  XCharStruct xcs_bidon;
  int i, y_utilise, base, text_haut, text_bas;
  char * reste;
  XFontStruct *police_attrib;
  XGCValues xgcvaleurs;
  Font fonte;

  y_utilise = 0;
  reste = texte;
  XGetGCValues (display, gc, GCFont, &xgcvaleurs);
  fonte = xgcvaleurs.font;
  police_attrib = XQueryFont (display, fonte) ;
  for (;;) {
    for (i=0; (reste[i] != '\0') &&
	   (XTextWidth(police_attrib, reste, i+1) < larg_win); ++i); 
    if ((reste[i] != '\0') && (i == 0))
      return;
    XTextExtents(police_attrib, reste, i, &bidon,
		 &text_haut, &text_bas, &xcs_bidon);
    base = y_utilise + 2 + text_haut ;
    if ( base + text_bas > haut_win)
	return;
    XDrawString (display, win, gc, 2, base, reste, i);  
    y_utilise = base + text_bas ;
    reste = reste + i;
  }
}

Remarque : il est moins couteux de disposer de 2 gc que de changer en permanence les attributs d'un seul.

chapître de l'exercice index général fonctions de la XLib événements types dans XLib