URL: https://linuxfr.org/forums/programmation-c--2/posts/lecture-sur-un-p%C3%A9riph%C3%A9rique Title: Lecture sur un périphérique Authors: xavier thomas Date: 2006年05月22日T12:28:33+02:00 Tags: Score: 0 Bonjours, Je travaille actuellement sur un programme qui lit les valeurs des axes d'un joystick. Mon problème est que ce programme ne lit ces valeurs que occasionnellement, et comme le device est géré de manière comparable a un FIFO, je me retrouve avec une valeur de l'axe qui n'est plus du tout d'actualité. J'aimerais pouvoir obtenir la valeur correspondant au dernier event du joystick. J'ai envisager plusieurs possibilités: - "lseek(device_fd,-sizeof(struct js_event),SEEK_END)" mais ça n'a aucun résultat - Emission d'un signal lors d'une réception dans le fichier (device) et connexion de ce signal a une fonction qui met à jour la valeur de mon axe, mais je ne trouve aucun moyen d'émettre un signal lors d'une réception dans le fichier. - Un fonctionnement similaire en créant un thread qui contiendrait une boucle infinie contenant un "select" (sans timeout) sur le descripteur de fichier et qui mettrait à jour la valeur de l'axe. Mais je n'ai jamais joué avec les threads et je ne sais pas si je peux modifier une variable globale (int) sans vérifier qu'il ne soit pas utilisé dans un autre thread! #define IMAGES_PATH "/mnt/ramdisk/img" #define DEVICE_FILE "/dev/input/js0" gint imagecpt=0; GtkWidget *image=NULL; GList *namelist=NULL; gint windowwidth=800; gint windowheight=600; struct itimerval timer; int device_fd=0; int axe=0; //****************************************************************************** // Fonction appelée a chaque fin de timer //****************************************************************************** //gboolean update_image(gpointer data){ void update_image(int signal){ £spaces£ £/spaces£GError *error=NULL; £spaces£ £/spaces£GdkPixbuf *pixbuf=NULL; £spaces£ £/spaces£GdkPixbuf *scaledpixbuf=NULL; £spaces£ £/spaces£gchar *filename=NULL; £spaces£ £/spaces£struct js_event js; £spaces£ £/spaces£//lseek(device_fd,-sizeof(struct js_event),SEEK_END); £spaces£ £/spaces£read(device_fd, &js, sizeof(struct js_event)); £spaces£ £/spaces£if((js.type & ~JS_EVENT_INIT)==JS_EVENT_AXIS && js.number==2){ £spaces£ £/spaces£axe=js.value; £spaces£ £/spaces£} £spaces£ £/spaces£ £spaces£ £/spaces£if(axe>10){ £spaces£ £/spaces£timer.it_value.tv_sec = 0; £spaces£ £/spaces£timer.it_value.tv_usec = 40000*32767/axe; £spaces£ £/spaces£timer.it_interval.tv_sec = 0; £spaces£ £/spaces£timer.it_interval.tv_usec = 0; £spaces£ £/spaces£setitimer (ITIMER_REAL, &timer, NULL); £spaces£ £/spaces£ £spaces£ £/spaces£filename = g_list_nth_data(namelist, imagecpt); £spaces£ £/spaces£if(filename == NULL){ £spaces£ £/spaces£gtk_main_quit(); £spaces£ £/spaces£return; £spaces£ £/spaces£} £spaces£ £/spaces£pixbuf = gdk_pixbuf_new_from_file(filename, &error); £spaces£ £/spaces£if(pixbuf==NULL){ £spaces£ £/spaces£printf("Error: %s: %s\n",filename,error->message); £spaces£ £/spaces£exit(69); £spaces£ £/spaces£} £spaces£ £/spaces£scaledpixbuf=gdk_pixbuf_scale_simple(pixbuf, windowwidth, windowheight, GDK_INTERP_NEAREST); £spaces£ £/spaces£gtk_image_clear(GTK_IMAGE(image)); £spaces£ £/spaces£gtk_image_set_from_pixbuf(GTK_IMAGE(image), scaledpixbuf); £spaces£ £/spaces£g_object_unref(pixbuf); £spaces£ £/spaces£g_object_unref(scaledpixbuf); £spaces£ £/spaces£ £spaces£ £/spaces£imagecpt = imagecpt+1; £spaces£ £/spaces£ £spaces£ £/spaces£return; £spaces£ £/spaces£} £spaces£ £/spaces£ £spaces£ £/spaces£timer.it_value.tv_sec = 0; £spaces£ £/spaces£timer.it_value.tv_usec = 40000; £spaces£ £/spaces£timer.it_interval.tv_sec = 0; £spaces£ £/spaces£timer.it_interval.tv_usec = 0; £spaces£ £/spaces£setitimer (ITIMER_REAL, &timer, NULL); £spaces£ £/spaces£ } //****************************************************************************** // Actualisation de la taille de l'image à la taille de la fenetre //****************************************************************************** gboolean size_updated(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data){ £spaces£ £/spaces£windowwidth = event->width; £spaces£ £/spaces£windowheight = event->height; £spaces£ £/spaces£printf("%d , %d\n",windowwidth, windowheight); £spaces£ £/spaces£return FALSE; } //****************************************************************************** // Main //****************************************************************************** int main(int argc,char **argv){ £spaces£ £/spaces£GtkWidget *mainwindow=NULL; £spaces£ £/spaces£GDir *dir=NULL; £spaces£ £/spaces£gchar *filename=NULL; £spaces£ £/spaces£gchar *name=NULL; £spaces£ £/spaces£ £spaces£ £/spaces£ £spaces£ £/spaces£//Ouverture du device et mode nonblocant £spaces£ £/spaces£if((device_fd = open(DEVICE_FILE, O_RDONLY)) < 0) { £spaces£ £/spaces£perror(DEVICE_FILE); £spaces£ £/spaces£return 1; £spaces£ £/spaces£} £spaces£ £/spaces£fcntl(device_fd, F_SETFL, O_NONBLOCK); £spaces£ £/spaces£ £spaces£ £/spaces£//Recuperation des noms de fichier et tri £spaces£ £/spaces£dir = g_dir_open(IMAGES_PATH,0,NULL); £spaces£ £/spaces£while(1){ £spaces£ £/spaces£filename = g_strdup(g_dir_read_name(dir)); £spaces£ £/spaces£if(filename == NULL) £spaces£ £/spaces£break; £spaces£ £/spaces£name = g_malloc((strlen(IMAGES_PATH)+strlen(filename)+1)* sizeof(gchar)); £spaces£ £/spaces£g_sprintf(name,"%s/%s",IMAGES_PATH,filename); £spaces£ £/spaces£g_free(filename); £spaces£ £/spaces£namelist = g_list_append(namelist,name); £spaces£ £/spaces£} £spaces£ £/spaces£namelist = g_list_sort(namelist,(GCompareFunc)strcmp); £spaces£ £/spaces£// Construction interface GTK £spaces£ £/spaces£gtk_init(&argc,&argv); £spaces£ £/spaces£mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); £spaces£ £/spaces£g_signal_connect(G_OBJECT(mainwindow),"destroy",G_CALLBACK(gtk_main_quit),NULL); £spaces£ £/spaces£g_signal_connect(G_OBJECT(mainwindow),"configure-event",G_CALLBACK(size_updated),NULL); £spaces£ £/spaces£ £spaces£ £/spaces£gtk_window_resize(GTK_WINDOW(mainwindow),640, 480); £spaces£ £/spaces£//gtk_window_fullscreen(GTK_WINDOW(mainwindow)); £spaces£ £/spaces£image = gtk_image_new(); £spaces£ £/spaces£gtk_container_add(GTK_CONTAINER(mainwindow),image); £spaces£ £/spaces£gtk_widget_show_all(mainwindow); £spaces£ £/spaces£// Timer £spaces£ £/spaces£signal(SIGALRM,update_image); £spaces£ £/spaces£timer.it_value.tv_sec = 0; £spaces£ £/spaces£timer.it_value.tv_usec = 40000; £spaces£ £/spaces£timer.it_interval.tv_sec = 0; £spaces£ £/spaces£timer.it_interval.tv_usec = 0; £spaces£ £/spaces£setitimer (ITIMER_REAL, &timer, NULL); £spaces£ £/spaces£ £spaces£ £/spaces£// Départ de la boucle principale £spaces£ £/spaces£gtk_main(); £spaces£ £/spaces£return (0); } Question subsidiaire: Pour afficher/redimensionner une image j'utilise gdk_pixbuf et gtk_image car je ne connais que gtk. Y aurait-il une méthode plus simple et/ou plus rapide (sdl, opengl, ...)