/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        T E S T   D ' O P E N - G L   S U R   ' X - W I N D O W '  :                                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xtc/OpenGL$R16$c' :                                                                                            */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, AAAAMMJJhhmmss).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

extern    void      *malloc();

#define   dimX      341
#define   dimY      341
                                        /* ATTENTION, en version 5.3, une valeur strictement inferieure a 342 fait que l'image       */
                                        /* n'apparait pas ; d'ailleurs 'glGetIntegerv(...)' renvoie alors (0,0) comme position       */
                                        /* apres le 'glRasterPos2i(...)'. On notera que 341 est le tiers par defaut de la taille     */
                                        /* des fenetres (soit : fenetre?xFACTEUR = 128x8 = 1024).                                    */
#define   fenetreX  128
#define   fenetreY  128
#define   FACTEUR   8
#define   Xmin      0
#define   Xmax      (dimX-1)
#define   Ymin      0
#define   Ymax      (dimY-1)
#define   Zmin      0
#define   Zmax      (dimY-1)

#define   fNOIR     (((float)0)/((float)255))
#define   fBLANC    (((float)255)/((float)255))
#define   fGRIS     fNOIR
                                        /* Un fond NOIR permet de mettre en evidence des problemes de "fantome" de fenetres qui      */
                                        /* d'arriere-plan (par rapport a la fenetre 'OpenGL') sont ramenes au premier-plan, puis     */
                                        /* de nouveau en arriere-plan. Ce phenomene se voit en ouvrant sur '$LACT12' une fenetre     */
                                        /* a partir de '$LACT27'...                                                                  */

#include  <X11/Xlib.h>
#include  <X11/X.h>
#include  <X11/Xutil.h>

#include <GL/glx.h>
#include <GL/gl.h>

#define   EVENEMENT(x)                                                                                                                  \
                    {                                                                                                                   \
                    evenement.type = LASTEvent;                                                                                         \
                                        /* Ainsi, il n'y a pas encore d'evenement                                                    */ \
                    while (evenement.type != x)                                                                                         \
                         {                                                                                                              \
                         XNextEvent(display,&evenement);                                                                                \
                         printf("\n event=%d\n",evenement.type);                                                                        \
                         }                                                                                                              \
                    }

#define   ROUGE                                                                                                                         \
                    0
#define   VERTE                                                                                                                         \
                    1
#define   BLEUE                                                                                                                         \
                    2
#define   ALPHA                                                                                                                         \
                    3
#define   gIMAGE(x,y,n)                                                                                                                 \
                    (*(((pointeur_sur_l_image) + (4*(((y)*dimX) + (x))+n))))                                                            \
                                        /* Acces a un point de l'image.                                                              */

extern    char      *getenv();
main(argc,argv)
int       argc;
char      *argv[];
     {
     unsigned long  niveau_du_bord;
     unsigned long  largeur_du_bord=0;

     char           *nom_du_display;
     Display        *display;
     int            ecran;
     Window         fenetre_de_base;
     Window         fenetre_a_ouvrir;

     XSetWindowAttributes     attributs;
     XSizeHints               hints;

     XVisualInfo    *visual_courant;
     Colormap       palette;
     XEvent         evenement;
     GLXContext     contexte_GL;

     char           *pointeur_sur_l_image=malloc(dimX*dimY*sizeof(int));
     int            X,Y;
                                        /* Image et ses coordonnees.                                                                 */
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        O U V E R T U R E   D U   D I S P L A Y  :                                                                                 */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     nom_du_display = getenv("DISPLAY");
     display = XOpenDisplay(nom_du_display);
     ecran = DefaultScreen(display);
     if   (display == 0)
          {
          printf("\n erreur d'open");
          exit(-1);
          }
     else
          {
          }
     fenetre_de_base= RootWindow(display,ecran);
     niveau_du_bord = WhitePixel(display,ecran);

          {
          int       listes_des_attributs[]={GLX_RGBA,GLX_RED_SIZE,8,GLX_GREEN_SIZE,8,GLX_BLUE_SIZE,8,None};
          visual_courant = glXChooseVisual(display,ecran,listes_des_attributs);
          }
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D E S   C O U L E U R S  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     palette = XCreateColormap(display,fenetre_de_base,visual_courant->visual,AllocNone);
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        O U V E R T U R E   D E   L A   F E N E T R E  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     hints.x = 128;
     hints.y = 0;
     hints.width = FACTEUR*fenetreX;
     hints.height= FACTEUR*fenetreY;
     hints.flags = USPosition | USSize;
     attributs.save_under = True;
     attributs.backing_store = Always;
     attributs.border_pixel = 0;
     attributs.colormap = palette;
     attributs.event_mask = PropertyChangeMask | ButtonPressMask | StructureNotifyMask;
     fenetre_a_ouvrir = XCreateWindow(display
                                     ,fenetre_de_base
                                     ,hints.x,hints.y
                                     ,hints.width,hints.height
                                     ,largeur_du_bord
                                     ,visual_courant->depth,InputOutput
                                     ,visual_courant->visual
                                     ,CWBackingStore | CWSaveUnder | CWBorderPixel | CWEventMask | CWColormap
                                     ,&attributs
                                      );
     XSelectInput(display,fenetre_a_ouvrir,attributs.event_mask);
     XSetStandardProperties(display,fenetre_a_ouvrir,"NOM-FENETRE","NOM-ICONE",None,argv,argc,&hints);
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        A F F I C H A G E   D E   L A   F E N E T R E  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     XMapWindow(display,fenetre_a_ouvrir);
     EVENEMENT(MapNotify);
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C R E A T I O N   D U   C O N T E X T E   ' G L '   E T   C O N N E X I O N   A   L A   F E N E T R E  :                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     contexte_GL = glXCreateContext(display,visual_courant,NULL,GL_FALSE);
     glXMakeCurrent(display,fenetre_a_ouvrir,contexte_GL);
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E   L ' I M A G E  :                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     for       (Y=Ymin ; Y<=Ymax ; Y++)
               {
               for       (X=Xmin ; X<=Xmax ; X++)
                         {
                         gIMAGE(X,Y,ROUGE)=X;
                         gIMAGE(X,Y,VERTE)=Y;
                         gIMAGE(X,Y,BLEUE)=X+Y;
                         gIMAGE(X,Y,ALPHA)=0;
                         }
               }

/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        E N V O I   D E   L ' I M A G E  :                                                                                         */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
          {
          int       coord[4];

          glClearColor(fGRIS,fGRIS,fGRIS,fBLANC);
          glClear(GL_COLOR_BUFFER_BIT);
          glFlush();

          glViewport(Xmin,Ymin,Xmax,Ymax);
          glMatrixMode(GL_PROJECTION);
          glLoadIdentity();
          glOrtho((double)Xmin,(double)Xmax,(double)Ymin,(double)Ymax,(double)Zmin,(double)Zmax);
                                        /* On pourra essayer ici de mettre en plus :                                                 */
                                        /*                                                                                           */
                                        /*                  gluOrtho2D((double)Xmin,(double)Xmax,(double)Ymin,(double)Ymax);         */
                                        /*                                                                                           */
                                        /* on ne sait jamais, mais cela ne resoud pas le probleme des images inferieures au tiers    */
                                        /* de la fenetre...                                                                          */
          glMatrixMode(GL_MODELVIEW);
          glLoadIdentity();

          glGetIntegerv(GL_CURRENT_RASTER_POSITION,coord);
          printf("\n position avant=(%d,%d,%d,%d)",coord[0],coord[1],coord[2],coord[3]);
          printf("\n coin demande  =(%d,%d)",(hints.width/2)-(dimX/2),(hints.height/2)-(dimY/2));
          glRasterPos2i((GLint)(hints.width/2)-(dimX/2),(GLint)(hints.height/2)-(dimY/2));
          glGetIntegerv(GL_CURRENT_RASTER_POSITION,coord);
          printf("\n position apres=(%d,%d,%d,%d)",coord[0],coord[1],coord[2],coord[3]);
          }

     glDrawPixels(dimX,dimY,GL_RGBA,GL_UNSIGNED_BYTE,pointeur_sur_l_image);
     glFlush();

/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        O N   A T T E N D  :                                                                                                       */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     evenement.type = LASTEvent;
     while     (evenement.type != ButtonPress)
               {
               XNextEvent(display,&evenement);
               }
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F E R M E T U R E   D E   L A   F E N E T R E  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
     glXMakeCurrent(display,None,NULL);
     glXDestroyContext(display,contexte_GL);

     XFreeColormap(display,palette);
     XUnmapWindow(display,fenetre_a_ouvrir);
     XDestroyWindow(display,fenetre_a_ouvrir);
     XSync(display,True);
     XCloseDisplay(display);
     }



Copyright © Jean-François Colonna, 2021-2023.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2021-2023.