Forum Programmation.c Xlib et evênements souris

Posté par  .
Étiquettes : aucune
0
18
août
2008
Bonjour,

je souhaite faire un petit programme en C qui intercepte tous les clicks souris pas seulement ceux sur une fenêtre précise, est ce possible?
Si oui comment? (la Xlib n'est peut être pas la bonne solution).

Pour être plus clair, je voudrais implémenter l'équivalent d'un hook souris sous windows afin de pouvoir gérer les évênements souris sur une vidéo jouée grâce à la libVLC (qui consume tous les évênements souris empêchant au développeur de les gérer).

La solution du hook fonctionne parfaitement sous windows mais la je suis vraiment à cours d'idée pour implémenter ça sous linux et je ne vois pas trop ou chercher de l'aide en ce qui concerne Xlib.

Merci d'avance.
  • # edit

    Posté par  . Évalué à 1.

    Précision: n'est-il pas possible d'intercepter directement les évènements venant du noyau ou un truc du style (plus bas niveau encore que la Xlib) ?
    • [^] # Re: edit

      Posté par  . Évalué à 2.

      Niveau kernel, tu peux aller voir dans /dev/input, il doit y avoir ce que tu cherches.
      • [^] # Re: edit

        Posté par  (site web personnel) . Évalué à 1.

        Oui en se mettant en filtre.

        Tu lis /dev/input/mice puis tu ressort le tout telquel dans un pipte nommé (commande mkfifo) et tu utilise ce pipe dans la config de X comme device de souris.

        Pour la lecture je connais http://search.cpan.org/~beppu/Linux-Input-1.02/lib/Linux/Inp(...) en perl, mais je ne sais pas quelle est la lib C qui est en dessous.
        • [^] # Re: edit

          Posté par  . Évalué à 2.

          Je vais peut-être dire une connerie, mais les données écrites dans /dev/input/mouse (ou équivalent) sont hardware-dependent non ?
          • [^] # Re: edit

            Posté par  (site web personnel) . Évalué à 2.

            Pas tout à fait. C'est justement l'intérêt des dev/input, le noyau formate les messages.
            Donc à part différencier clavier / souris ... (et seulement s'il a besoin) l'utilisateur n'a pas complexité à gérer.
            • [^] # Re: edit

              Posté par  . Évalué à 1.

              Ok, j'arrive à lire correctement dans le /dev/input/event correspondant à ma souris, des structures et constantes dans linux/input.h permettent d'interprété facilement ces données.

              De là, j'ai plusieurs questions :

              Quelles différences entre /dev/input/mice et le /dev/input/event* correspondant à la souris ? (apparemment /dev/input/mice ne reçoit pas tous les evénements)

              je ne suis pas un pro de linux et je n'ai donc pas compris l'histoire du tube nommé :)

              Dernière chose qui me tracasse, avec cette méthode, je n'ai aucun moyen de récupérer la position de la souris sur l'écran ? (j'ai regardé les sorties de /dev/input/event et /dev/input/mice, je ne vois aucun champ pouvant correspondre à la position du pointeur ).

              Ca fait beaucoup de questions, mais il est très difficile de trouver des infos à ce sujet sur le net :>
              • [^] # Re: edit

                Posté par  (site web personnel) . Évalué à 3.

                Je crois que la différence ne tient qu'au nom, mais je ne suis pas sur.

                Un tube nommé c'est un pipe (comme ca |) mais qui a un nom dans le système de fichier (comme /tmp/toto). La seule fonction d'un tube (ou pipe) c'est de lire toute ce que tu lui envoie et de le ressortir tel quel. Ainsi tu peux faire croire à une application qu'elle lit un fichier alors qu'elle lit un flux que tu lui envoie au fur et a mesure.

                Et en effet, avec cette méthode tu ne peux pas connaître la position du curseur puisque tu ne lis que des evenements de déplacement de souris qui sont interpretés après par le serveur X. Et dans ce cas tu n'as pas de meilleur source d'information que X -> voir le message en dessous sur vnc.
  • # VNC

    Posté par  . Évalué à 1.

    Un chti tour dans les sources d'un serveur VNC devrait te mettre plus que sur la bonne voie.
    • [^] # Re: VNC

      Posté par  . Évalué à 2.

      J'ai regardé les sources de RealVNC et il utilise bien le systême d'events de la Xlib. J'avais tenté de faire la même chose avant de voir ce code et évidemment ça ne fonctionne pas. Comme pour les techniques cités ci-dessus, trouver de l'aide pour la Xlib c'est pas facile.
  • # moi j'aurais plutôt regardé

    Posté par  . Évalué à 1.

    xev qui est un utilitaire qui permet de savoir tout ce que tu fait avec ton interface
    ( frappe au claver, déplacement de sourie... )

    <mode id="HS">
    génial comme keylogger quand des boulet sont passé par xhost +machine ou xhost +

    après 2 ans en IUT info on fini par connaitre ce genre de détail :D

    faites comme moi utiliser xauth add ou ssh -X ( ce qui n'empêche pas root de faire de même, mais au moins les utilisateurs normaux ne peuvent pas )
    </mode >

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: moi j'aurais plutôt regardé

      Posté par  . Évalué à 1.

      Y'avait de l'idée masi tout comme moi, xed n'est pas capable de détecter les mouvement, click, etc de souris sur une fenêtre autre que celle qu'il créé lui même...
      • [^] # Re: moi j'aurais plutôt regardé

        Posté par  . Évalué à 3.

        y a la solution du bourrin qui consisterait à faire une fenêtre transparente au dessus du reste en plein écran :D

        Sinon tu peux aussi spécifier l'id de la fenêtre à écouter avec l'option -id
        Pour récupérer l'id d'une fenêtre il faut utiliser xwininfo. Ensuite en regardant comment xev arriver à se binder au dessus d'une fenêtre d'une application tu devrais pouvoir faire ce que tu cherches (je pense)

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: moi j'aurais plutôt regardé

          Posté par  . Évalué à 1.

          ouais justement, tu peux spécifié une autre fenêtre mais impossible d'intercepter les clicks souris sur la fenêtre en question...

          Ce qui me parait normal puisqu'on peut lire dans la doc de la Xlib: "Only one client at a time can select a ButtonPress event, which is associated with the event mask ButtonPressMask."

          J'y avais pensé à la fenêtre transparente quand je cherchais comment faire sous Windows :D
          Je crois que je vais tenté comme ça sous nux :)
  • # Les extensions DEC-XTRAP et RECORD ?

    Posté par  . Évalué à 4.

    Bonjour,

    Après quelques recherches, il me semble que, selon ce que tu veux faire, tu puisse utiliser les extensions X11 suivantes:

    - RECORD: permet de recevoir les évènements X, mais probablement pas de les intercepter [http://refspecs.linux-foundation.org/X11/recordlib.pdf];

    - DEC-XTRAP, aka XTrap: qui permet cette fois en plus de capturer les évènements concernés [http://perso.tls.cena.fr/jestin/Video/Docs/XTrap_Arch.ps.gz].

    Ces extensions sont en général présente sur tous les serveurs X11 (ie: même sur les "vieilles" machines, hors linux).

    Sinon, il y a aussi d'autres solutions de bricolage:
    - demander à recevoir *aussi* les évenements de la fenêtre (man XChangeWindowAttributes, man XSetWindowAttributes: le champs event_mask), d'après la doc c'est possible;
    - créer une fenêtre transparente par dessus (InputOnly dans man XCreateWindow), mais ça n'est pas certain qu'elle reste au-dessus (dépend du WM);

    Bon sinon je n'ai jamais utilisé la libVLC, mais cela m'étonnes que celq soit un problème, car d'après [http://www.videolan.org/developers/vlc/doc/doxygen/html/grou(...)], c'est toi qui possède la fenêtre qui tu lui as spécifiée avec libvlc_media_player_set_drawable, me trompe-je ?
    • [^] # Re: Les extensions DEC-XTRAP et RECORD ?

      Posté par  . Évalué à 1.

      En fait, je tiens à préciser que mon application est en JAVA et utilise jVLC pour accéder à la libVLC, mais de la même manière je lui passe une objet ou dessiné et cet objet ne reçoit tout simplement pas les evenements. Il faut que je regarde comment vlc gère ça masi je crois que d'une manière ou d'une autre la lib absorbe les events donc inutile de s'enregistrer en tant que receveur au niveau de la fenêtre, on ne reçoit rien...

      En revanche la Xlib a un système de grab qui permet de s'accaparer le pointeur et donc de recevoir tous les evenements liés à celui ci, l'incovénient, c'est que les evenements en question ne sont plus transmis aux autres fenêtres, en gros ca freeze l'interface...

      J'ai deja essayé le InputOnly et ca ne marche pas (je ne sais pas si on peut recevoir des evénements sur une fenêtre InputOnly) de toute manière, cette méthode me plait moyennement :)

      Je vais approfondir la piste du XGrabPointer et essayer de voir ce que je peux faire avec les extensions.

      Merci pour vos suggestions :)
      • [^] # Re: Les extensions DEC-XTRAP et RECORD ?

        Posté par  . Évalué à 2.

        La solution par le grab est une solution à laquelle j'avais pensé, mais qui est un peu trops gruik à mon goût... Cependant, si tu veux l'essayer, cela peut marcher:
        - dans l'évenement XButtonEvent, tu as un champs subwindow, qui doit contenir la fenêtre sur laquelle l'utilisateur à cliqué;
        - lui faire suivre l'évennement, grace à XSendEvent.

        Pour le InputOnly, elle doit recevoir des évennements, elles ne peuvent même normalement faire que cela...

        Par contre, je viens de penser que la bonne solution par cette méthode, c'est de créer la fenêtre comme fenêtre fille de la fenêtre VLC, de la mettre sur le devant (XRaiseWindow... au dernier moment), cela pourrait peut-être marcher.
        (au pire, il faut peut-être la mettre en InputOutput?)
        • [^] # Re: Les extensions DEC-XTRAP et RECORD ?

          Posté par  . Évalué à 1.

          Bon et bien XTrap fait exactement ce que je veux, intercepter n'importe quels evénements sans perturber le flow normal (pas besoin de les réenvoyer après ou quoi que ce soit), plus qu'a interfacer ça en JAVA.

          Merci :>

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.