Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 25/06/2013, à 08:15

ubuntuforce

faire une animation en C avec Xlib [résolu]

Salut les Ubuntues,
Je suis débutant en C et j'aimerai arriver a faire une animation avec la bibliothèque Xlib qui est a la base de XWindow je crois.
Bref je suis bloquer car l'appel a la fonction:

XEvent event ;
XNextEvent(display,&event) ;

Est bloquant en attente d'un évènement alors que je voudrai faire une animation donc des images générer par programmation s'affichant les unes après les autres...
J'ai fait un petit programme qui illustre mon problème: c'est un chronomètre qui ne s'incrémente seulement si l'on clique avec la souris sur la fenêtre:

 
#include <stdio.h>
#include <string.h>
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
 
#include <tgmath.h>
 
#define MAXPX 360
 
#ifndef M_PI
  M_PI=3.1415
#endif  
 
struct pixels {
  float x ;
  float y ;
} ;
 
unsigned int pixel_idx=0 ;
 
 
struct pixels get_coords(int position,int scale,float radius,int center_x, int center_y) {
 
  struct pixels res_px ;
  int offset=-90 ;
  float degrees=360/scale*position+offset ;
  float rad=degrees/180.0*M_PI ;
  float xpos=cos(rad) * radius + center_x ;
  float ypos=sin(rad) * radius + center_y ;
  res_px.x=xpos ;
  res_px.y=ypos ;
  return res_px ;
 
}
 
 
int main() {
 
 Display *display ;
 Window root_win, win ;
 GC clock_pointer_gc,clock_circle_gc ;
 XGCValues clock_circle_values, clock_pointer_values ;
 int screen_num,width=450,height=450 ;
 unsigned long background, clock_circle ;
 
 display=XOpenDisplay(NULL) ;           //set root display
 
 root_win=RootWindow(display,0) ;      // set root window
 screen_num=DefaultScreen(display) ;   // get the root screen number
 
 /* start of settings for color getting */ 
 Colormap cmap ;
 XColor xc, xc1 ;
 cmap=DefaultColormap(display,screen_num) ;
 
 XAllocNamedColor(display,cmap,"Red",&xc,&xc1) ; // getting the Red color
 background=xc.pixel ; //color for background
 
 XAllocNamedColor(display,cmap,"White",&xc,&xc1) ; // getting the white color
 clock_circle=xc.pixel ; // color for clock circle
 
 /* settings for the clock pointer */
 clock_pointer_values.foreground=BlackPixel(display,screen_num) ;
 clock_pointer_values.line_width=10 ;
 clock_pointer_values.line_style=LineSolid ;
 clock_pointer_values.cap_style=CapRound ;    /* CapNotLast, CapButt,CapRound, CapProjecting */
 
 /* settings for the clock circle */
 clock_circle_values.foreground=clock_circle ;
 clock_circle_values.line_width=1 ;
 clock_circle_values.line_style=LineSolid ;
 clock_circle_values.cap_style=CapRound ;     /* CapNotLast, CapButt,CapRound, CapProjecting */
 clock_circle_values.join_style= JoinRound ;  /* JoinMiter, JoinRound, JoinBevel */
 
 
 win=XCreateSimpleWindow(display,root_win,
			 0,0,              //x,y
			 width,height,    //width height
			 0,0,        // borderwidth && bordercolor
			 background      // background color
			) ; 
 
 
 clock_pointer_gc=XCreateGC(display,win,GCForeground | GCLineWidth | GCLineStyle| GCCapStyle | GCJoinStyle,&clock_circle_values) ;
 clock_circle_gc=XCreateGC(display,win,GCForeground| GCLineWidth | GCLineStyle| GCCapStyle ,&clock_pointer_values) ;
 XSelectInput(display,win,ButtonPressMask  | KeyPressMask | ExposureMask | StructureNotifyMask ) ;
 
 XMapWindow(display,win) ; // start the display
 
 struct pixels tmp_px1 ;
 struct pixels tmp_px2 ;
 float center_x=450/2 ;
 float center_y=450/2 ;
 XPoint clock_circle_px[360] ;
 int clock_pointer_pos=0 ;
 for (;;) {
 
 
   XEvent event ;
   XNextEvent(display,&event) ;
   switch(event.type) {
     case Expose :
       ;
     case ConfigureNotify :
       if (event.xconfigure.width != 450 || event.xconfigure.height != 450) {
	 width=event.xconfigure.width   ;
	 height=event.xconfigure.height ;
	 XClearWindow(display,event.xany.window) ;
	 printf("size changed to width: %i ancd height: %i\n",width,height) ;
       }
       break ;
 
     case ButtonPress :  
 
 
         XClearWindow(display,event.xany.window) ;  
 
         int c ;
	 for ( c=0 ; c < 360 ; c++) {
	   tmp_px1=get_coords(c,360,200,450/2,450/2) ;
	   clock_circle_px[c].x=tmp_px1.x ;
	   clock_circle_px[c].y=tmp_px1.y ;
	 }
 
	 XFillPolygon(display, win, clock_pointer_gc, clock_circle_px, 360, 0, 0) ;
 
	 tmp_px2=get_coords(clock_pointer_pos,60,150,450/2,450/2) ;
 
 
	 clock_pointer_pos++ ;
	 XDrawLine(display, win, clock_circle_gc,center_x,center_y,tmp_px2.x,tmp_px2.y) ;
 
 
	 break ;
     case KeyPress : 
         printf("keycode %i == %c\n",(int) event.xkey.keycode,event.xkey.keycode) ;
         XCloseDisplay(display) ;
         return 0 ;
 
       }
  }
}

A compiler avec :

gcc -Wall -Wextra nom_fichier.c -lX11 -lm 

Et ne pas gerer les évènements et mettre le code dans la boucle principale avec un appel a sleep() donne un résultat chaotique de flash d'aiguille de chronomètre...

En espérant que je suis à la bonne adresse chez les programmeurs Ubuntues (Linux) ou je puisse trouver réponse a ma question.
Merci pour vos réponses éclairées.

Dernière modification par ubuntuforce (Le 27/06/2013, à 05:23)


Rendez-vous sur mon site présentant mes créations open-source: http://www.open-source-projects.net/
Rendez-vous sur mon site dédier a mes créations d'imagerie 3D: http://www.3dreaming-imaging.net/
Testez pendant une semaine l'éditeur avec terminaux intégrées http://www.open-source-projects.net/it-edit/it-edit Vous l'adopterai sûrement !

Hors ligne

#2 Le 25/06/2013, à 11:46

pingouinux

Re : faire une animation en C avec Xlib [résolu]

Bonjour,
J'ai fait quelques tests, et je pense avoir obtenu ce que tu voulais, en remplaçant ta boucle for(;;) par

 for (;;) {

         for ( c=0 ; c < 360 ; c++) {
           tmp_px1=get_coords(c,360,200,450/2,450/2) ;
           clock_circle_px[c].x=tmp_px1.x ;
           clock_circle_px[c].y=tmp_px1.y ;
         }

         XFillPolygon(display, win, clock_pointer_gc, clock_circle_px, 360, 0, 0) ;

         tmp_px2=get_coords(clock_pointer_pos,60,150,450/2,450/2) ;


         clock_pointer_pos++ ;
         XDrawLine(display, win, clock_circle_gc,center_x,center_y,tmp_px2.x,tmp_px2.y) ;
         XFlush(display) ;
         sleep(1);

  }

Hors ligne

#3 Le 25/06/2013, à 17:24

ubuntuforce

Re : faire une animation en C avec Xlib [résolu]

Merci beaucoup pour la réponse,
avec un appel a XFlush(display) il n'y a pas besoin de passer un XEvent en argument pour effacer le display apparement. 

Il y a une petite erreur dans mon code:
la valeur de la variable clock_pointer_pos n'est pas contrôler afin qu'elle ne dépasse pas 360 et s'incrémente toujours ce qui fait qu'au bout d'un bon moment on devrait dépasser les 4 bytes du int mais avant le valeur fonctionne quand même dans la fonction de calcule de coordonnées.

PS: Puisque c'est le sujet je ne trouve pas de bon tutoriels sur Xlib pourtant ça ne doit pas manquer sur le sujet (je tombe toujours sur les mêmes ou des pdf chunks) , si vous connaissez l'adresse d'un bon tutoriel ce serai sympa de poster.

Dernière modification par ubuntuforce (Le 25/06/2013, à 17:27)


Rendez-vous sur mon site présentant mes créations open-source: http://www.open-source-projects.net/
Rendez-vous sur mon site dédier a mes créations d'imagerie 3D: http://www.3dreaming-imaging.net/
Testez pendant une semaine l'éditeur avec terminaux intégrées http://www.open-source-projects.net/it-edit/it-edit Vous l'adopterai sûrement !

Hors ligne

#4 Le 25/06/2013, à 18:25

grim7reaper

Re : faire une animation en C avec Xlib [résolu]

Salut,

Certaines des meilleures ressources que je connais sont sur ce site.
Sinon, en français il y a ça.

Et non, ça ne court pas les rue car la majorité des gens codes en Qt, GTK, WxWidget… mais pas en Xlib de base.
Les vieux de la vieilles peuvent rester sur du XtIntrinsics ou du Motif (qui sont des petites bibliothèques de widget basé sur Xlib).
Mais du Xlib pur et dur, c’est assez rare (bas niveau, pas portable, …)

Donc non, pas des masses de tuto’. De la doc’ oui, des tutos bof.

Dernière modification par grim7reaper (Le 25/06/2013, à 18:29)

Hors ligne

#5 Le 27/06/2013, à 05:23

ubuntuforce

Re : faire une animation en C avec Xlib [résolu]

Merci pour les liens,
alors Xlib n'est pas si béton que ca,
Je pensais que XWindows était basé dessus et GTK aussi.
Mais bon tant que j'ai un display pour générer des animations je suis content.
Merci pour vos réponses éclairées.


Rendez-vous sur mon site présentant mes créations open-source: http://www.open-source-projects.net/
Rendez-vous sur mon site dédier a mes créations d'imagerie 3D: http://www.3dreaming-imaging.net/
Testez pendant une semaine l'éditeur avec terminaux intégrées http://www.open-source-projects.net/it-edit/it-edit Vous l'adopterai sûrement !

Hors ligne

#6 Le 27/06/2013, à 07:40

grim7reaper

Re : faire une animation en C avec Xlib [résolu]

ubuntuforce a écrit :

alors Xlib n'est pas si béton que ca

Bah tout dépends de ce que tu entends par béton.
Mais elle est très bas niveau, la couche juste en dessous c’est le protocole X

ubuntuforce a écrit :

Je pensais que XWindows était basé dessus et GTK aussi.

Mais GTK et Qt se base bien dessus (pour les versions Linux bien sûr, et maintenant ils commencent aussi à être basé sur le futur Wayland).
Pour XWindow, il est aussi basé sur la Xlib (enfin, il est plus exact de dire que la Xlib est un composant de XWindow).

Hors ligne

#7 Le 27/06/2013, à 09:54

claudius01

Re : faire une animation en C avec Xlib [résolu]

Bonjour,

grim7reaper a écrit :

Mais GTK et Qt se base bien dessus (pour les versions Linux bien sûr, et maintenant ils commencent aussi à être basé sur le futur Wayland)...

... sauf pour Ubuntu qui s'appuiera sur le serveur d'affichage Mir.


Cordialement, A+
--
Claudius

Hors ligne