IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

[Xlib]Recuperer clic souris et touches claviers


Sujet :

Linux

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut [Xlib]Recuperer clic souris et touches claviers
    Salut à tous,

    J'aimerai récupérer le clic de la souris et l'appuie sur une touche du clavier avec la Xlib (attention pas en tant qu'évènement de fenêtre). Est ce qu'il existe une fonction qui renvoit les différentes actions du clavier et des clics de la souris (dans un intervalle de temps donné) ???
    J'ai rien trouvé de la sorte dans la doc...

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    t'as pas assez cherché

    XSelectInput

    XNextEvent

    switch ( event->type)
    ....

    Et pour avoir toutes les fenêtres, XQueryTree
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut
    Ok merci, j'ai essayé ces fonctions... et j'ai un ptit bug, dans le code suivant, j'ai uniquement les évènements claviers qui sont reconnus (pas le clic de souris ni les mouvements de la souris). Je ne vois vraiment pas d'où pourrait venir l'erreur... peut être que ça a un rapport avec le fait que cette portion de code est excecutée dans un thread ?(aucune raison à prioris)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
        XSelectInput(d, focus, ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask );
        XEvent e;
        while(true)
        {
            printf("attente d'un evenement\n");
            XNextEvent(d, &e);
            if(e.type == MotionNotify)
            {
                printf("ca bouge\n");
            }
            else if (e.type == ButtonPress)
            {
                printf("touche souris appuyee !!!\n");
            }
            else if (e.type==KeyPress)
            {
                printf("bouton clavier\n");
            }
            else
            {
                printf("ca boucle\n");
            }
        }

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut
    En fait , j'ai l'erreur suivante :

    X Error of failed request: BadAccess (attempt to access private resource denied)

    j'ai cette erreur lorsque j'essaye d'accéder aux évènements d'une fenêtre (via XSelectInput) que je n'ai pas directement crée. On dirait qu'il y a une protection qui empèche un programme extérieur d'écouter les évènements d'une fenêtre qui n'est pas déclarée dans le programme... est-ce possible ?

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Falcor Voir le message
    En fait , j'ai l'erreur suivante :

    X Error of failed request: BadAccess (attempt to access private resource denied)

    j'ai cette erreur lorsque j'essaye d'accéder aux évènements d'une fenêtre (via XSelectInput) que je n'ai pas directement crée. On dirait qu'il y a une protection qui empèche un programme extérieur d'écouter les évènements d'une fenêtre qui n'est pas déclarée dans le programme... est-ce possible ?
    non. Ecouter est toujours possible..

    voici un petit exemple pour "ecouter" le ScrollLock :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    /*  
    *
    *   COPYRIGHT 2008 COGITECH Jean SOUVIRON
    *   19 Fevrier 2008
    *
    *   Petit programme pour surveiller les clefs (ici ScrollLock)
    *   et appeler un script ou un programme sur l'activation de la touche
    *
    *
    *
    *
    *   Contient :
    *
    *    void   Finish        pour fermer la connection
    *
    *    void   Usage         pour donner les parametres
    *
    *    void   Hierarchie    pour recuperer la clef quelle que soit la fenetre.
    *        
    *
    */
    
    
    /*---- Include */
    #include <stdio.h>
    #include <strings.h>
    
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    
    
    /*--- Variables globales ---*/
    static Display *display ;
    
    
    
    
    
    /*
     * Usage
     *
     */
    static void Usage ( char *Name )
    {
      fprintf ( stderr, "\n\n%c\nCe programme peut avoir un parametre :",toascii(7));
      fprintf ( stderr, "\nAppel : %s [-f commandname]", Name);
      fprintf ( stderr, "\nCommandname : le nom (avec chemin complet) d'un script ou");
      fprintf ( stderr, "\n              d'un programme qui sera appelle lorsque la touche");
      fprintf ( stderr, "\n              ScrollLock sera appuyee");
      fprintf( stderr, "\nSinon on appellera l'action par defaut.\n%c",toascii(7));
    } 
    
    
    
    /* 
     * Finish
     *
     */
    static void Finish ( void )
    {
      XCloseDisplay(display);
    }
    
    
    
    /*
     * Hierarchie
     *
     */
    static void Hierarchie ( Window racine )
    {
      Window w1, child, *children=(Window *)NULL ;
      int    nchildren, i ;
    
      XQueryTree ( display, racine, &w1, &child, &children, &nchildren );
      if ( nchildren > 0 )
        {
          for ( i = 0 ; i < nchildren ; i++ )
            Hierarchie ( children[i] );
          
          XFree(children);
        }
    
      XSelectInput (display, racine, KeyReleaseMask|SubstructureNotifyMask);
    }
    
    
    
    
    /*
     * Main
     *
     */
    int main (int argc, char *argv[])
    {
    Window               root ;
    KeySym	             Symbol, ScrollLock=-1 ;
    XKeyEvent           *Eve=(XKeyEvent *)NULL ;
    XMapEvent           *Map=(XMapEvent *)NULL ;
    XEvent               event ;
    XKeyboardControl     kbd ; 
    XKeyboardState       kst ;
    XSetWindowAttributes xswa ;
    int                  screen, x, n ;
    char                 Chaine[5], Command[500], a ;
    
    
    /*
    --- Initialisations
    */
     x = 0 ;
     for ( n = 1 ; n < argc ; n++ )
       if ( strcasecmp(argv[n], "-f") == 0 )
         {
           if ( n != (argc-1) )
             x = n ;
           else
             x = -1 ;
          
           break ;
         }
    
     if ( x < 0 )
       {
         Usage(argv[0]);
         return 1 ;
       }
    
     if ( (x == 0) && (argc > 1) )    /* édité !!! */
       {
         Usage(argv[0]);
         return 1 ;
       }
    
     if ( x > 0 )
       sprintf ( Command, "%s &", argv[x+1]);
     else
       strcpy ( Command, "" );
    
    
    
     atexit((void *)&Finish);
     display = XOpenDisplay ("");
    
    
    /*
    --- Selection de l'input
    */
     n = ScreenCount ( display );
     for ( x = 0 ; x < n ; x++ )
       {
         root = XRootWindow (display, x);
         Hierarchie(root);
       }
    
    
    
    /*
    --- Recuperation du symbole ScrollLock
    */
     ScrollLock = XStringToKeysym ("Scroll_Lock");
    
     kbd.led = 3 ;
     XGetKeyboardControl ( display, &kst );
     a = (char)kst.led_mask ;
     kbd.led_mode = (a << 2);
    
    
    
    /*
    --- Boucle infinie de lecture des evenements
    */
     while ( 1 )
       {
         XNextEvent (display, &event );
    
         switch (event.type )
           {
             /* Le vrai evenement a surveiller */
             case KeyRelease :
                 Eve = (XKeyEvent *)&event ;
                 memset ( Chaine, '\0', 5 ) ;
                 XLookupString ( Eve, Chaine, 4, &Symbol, NULL );
    
                 if ( Symbol == ScrollLock)
                   {
                     if ( kbd.led_mode == LedModeOn )
                         kbd.led_mode = LedModeOff ;
                     else
                         kbd.led_mode = LedModeOn ;
                     
                     if ( strlen(Command) == 0 )
                         XChangeKeyboardControl (display,KBLedMode, &kbd);
                     else
                       {
                         system(Command);
                       }
                   }
                 break ;
    
             /* En cas de creation de fenetre, on a besoin de selectionner */
             /* l'evenement sur cette fenetre et ses descendants */
             case MapNotify :
                 Map = (XMapEvent *)&event ;
                 Hierarchie(Map->window);
                 break ;
    
             default :
                 break ;
           }
       }
    
    
    /*
    --- Fin
    */
     Finish();
    
     return 0 ;
    }
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    non. Ecouter est toujours possible..

    voici un petit exemple pour "ecouter" le ScrollLock :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
     
    /*  
    *
    *   COPYRIGHT 2008 COGITECH Jean SOUVIRON
    *   19 Fevrier 2008
    *
    *   Petit programme pour surveiller les clefs (ici ScrollLock)
    *   et appeler un script ou un programme sur l'activation de la touche
    *
    *
    *
    *
    *   Contient :
    *
    *    void   Finish        pour fermer la connection
    *
    *    void   Usage         pour donner les parametres
    *
    *    void   Hierarchie    pour recuperer la clef quelle que soit la fenetre.
    *        
    *
    */
     
     
    /*---- Include */
    #include <stdio.h>
    #include <strings.h>
     
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
     
     
    /*--- Variables globales ---*/
    static Display *display ;
     
     
     
     
     
    /*
     * Usage
     *
     */
    static void Usage ( char *Name )
    {
      fprintf ( stderr, "\n\n%c\nCe programme peut avoir un parametre :",toascii(7));
      fprintf ( stderr, "\nAppel : %s [-f commandname]", Name);
      fprintf ( stderr, "\nCommandname : le nom (avec chemin complet) d'un script ou");
      fprintf ( stderr, "\n              d'un programme qui sera appelle lorsque la touche");
      fprintf ( stderr, "\n              ScrollLock sera appuyee");
      fprintf( stderr, "\nSinon on appellera l'action par defaut.\n%c",toascii(7));
    } 
     
     
     
    /* 
     * Finish
     *
     */
    static void Finish ( void )
    {
      XCloseDisplay(display);
    }
     
     
     
    /*
     * Hierarchie
     *
     */
    static void Hierarchie ( Window racine )
    {
      Window w1, child, *children=(Window *)NULL ;
      int    nchildren, i ;
     
      XQueryTree ( display, racine, &w1, &child, &children, &nchildren );
      if ( nchildren > 0 )
        {
          for ( i = 0 ; i < nchildren ; i++ )
            Hierarchie ( children[i] );
     
          XFree(children);
        }
     
      XSelectInput (display, racine, KeyReleaseMask|SubstructureNotifyMask);
    }
     
     
     
     
    /*
     * Main
     *
     */
    int main (int argc, char *argv[])
    {
    Window               root ;
    KeySym	             Symbol, ScrollLock=-1 ;
    XKeyEvent           *Eve=(XKeyEvent *)NULL ;
    XMapEvent           *Map=(XMapEvent *)NULL ;
    XEvent               event ;
    XKeyboardControl     kbd ; 
    XKeyboardState       kst ;
    XSetWindowAttributes xswa ;
    int                  screen, x, n ;
    char                 Chaine[5], Command[500], a ;
     
     
    /*
    --- Initialisations
    */
     x = 0 ;
     for ( n = 1 ; n < argc ; n++ )
       if ( strcasecmp(argv[n], "-f") == 0 )
         {
           if ( n != (argc-1) )
             x = n ;
           else
             x = -1 ;
     
           break ;
         }
     
     if ( x < 0 )
       {
         Usage(argv[0]);
         return 1 ;
       }
     
     if ( x > 0 )
       sprintf ( Command, "%s &", argv[x+1]);
     else
       strcpy ( Command, "" );
     
     
     
     atexit((void *)&Finish);
     display = XOpenDisplay ("");
     
     
    /*
    --- Selection de l'input
    */
     n = ScreenCount ( display );
     for ( x = 0 ; x < n ; x++ )
       {
         root = XRootWindow (display, x);
         Hierarchie(root);
       }
     
     
     
    /*
    --- Recuperation du symbole ScrollLock
    */
     ScrollLock = XStringToKeysym ("Scroll_Lock");
     
     kbd.led = 3 ;
     XGetKeyboardControl ( display, &kst );
     a = (char)kst.led_mask ;
     kbd.led_mode = (a << 2);
     
     
     
    /*
    --- Boucle infinie de lecture des evenements
    */
     while ( 1 )
       {
         XNextEvent (display, &event );
     
         switch (event.type )
           {
             /* Le vrai evenement a surveiller */
             case KeyRelease :
                 Eve = (XKeyEvent *)&event ;
                 memset ( Chaine, '\0', 5 ) ;
                 XLookupString ( Eve, Chaine, 4, &Symbol, NULL );
     
                 if ( Symbol == ScrollLock)
                   {
                     if ( kbd.led_mode == LedModeOn )
                         kbd.led_mode = LedModeOff ;
                     else
                         kbd.led_mode = LedModeOn ;
     
                     if ( strlen(Command) == 0 )
                         XChangeKeyboardControl (display,KBLedMode, &kbd);
                     else
                       {
                         system(Command);
                       }
                   }
                 break ;
     
             /* En cas de creation de fenetre, on a besoin de selectionner */
             /* l'evenement sur cette fenetre et ses descendants */
             case MapNotify :
                 Map = (XMapEvent *)&event ;
                 Hierarchie(Map->window);
                 break ;
     
             default :
                 break ;
           }
       }
     
     
    /*
    --- Fin
    */
     Finish();
     
     return 0 ;
    }
    Bonjour souviron34, j'ai modifié ton programme afin qu'il compile, peux tu expliquer rapidement comment s'en servir, quand je l'appelle sans lui passer d'argument, il ne fais rien, il n'affiche même pas la fonction usage!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    /*  
     *
     *   COPYRIGHT 2008 COGITECH Jean SOUVIRON
     *   19 Fevrier 2008
     *
     *   Petit programme pour surveiller les clefs (ici ScrollLock)
     *   et appeler un script ou un programme sur l'activation de la touche
     *
     *
     *
     *
     *   Contient :
     *
     *    void   Finish        pour fermer la connection
     *
     *    void   Usage         pour donner les parametres
     *
     *    void   Hierarchie    pour recuperer la clef quelle que soit la fenetre.
     *        
     *
     */
     
    /*---- Include */
    #include <stdio.h>
    #include <strings.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
     
    /*--- Variables globales ---*/
    static Display *display;
     
    /*
     * Usage
     */
    static void Usage (char const *Name)
    {
       fprintf (stderr, 
                "\n\n%c\n"
                "Ce programme peut avoir un parametre :\n"
                "Appel : %s [-f commandname]\n"
                "Commandname : le nom (avec chemin complet) d'un script ou\n"
                "              d'un programme qui sera appelle lorsque la touche\n"
                "              ScrollLock sera appuyee\n"
                "Sinon on appellera l'action par defaut.\n%c",
                toascii (7), Name, toascii (7));
    }
     
    /* 
     * Finish
     */
    static void Finish (void)
    {
       XCloseDisplay (display);
    }
     
    /*
     * Hierarchie
     */
    static void Hierarchie (Window racine)
    {
       Window w1, child; 
       Window *children = NULL;
       unsigned nchildren;
     
       XQueryTree (display, racine, &w1, &child, &children, &nchildren);
       if (nchildren > 0)
       {
          unsigned i;
          for (i = 0; i < nchildren; i++)
             Hierarchie (children[i]);
     
          XFree (children), children = NULL;
       }
     
       XSelectInput (display, racine, KeyReleaseMask | SubstructureNotifyMask);
    }
     
    /*
     * Main
     */
    int main (int argc, char **argv)
    {
       Window root;
       KeySym Symbol, ScrollLock = (KeySym) -1;
       XKeyEvent *Eve = NULL;
       XMapEvent *Map = NULL;
       XEvent event;
       XKeyboardControl kbd;
       XKeyboardState kst;
       int n, x = 0;
       char Chaine[5], Command[500], a;
     
    /*
       --- Initialisations
     */
       for (n = 1; n < argc; n++)
          if (strcasecmp (argv[n], "-f") == 0)
          {
             if (n != (argc - 1))
                x = n;
             else
                x = -1;
     
             break;
          }
     
       if (x < 0 || ( (x == 0) && (argc > 1) ))
       {
          Usage (argv[0]);
          return 1;
       }
     
       if (x > 0)
          sprintf (Command, "%s &", argv[x + 1]);
       else
          strcpy (Command, "");
     
       atexit (Finish);
       display = XOpenDisplay ("");
     
    /*
       --- Selection de l'input
     */
       n = ScreenCount (display);
       for (x = 0; x < n; x++)
       {
          root = XRootWindow (display, x);
          Hierarchie (root);
       }
     
    /*
       --- Recuperation du symbole ScrollLock
     */
       ScrollLock = XStringToKeysym ("Scroll_Lock");
     
       kbd.led = 3;
       XGetKeyboardControl (display, &kst);
       a = (char) kst.led_mask;
       kbd.led_mode = (a << 2);
     
    /*
       --- Boucle infinie de lecture des evenements
     */
       while (1)
       {
          XNextEvent (display, &event);
     
          switch (event.type)
          {
             /* Le vrai evenement a surveiller */
             case KeyRelease:
                Eve = (XKeyEvent *) & event;
                memset (Chaine, '\0', 5);
                XLookupString (Eve, Chaine, 4, &Symbol, NULL);
     
                if (Symbol == ScrollLock)
                {
                   if (kbd.led_mode == LedModeOn)
                      kbd.led_mode = LedModeOff;
                   else
                      kbd.led_mode = LedModeOn;
     
                   if (strlen (Command) == 0)
                      XChangeKeyboardControl (display, KBLedMode, &kbd);
                   else
                   {
                      system (Command);
                   }
                }
                break;
     
                /* En cas de creation de fenetre, on a besoin de selectionner */
                /* l'evenement sur cette fenetre et ses descendants */
     
             case MapNotify:
                Map = (XMapEvent *) & event;
                Hierarchie (Map->window);
                break;
     
             default:
                break;
          }
       }
     
       Finish ();
       return 0;
    }
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    ok pour qu'il affiche usage il faudrait l'appeller avec -n à la fin (j'ai effectivement oublié de rajouter le cas d'un '?' ou -i.. Je le rajoute dans le post).

    Ce qu'il fait c'est qu'il tourne en permanence, et , quand l'utilisateur appuie sur la touche ScrollLock d'un clavier , il appelle eventuellement un script ou un programme passé comme argument. Si il n'y a oas de programme passé en argument, il change la LED correspondante.

    Pour ce faire il fait son select et écoute sur toutes les fenêtres de tous les espaces de travail du bureau .
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  8. #8
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Ok merci, j'ai modifié mon source en conséquence.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut
    non. Ecouter est toujours possible..
    Ok si écouter est toujours possible, est-ce que générer un clic l'est aussi ?
    (en utilisant XSendEvent(...) par ex) ?

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    absolument..

    ca ne veut pas dire qu'il sera entendu.. Il faut que la fenetre a qui c'est envoye l'ecoute..

    Mais c'est le principe du dialogue entre le Xserveur et les applis, de meme qu'entre des applis du style xtalk...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut
    Ok, j'ai regardé tout ça d'un peu plus prêt.

    Mais si par exemple je veux faire un programme qui écoute les clics souris reçus par une fenetre (qui ne fais pas partie de mon programme) je ne pense pas que celà soit possible.
    Il faudrait récupérer le "Display" de la fenêtre en question et effectuer en continu un "XPeekEvent" (et non pa XNextEvent pour ne pas supprimer l'évènement de la file) pour voir si un des évènements n'est pas de type "ButtonPress".
    Je pense que c'est irréalisable en pratique mais je ne vois vraiment pas d'autres façons de faire.

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    si la fenêtre est sur le même écran, elle a le même Display..

    Oui c'est possible (dans mon exemple j'écoute toutes les fenêtres de tous les espaces de travail du DeskTop)

    Pour le NextEvent, c'est pas grave.. Suffir de faire un XDispatchEvent ensuite. (à condition de stocker l'id pour par le retraiter en boucle infinie)

    Sinon oui un Peek, ou un PeekIf...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 26
    Points : 18
    Points
    18
    Par défaut
    Ok j'ai testé... mais chez moi ça ne passe toujours pas.

    Voilà le programme que j'ai fait pour écouter les clics souris d'une fenetre donnée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    /*
       Simple Xlib application drawing a box in a window.
     */
     
    #include <X11/Xlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
     
     int main() {
        Display *d;
        int s;
        Window w;
        XEvent e;
     
        /* open connection with the server */
        d=XOpenDisplay(NULL);
        if(d==NULL) {
            printf("Cannot open display\n");
            exit(1);
        }
        s=DefaultScreen(d);
     
        Window ecoute;
     
        printf("id de la fenetre que vous voulez ecouter\n");
        scanf("%d",&ecoute);
        XSelectInput(d, ecoute,ButtonPressMask );
     
     
        /* event loop */
        while(true)
        {
            XPeekEvent(d,&e);
            if(e.type==ButtonPress)
            {
                printf("click souris !!!\n");
            }
        }
     
        /* close connection to server */
        XCloseDisplay(d);
     
        return 0;
     }
    Pour récupérer les identifiants de fenetre, j'ai fait le programme suivant (qui affiche l'id de la fenetre qui a le focus).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <X11/Xlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
     
     int main() {
        Display *d;
        int s;
        Window w;
        XEvent e;
     
        /* open connection with the server */
        d=XOpenDisplay(NULL);
        if(d==NULL) {
            printf("Cannot open display\n");
            exit(1);
        }
        s=DefaultScreen(d);
     
     
     
     
     
        Window focus_return,focus_courant;
        int revert_to_return;
     
        focus_return=focus_courant;
     
        /* event loop */
        while(true)
        {
            sleep(1);
            XGetInputFocus(d, &focus_courant,&revert_to_return);
            if(focus_courant!=focus_return)
            {
                printf("fenetre qui a le focus : %d\n",focus_courant);
                focus_return=focus_courant;
            }
        }
     
        /* close connection to server */
        XCloseDisplay(d);
     
        return 0;
     }


    Cependant, dès que le premier programme execute le "XPeekEvent(d,&e)", j'ai la jolie erreur suivante...
    X Error of failed request: BadAccess (attempt to access private resource denied)
    Major opcode of failed request: 2 (X_ChangeWindowAttributes)
    Serial number of failed request: 7
    Current serial number in output stream: 7

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 8
    Points : 9
    Points
    9
    Par défaut
    Bonjour à tous (et re-bonjour souviron34).

    J'arrive encore un peu après la bataille, mais je souhaiterais récupérer des événements tout à fait de la même manière que vous le faites ici, en gros pour empêcher la fenêtre d'une certaine application de repasser par dessus la mienne. J'ai donc la réponse à pas mal de questions dans cette discussion, à part une: comment récupère-t-on l'id d'une fenêtre à partir de son nom?
    Sinon y a-t-il un autre moyen de récupérer la fenêtre d'une application dont on connait aussi le nom?

    Merci d'avance,
    Ssspiralle

  15. #15
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    il y a plusieurs moyens..

    Avec X tout court, c'est relativement plus complexe. Si tu te sers de la Toolkit, ou d'un outil comme Motif ou autres bibliothèques de widgets, il y a des fonctions toutes faites.

    Aussi, pour garder la fenêtre au dessus, il y a aussi des différences suivant qu'on fonctionne en X simple ou avec la Toolkit ou des bibliothèques de Widgets..

    Pour X pur, tu peux sélectionner les ConfigureEvent (ou Expose). Expose sera envoyé (mais il est aussi envoyé pour juste le fait qu'un menu s'ouvre ou des choses comme ça).

    Configure sera envoyé si l'ordre des fenêtres change dans la pile. Dans ce cas, si tu vois la fenêtre non désirée passer par dessus, tu peux faire un MapRaised ...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 8
    Points : 9
    Points
    9
    Par défaut
    Merci encore souviron34!

    En fait, je peux utiliser indifféremment Xlib, Xt ou Motif.


    Ce à quoi j'avais pensé, c'est récupérer l'événement Expose de la fenêtre de l'autre appli (mais j'essaierai peut-être aussi avec Configure s'il y a trop d'Expose) avec un XselectInput, puis quand cet événement a lieu repasser ma fenêtre au premier plan.

    Mais j'ai un problème:
    Une fois que j'ai demandé à ma fenetre de récupérer les événements de l'autre fenêtre, je ne sais pas comment associer une réaction à cet événement. Je ne peux pas faire comme dans ton exemple où il y a une boucle qui ne fait que ca, puisqu'il s'agit d'un programme destiné à autre chose. Je voulais donc ajouter une réaction (callback? Action?) au niveau de Xt (type XtAddCallback), mais je ne sais pas comment faire, puisqu'il n'y a pas d'équivalent de XmNactivateCallback qui corresponde à mon événement. De plus je ne sais pas comment reconnaitre que cet événement vient d'une autre window: est-ce que le event.window qui est dans l'événement est bien la window de mon autre appli qui a causé l'événement?

    Par ailleurs, j'ai fait un test avec une boucle infinie comme la vôtre avec le XSelectInput, je vois bien les événements correspondant au masque VisibilityChangeMask ou EnterWindowMask, par contre je ne reçois rien quand je choisis le ExposureMask, tant que je ne modifie pas la taille de ma fenetre... Est-on bien sensé recevoir un Exposure event dès qu'une partie de la fenêtre précédemment invisible devient visible?

    Merci d'avance!
    Ssspiralle

  17. #17
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    pour les événements c'est un XtEventHandler :



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          XtAddEventHandler ( Ma_Drawable, 
    		         KeyReleaseMask , False,
    		         (XtEventHandler) ReadKeyboardEH, 
    		         (XtPointer)&Ma_DataStruct);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    /*
     *  R e a d K e y b o a r d E H
     *
     */
    static void ReadKeyboardEH ( Widget w, XtPointer *cdata,
    			     XEvent *sevent, Boolean *cont )
    {
       Ma_Struct_Data *idata = (Ma_StructData*)cdata ;
       KeySym	 Symbol ;
       XKeyEvent    *Eve=(XKeyEvent *)NULL ;
       char          Chaine[5] ;
       static KeySym   Left=-1, Right, Down, Up, Alt ;
       int           n ;
     
    /*
    --- Translates the key event
    */
       Eve = (XKeyEvent *)sevent ;
     
    /*
    --- If it is the first time we are called, go and gets values for the arrow keys
    */
       if ( Left == -1 )
         {
            Left = XStringToKeysym ("Left");
            Right = XStringToKeysym ("Right");
            Up = XStringToKeysym ("Up");
            Down = XStringToKeysym ("Down");
            Alt = XStringToKeysym ("Alt");
         }
     
       memset ( Chaine, '\0', 5 ) ;
       XLookupString ( Eve, Chaine, 4, &Symbol, NULL );
     
    /*
       if ( (Symbol == Left) || (Symbol == Right) || 
    	(Symbol == Down) || (Symbol == Up) )
           Appelle_Action_Sur_Fleche ( idata, Symbol );
    */
     
       if ( strlen(Chaine) == 0 )
          return ;
     
       fprintf ( stderr, "\Caractère entré : %s",Chaine);
    }
    Un ExposeEvent sera généré chaque fois qu'une fenêtre(au sens X, un rectangle de l'écran) devient partiellement visible (un menu qui disparait, une fenêtre qui vient se superposer et disparait, etc)..

    Pour l'attribut Motif à mettre pour que la fenêtre reste toujours au dessus, il me semble que ça a à voir avec quelque chose comme "sticky".. Je vais aller vérifier..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  18. #18
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    au fait, pour récupérer le nom, il me semble avec la Toolkit que c'est XtName et, combiné avec XtWindowToWidget ou XtWindow, tu peux récupérer le nom du Widget ou de la fenêtre..


    Pour X, il y a un Atom WM_NAME..


    Aussi, si tu veux que ta fenêtre reste au dessus, il suffirait de sélectionner un des événements CirculateNotify, ConfigureNotify, VisibilityNotify, ou LeaveWindow, et tester par rapport à l'état renvoyé. Si elle est partiellement cachée, il suffit de réappeler Raise...

    Ou si c'est l'autre fenêtre (identifiée) que tu veux absolument garder en dessous, il suffit de regarder les mêms événements et de appeler Lower si elle est "poppée" par dessus..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 8
    Points : 9
    Points
    9
    Par défaut
    Oki merci, je vais pouvoir tenter une version avec nom de fenêtre et boucle à la Xt.

    Par contre pour les événements, j'en ai essayé un petit paquet, et le comportement ressemble à ce que je veux quand je réagis aux FocusIn, sauf qu'il faut que l'utilisateur garde enfoncée la souris un certain temps sur la barre de la fenêtre pour que ca marche (le même que pour commencer à la déplacer (j'utilise mwm))... Si je rajoute l'événement VisibilityNotify, c'est pas mal, ca règle ce problème mais par contre la fenêtre de mon appli apparait un peu trop souvent (par exemple quand on met une fenêtre d'un troisième programme complètement par dessus), ce qui en l'occurrence correspond au comportement annoncé...

    Par contre ce que je fais c'est que sur réception de l'événement, je Raise la fenêtre PUIS que je lui rend le focus (XSetInputFocus), et malgré l'ordre, ça crash quand j'iconifie la fenêtre de mon appli (celle qui reste au dessus) au moment où elle couvrait l'autre, comme si je donnais l'input à une fenêtre iconifiée (BadMatch). Je vais certainement ne faire le XSetInputFocus que si le WM_STATE de ma fenêtre n'est pas IconicState ou WithDrawnState (mais ca a l'air pas évident d'utiliser XGetWindowProperty!).

    Sinon l'événement qui ne fait vraiment pas ce que j'aurais pensé, c'est CirculateNotify, qui pourtant semble être exactement ce qu'il me faut dans la théorie, mais qui dans la pratique n'apparaît jamais...Mais je travaille sur un cygwin, je vais essayer de voir si ca ne marche pas mieux sur une vrai machine.

    Encore merci pour tout!
    Ssspiralle

  20. #20
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 8
    Points : 9
    Points
    9
    Par défaut
    Par contre je regarde le XtAddEventHandler, et j'ai l'impression qu'on ne peut choisir de réagir qu'à des masques prédéfinis (ExposureMask, ...).
    Or moi j'aimerais faire par exemple l'équivalent de ceci dans la boucle X:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    XSelectInput(display, myWindow, ...);
    XSelectInput(display, windowToKeepHidden, FocusChangeMask);
    while(1)
    {<div style="margin-left:40px">XNextEvent(display, &event);
     
    if (event.type == FocusIn && event.xfocus.window == windowToKeepHidden)
    {<div style="margin-left:40px">XMapRaised(display, myWindow);
    XSetInputFocus(display, myWindow);</div>}
    ....</div>}
    car je ne veux pas que la fenêtre soit Raisée () quand je récupère le message indiquant mon propre focusIn, sinon je suppose que je finis en boucle, et de plus je ne veux pas des événements FocusOut, qui viennent avec dans le FocusChangeMask. Y a-t-il un moyen de créer un nouveau mask?

Discussions similaires

  1. Touche du clavier + Clic souris en même temps
    Par As2piK dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 08/12/2010, 12h44
  2. Recuperer coordonnees lors d'un clic souris win32
    Par fayred dans le forum Windows
    Réponses: 3
    Dernier message: 18/10/2007, 18h40
  3. Recuperer coord du point du clic souris
    Par LotfiB dans le forum OpenGL
    Réponses: 7
    Dernier message: 27/02/2007, 10h20
  4. Emulation de clic souris / touche clavier
    Par Gogoye dans le forum Windows
    Réponses: 3
    Dernier message: 08/09/2005, 14h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo