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.

#26 Le 20/12/2009, à 23:15

bece

Re : Souris-mètre en C

Finalement on revient à la boucle infinie big_smile
En tout cas avec la boucle événementielle et donc le MotionNotify, j'ai une belle erreur de segmentation. Après débugage cette erreur proviendrait du XQueryPointer qui est placé dans le if (motionNotify);

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

int main(void)
{

    Display *d;
    Window root;
    XEvent ev;
		/* Variables */
	int coorX = 0;
	int coorY = 0;
	int childx = 0;
	int childy = 0;
	int distanceX = 0;
	int distanceY = 0;
	int longueurX = 0;
	int longueurY = 0;
	int longueurT = 0;
	int c = 0; /* compteur */
      /* root window the pointer is in */
  Window inchildwin; /* child win the pointer is in */
  int rootx, rooty;
	unsigned int mask;
	Window *props;
    
    if(!(d = XOpenDisplay(0x0))){
        return 1;
    }
    
    root = DefaultRootWindow(d);
   
    XGrabPointer(d, root, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, root, None, CurrentTime); 
    for(;;)
    {
        XNextEvent(d, &ev);
        if(ev.type == MotionNotify){
					XQueryPointer(d, props[0], &root, &inchildwin, &rootx, &rooty, &childx, &childy, &mask);
           /* Calcul de la distance */
					if (c==1) {
					distanceX = childx - coorX;
					distanceX = fabs((double)distanceX);
					longueurX += distanceX;		
					coorX = childx;
					distanceY = childy - coorY;
					distanceY = fabs((double)distanceY);
					longueurY += distanceY;		
					coorY = childy;
					longueurT = longueurX + longueurY;
					printf("affichage du résultat : %d\n", longueurX); 
					}
					else {
						coorX = childx;
						coorY = childy;
						c = 1;
				} 
      }
   }
}

"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#27 Le 20/12/2009, à 23:22

mika

Re : Souris-mètre en C

Avec ou sans event, j'ai pas d'erreur (à mon avis tu pointes la mauvaise fenêtre, regarde mon code, j'ai tout refait par ce qu'avec des définitions j'étais un peu perdu).

Pour la boucle, elle peut ne pas être infinie (j'ai fait au plus simple), tu peux très bien mettre un event sur une touche ou un bouton de la souris pour arrêter la capture. Mon idée de départ était pas idiote même si inutile au bout du compte (tu remarqueras que le CPU n'est plus bouffé).

Cela dit je reste persuadé que si tu pousses un peu plus loin ton programme, le MotionNotify te sera utile.

Dernière modification par mika (Le 20/12/2009, à 23:24)


Pinard m'a tueR (in vino veritas ?)
Cherche logiciel pour tagger ses vinyles.

Hors ligne

#28 Le 20/12/2009, à 23:27

bece

Re : Souris-mètre en C

En tout cas merci beaucoup pour ton aide.
Mais je pensais à autre chose. Pour éviter qu'il exécute je ne sais combien de fois le calcul à la seconde, pourquoi ne mettrons pas de timer. Par exemple 200milisecondes, ainsi il n'effectuerait le calcul seulement 5 fois par seconde. Et cela m'aiderait pour écrire le résultat dans un fichier (toutes les dix minutes par exemple). A ton avis ?


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#29 Le 20/12/2009, à 23:31

bece

Re : Souris-mètre en C

Oui tes codes qu'il y ait un event ou non fonctionnaient chez moi. C'est juste que quand j'ai rajouté un XQueryPointer() que ça plante. Avec ceci :

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

int main(void)
{

    Display *d;
    Window root;
    XEvent ev;
    Window inchildwin; /* child win the pointer is in */
    int rootx, rooty;
    unsigned int mask;
    Window *props;
    
    if(!(d = XOpenDisplay(0x0))){
        return 1;
    }
    
    root = DefaultRootWindow(d);
   
    XGrabPointer(d, root, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, root, None, CurrentTime); 
    for(;;)
    {
        XNextEvent(d, &ev);
        if(ev.type == MotionNotify){
                    XQueryPointer(d, props[0], &root, &inchildwin, &rootx, &rooty, &childx, &childy, &mask);
          
      }
   }
}

Dernière modification par bece (Le 20/12/2009, à 23:32)


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#30 Le 20/12/2009, à 23:37

mika

Re : Souris-mètre en C

bece a écrit :

En tout cas merci beaucoup pour ton aide.
Mais je pensais à autre chose. Pour éviter qu'il exécute je ne sais combien de fois le calcul à la seconde, pourquoi ne mettrons pas de timer. Par exemple 200milisecondes, ainsi il n'effectuerait le calcul seulement 5 fois par seconde. Et cela m'aiderait pour écrire le résultat dans un fichier (toutes les dix minutes par exemple). A ton avis ?

Ben j'y ai pensé, mais du coup ne vas t'il pas sauter justement des mouvements ?

Essaye avec l'event, je te dis qu'a l'affichage ça saute mais il faudrait voir au bout du compte si tout est bien incrémenté. J'avoue que j'ai pas regardé.

Pour ton erreur c'est props[0] (encore une fois regarde mon code, les trois windows définis, etc...).

Dernière modification par mika (Le 20/12/2009, à 23:38)


Pinard m'a tueR (in vino veritas ?)
Cherche logiciel pour tagger ses vinyles.

Hors ligne

#31 Le 20/12/2009, à 23:44

tiky

Re : Souris-mètre en C

Je te conseille d'utiliser GTK+ pour faire ce programme. Je viens de réussir à écrire l'essentiel en moins de 60 lignes de code et il est portable...


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#32 Le 20/12/2009, à 23:44

bece

Re : Souris-mètre en C

Si il va sauter des mouvements c'est certain. Mais bon on peut bien baisser le nombre de miliseconde, la marge d'erreur diminuerait donc.

Je viens de recouper tes deux codes, et j'ai le Xquerypointer qui fonctione dans l'event.
Tout marche nickel (sans le calcul, je l'ai pas encore mis) :

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

int main(void)
{

    Display *d;
    Window root;
    Window root_return, child_return;
    unsigned int mask;
    int root_x, root_y, win_x, win_y;
    XEvent ev;
   
    if(!(d = XOpenDisplay(0x0))){
        return 1;
    }
    
    root = DefaultRootWindow(d);
   
    XGrabPointer(d, root, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, root, None, CurrentTime);
    
    for(;;)
    {
        XNextEvent(d, &ev);
        if(ev.type == MotionNotify){
             XQueryPointer (d, root, &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask);
            printf(" x:%d y:%d\n",win_x,win_y);
        }
    }
}

Voila demain je teste au niveau des calculs, etc... Et peut-être essayer d'avoir une approche avec le temps. Merci pour l'aide en tout cas smile


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#33 Le 20/12/2009, à 23:45

mika

Re : Souris-mètre en C

Ben voila smile Bon courage pour la suite, je regarderais le final wink


Pinard m'a tueR (in vino veritas ?)
Cherche logiciel pour tagger ses vinyles.

Hors ligne

#34 Le 21/12/2009, à 00:11

tiky

Re : Souris-mètre en C

Si ça vous intéresse, le code GTK+:

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <math.h>
#define INTERVAL 100

typedef struct
{
  gint last_x, last_y;
  gdouble distance;
} MotionRecord;

gdouble distance (gint dx, gint dy)
{
  static gboolean initialized = FALSE;
  static gdouble dx_mm, dy_mm; 
  if (!initialized)
    {
      gdouble width_meter, width_pixel, height_meter, height_pixel;
      GdkScreen *screen = gdk_screen_get_default ();
      width_meter = (gdouble)gdk_screen_get_width_mm (screen) / 1000;
      width_pixel = gdk_screen_get_width (screen);
      height_meter = (gdouble)gdk_screen_get_height_mm (screen) / 1000;
      height_pixel = gdk_screen_get_height (screen);
      
      dx_mm = (gdouble)width_meter / width_pixel;
      dy_mm = (gdouble)height_meter / height_pixel;
      initialized = TRUE;
    }
    
  return sqrt (pow (dx_mm*dx, 2) + pow (dy_mm*dy, 2));
}

gboolean record_motion (gpointer data)
{
  static gboolean initialized = FALSE;
  MotionRecord *record = (MotionRecord *)data;
  GdkWindow *root_window;
  gint x, y;  
  
  root_window = gdk_screen_get_root_window (gdk_screen_get_default ());
  gdk_window_get_pointer (root_window, &x, &y, NULL);
  
  if (initialized)
    {
      gint dx, dy;
      dx = record->last_x - x;
      dy = record->last_y - y;
      record->distance += distance (dx, dy);
    }
  else
    initialized = TRUE;
    
  record->last_x = x;
  record->last_y = y;
  g_print ("distance: %.2fm\n", record->distance);
  return TRUE;
}

int main (int argc, char **argv)
{
  MotionRecord record = {0};
  
  gtk_init (&argc, &argv);
  g_timeout_add (INTERVAL, record_motion, &record);
  gtk_main ();
  
  return EXIT_SUCCESS;
}

Dernière modification par tiky (Le 21/12/2009, à 00:19)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#35 Le 21/12/2009, à 00:14

mika

Re : Souris-mètre en C

Sur qu'en gtk ou qt c'est plus simple... L'avantage de la xlib c'est que c'est au niveau inférieur donc tu te libères de ça.
En tout cas après avoir retâter du xlib, je sais pourquoi j'y touchais plus smile


Pinard m'a tueR (in vino veritas ?)
Cherche logiciel pour tagger ses vinyles.

Hors ligne

#36 Le 21/12/2009, à 00:27

tiky

Re : Souris-mètre en C

mika a écrit :

Sur qu'en gtk ou qt c'est plus simple... L'avantage de la xlib c'est que c'est au niveau inférieur donc tu te libères de ça.
En tout cas après avoir retâter du xlib, je sais pourquoi j'y touchais plus smile

Oui mais il faut bien faire un choix et la xlib c'est quand même loin d'être le meilleur. On ne peut pas de toute façon se dispenser d'une bibliothèque graphique et pratiquement tous les systèmes qui possèdent la Xlib possèdent également GTK+. Sans compter qu'une fois le souris-mètre terminé, il est quand même plus sympathique de réaliser une interface graphique pour afficher la distance avec GTK+ qu'avec la Xlib.

Dernière modification par tiky (Le 21/12/2009, à 00:31)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#37 Le 21/12/2009, à 10:59

bece

Re : Souris-mètre en C

Bonjour,

tiky a écrit :

width_meter = (gdouble)gdk_screen_get_width_mm (screen) / 1000;

Avec gtk il existerait une fonction qui calculerait directement le nombre de milimètres ?? Ce serait très intérenssant parce que sinon il faudrait calculer pour chaque résolution combien vaut un pixel.

Au final, il y aura bien sur une petite interface graphique pour indiquer la distance parcourue. Mais avec gtk y a-t-il possibilité de passer dans la zone de notification ?


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#38 Le 21/12/2009, à 12:03

bece

Re : Souris-mètre en C

Bon pas moyen de faire marcher ton code, je n'ai peut-être pas gtk, j'ai essayé de l'installer, mais j'ai des erreur à tous mes ./configure, et le paquet libgtk-dev ne veut pas non plus s'installer.

Edit : Bon j'ai réussi à installer les différents fichiers : libgtk2.0-dev, libgtk2.0-bin, libgtk2.0-common, libgtk2.0-0, libgtk2.0-cil mais à la compilation j'ai ça :

bece@bece-desktop:~$ gcc `pkg-config --libs --cflags gtk+` mainb.c -o testgtk;
sh: gtk-config: not found
sh: gtk-config: not found
sh: gtk-config: not found
mainb.c:2:21: error: gtk/gtk.h: Aucun fichier ou dossier de ce type
mainb.c: In function ‘main’:
mainb.c:6: error: ‘GtkWidget’ undeclared (first use in this function)
mainb.c:6: error: (Each undeclared identifier is reported only once
mainb.c:6: error: for each function it appears in.)
mainb.c:6: error: ‘p_Window’ undeclared (first use in this function)
mainb.c:7: error: ‘p_Label’ undeclared (first use in this function)
mainb.c:8: error: ‘gchar’ undeclared (first use in this function)
mainb.c:8: error: ‘sUtf8’ undeclared (first use in this function)
mainb.c:12: error: ‘GTK_WINDOW_TOPLEVEL’ undeclared (first use in this function)
mainb.c:15: error: ‘GTK_WIN_POS_CENTER’ undeclared (first use in this function)
mainb.c:16: error: ‘gtk_main_quit’ undeclared (first use in this function)

Dernière modification par bece (Le 21/12/2009, à 13:18)


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#39 Le 21/12/2009, à 13:17

tiky

Re : Souris-mètre en C

bece a écrit :

Bonjour,

tiky a écrit :

width_meter = (gdouble)gdk_screen_get_width_mm (screen) / 1000;

Avec gtk il existerait une fonction qui calculerait directement le nombre de milimètres ?? Ce serait très intérenssant parce que sinon il faudrait calculer pour chaque résolution combien vaut un pixel.

Au final, il y aura bien sur une petite interface graphique pour indiquer la distance parcourue. Mais avec gtk y a-t-il possibilité de passer dans la zone de notification ?

Oui cette fonction existe... tu l'as sous les yeux big_smile. Elle donne la taille de l'écran en millimètre. J'ai testé avec une règle, le programme est très précis.

Pour compiler:

gcc -o code code.c -Wall -g -pedantic $(pkg-config --libs --cflags gtk+-2.0)

Quelles sont les erreurs que tu obtiens quand tu essayes d'installer libgtk-dev?

Dernière modification par tiky (Le 21/12/2009, à 13:20)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#40 Le 21/12/2009, à 13:21

bece

Re : Souris-mètre en C

J'ai édité mon précédent post, et j'ai donc installer les différentes choses qu'il faut pour gtk, par contre je n'arrive pas à compiler.

tiky a écrit :

Oui cette fonction existe... tu l'as sous les yeux big_smile. Elle donne la taille de l'écran en millimètre. J'ai testé avec une règle, le programme est très précis.

C'est excellent ça smile

Et en faisant ta commande pour compiler, j'obtiens ceci :

bece@bece-desktop:~$ gcc -o code gtk.c -Wall -g -pedantic $(pkg-configure --libs --cflags gtk+-2.0)
pkg-configure: command not found
gtk.c:3:21: error: gtk/gtk.h: Aucun fichier ou dossier de ce type
gtk.c:4:18: error: glib.h: Aucun fichier ou dossier de ce type
gtk.c:10: error: expected specifier-qualifier-list before ‘gint’
gtk.c:12: warning: struct has no members
gtk.c:14: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘distance’
gtk.c:35: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘record_motion’
gtk.c: In function ‘main’:
gtk.c:63: warning: excess elements in struct initializer
gtk.c:63: warning: (near initialization for ‘record’)
gtk.c:65: warning: implicit declaration of function ‘gtk_init’
gtk.c:66: warning: implicit declaration of function ‘g_timeout_add’
gtk.c:66: error: ‘record_motion’ undeclared (first use in this function)
gtk.c:66: error: (Each undeclared identifier is reported only once
gtk.c:66: error: for each function it appears in.)
gtk.c:67: warning: implicit declaration of function ‘gtk_main’

Edit : Bon j'ai trouvé d'où vient l'erreur des fichiers non trouvés. C'est jsute qu'ils ne sont pas la bonne place indiquée dans le .c. Sauf que si je met le bon nom de chemin, il ne trouve pas non plus puisque gtk.h inclu plein d'autres .h et il faudrait à eux aussi changer le chemin pour y arriver. Y a-t-il un autre moyen ?

Dernière modification par bece (Le 21/12/2009, à 14:22)


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#41 Le 21/12/2009, à 15:09

tiky

Re : Souris-mètre en C

Je mettais trompé dans la commande à taper. Je l'ai corrigée mais trop tard wink.

pkg-configure: command not found

Normale, la bonne commande est pkg-config.

Il ne faut pas changer les #include dans le code source. Ils sont parfaitement corrects !


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#42 Le 21/12/2009, à 16:06

bece

Re : Souris-mètre en C

Merci beaucoup, ça fonctionne parfaitement. smile


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#43 Le 21/12/2009, à 19:21

bece

Re : Souris-mètre en C

Est-ce que tu peux m'expliquer un petit peu ton code stp, je n'ai jamais fait de gtk.


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#44 Le 21/12/2009, à 19:29

vogia

Re : Souris-mètre en C

suivez ce cours d'université et vous en apprendrez beaucoup:
http://www-lipn.univ-paris13.fr/~recanati/05.htm

#45 Le 21/12/2009, à 19:41

bece

Re : Souris-mètre en C

Oui merci, j'étais tombé dessus au cour de mes recherches, mais c'est sur la librairie X11.


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#46 Le 21/12/2009, à 23:04

tiky

Re : Souris-mètre en C

Bonsoir,

Je te détaille le code. Il est pas très propre. Je suis en train d'en faire un bien meilleur avec un jolie widget transparent pour l'affichage.

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <math.h>
#define INTERVAL 100

Je pense qu'il n'y a pas grand chose à dire là-dessus.

typedef struct
{
  gint last_x, last_y;
  gdouble distance;
} MotionRecord;

Cette structure permet d'enregistrer la distance parcourue par la souris jusqu'alors et la dernière position capturée de manière à pouvoir calculer la prochaine distance.

gdouble distance (gint dx, gint dy)
{
  static gboolean initialized = FALSE;
  static gdouble dx_mm, dy_mm; 
  if (!initialized)
    {
      gdouble width_meter, width_pixel, height_meter, height_pixel;
      GdkScreen *screen = gdk_screen_get_default ();
      width_meter = (gdouble)gdk_screen_get_width_mm (screen) / 1000;
      width_pixel = gdk_screen_get_width (screen);
      height_meter = (gdouble)gdk_screen_get_height_mm (screen) / 1000;
      height_pixel = gdk_screen_get_height (screen);
      
      dx_mm = (gdouble)width_meter / width_pixel;
      dy_mm = (gdouble)height_meter / height_pixel;
      initialized = TRUE;
    }
    
  return sqrt (pow (dx_mm*dx, 2) + pow (dy_mm*dy, 2));
}

Cette fonction calcule la distance parcourue par la souris en mètre. Elle prend en paramètre la variation de l'abscisse et l'ordonnée. La variable initialized permet de s'assurer que le calcule du rapport entre le mètre et le pixel
de l'écran n'est pas fait à chaque appel de la fonction (nb : dans le code que je prépare, le calcule est fait à chaque fois que l'on change d'écran).

Les fonctions gdk_screen_get_width et gdk_screen_get_height donne la taille en pixel de l'écran. Les homologues
se terminant par _mm donne la taille en millimètre. 

gboolean record_motion (gpointer data)
{
  static gboolean initialized = FALSE;
  MotionRecord *record = (MotionRecord *)data;
  GdkWindow *root_window;
  gint x, y;  
  
  root_window = gdk_screen_get_root_window (gdk_screen_get_default ());
  gdk_window_get_pointer (root_window, &x, &y, NULL);
  
  if (initialized)
    {
      gint dx, dy;
      dx = record->last_x - x;
      dy = record->last_y - y;
      record->distance += distance (dx, dy);
    }
  else
    initialized = TRUE;
    
  record->last_x = x;
  record->last_y = y;
  g_print ("distance: %.2fm\n", record->distance);
  return TRUE;
}

Cette fonction est appelée à intervalle régulier. Elle récupère la postion de la souris à l'aide de la fonction gdk_window_get_pointer qui attend comme argument un pointeur sur un GdkWindow. gdk_screen_get_root_window
permet d'obtenir ce pointeur la «fenêtre mère», c'est-à-dire l'écran en totalité sur le serveur X11 par exemple.

int main (int argc, char **argv)
{
  MotionRecord record = {0};
  
  gtk_init (&argc, &argv);
  g_timeout_add (INTERVAL, record_motion, &record);
  gtk_main ();
  
  return EXIT_SUCCESS;
}

gtk_init permet d'initialiser la bibliothèque GTK+. g_timeout_add ajoute une fonction a appelé à intervalle régulier dans la boucle des événements. gtk_main lance cette boucle.

Dernière modification par tiky (Le 21/12/2009, à 23:04)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#47 Le 22/12/2009, à 00:26

n3o51

Re : Souris-mètre en C

Bonsoir

Bien sympa ton prog la tiny pourrait tu remettre le code en une seule fois et comment le compiler smile

Merci après on pourras facilement intégrer ça a conky big_smile

Dernière modification par n3o51 (Le 22/12/2009, à 00:27)


Welcome to the real world
________________________________

Hors ligne

#48 Le 22/12/2009, à 00:50

tiky

Re : Souris-mètre en C

@n3o51 : Il est à la page précédente, mais j'en ai fait un meilleur, seulement je galère pour obtenir un widget transparent. Ça ne fonctionne pas alors que j'ai bien l'extension composite activée.

Dernière modification par tiky (Le 22/12/2009, à 00:50)


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne

#49 Le 22/12/2009, à 11:45

bece

Re : Souris-mètre en C

Merci, voila ce que je ne comprenais pas, c'était comment c'était possible que ça boucle alors qu'il n'y en avait nul part big_smile

Edit : Bon avant de continuer plus en avant (création graphique plus mis en place dans le system tray) je vais essayer d'apprendre cette bibliothèque. ben oui, c'est bien les codes tout fait mais c'est encore mieux quand on le fait soit même.

Dernière modification par bece (Le 22/12/2009, à 11:57)


"L'informatique, c'est l'art de passer 15 jours à gagner 5 millisecondes"

Hors ligne

#50 Le 22/12/2009, à 12:49

tiky

Re : Souris-mètre en C

bece a écrit :

Merci, voila ce que je ne comprenais pas, c'était comment c'était possible que ça boucle alors qu'il n'y en avait nul part big_smile

Edit : Bon avant de continuer plus en avant (création graphique plus mis en place dans le system tray) je vais essayer d'apprendre cette bibliothèque. ben oui, c'est bien les codes tout fait mais c'est encore mieux quand on le fait soit même.

La seule vraie documentation : http://library.gnome.org/devel/gtk/stable/index.html
Tu peux également trouvé des tutoriels sur le même site wink.


Conseil d'expert: il vous faut un dentifrice adapté...

Hors ligne