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 :

problème d'event sous X11/Motif


Sujet :

Linux

  1. #1
    Membre averti Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Points : 407
    Points
    407
    Par défaut problème d'event sous X11/Motif
    Bonjour,
    Je fais un portage HP-UX 11.11 vers Linux Red Hat 3.4.6 et les libs X11R6.
    j'ai un comportement différent, sur la séquence suivante, dans une drawing area :
    - click gauche, bouton maintenu appuyé
    - drag
    - bouton relaché.

    Je constate la chose suivante :
    sous HP-UX, l'action drag fait que event->xbutton.button vaut 1
    sous Linux, cela vaut 0

    Dans le code, j'ai une callback :
    XtAddCallback(drawing_a,XmNinputCallback,mycallback,arg)
    avec
    void mycallback(widget, client_data, call_data)
    Widget widget;
    XtPointer client_data;
    XtPointer call_data;
    {
    XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
    XEvent *event = cbs->event;
    ...



    Je dois dire que je patauge. Toutes suggestions seront les bienvenues.
    Merci

  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
    en quoi as-tu besoin de la VALEUR de event->xbutton.button ??

    Il y a un "mapping" avec des définitions de structure suivant le type d'évènement :

    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
    void mycallback(widget, client_data, call_data)
    Widget widget;
    XtPointer client_data;
    XtPointer call_data;
    {
    XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
    XEvent *event = cbs->event; 
    XButtonEvent   *sevent=(XButtonEvent *)call_data->event  ;
    ...
    
       if ( (event->type != ButtonPress) &&
            (event->type != ButtonRelease) ) return ;
    
       if ( sevent->type == ButtonPress )
         {
           if ( sevent->button == Button1 )
             {
             }
           else
           if ( sevent->button == Button3 )
             {
             }
         }
       else
       if ( sevent->type == ButtonRelease )
         {
           if ( sevent->button == Button1 )
             {
             }
           else
           if ( sevent->button == Button3 )
             {
             }
          }

    d'autre part l'action drag n'est pas effectuée par cette callback, mais par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       XtAddEventHandler ( drawing_a, 
    		       PointerMotionMask | ButtonMotionMask, False,
    		       (XtEventHandler)MonEventhandler, arg);
    Enfin il faudrait sans doute un peu plus de code...

    Cordialement
    "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 averti Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Points : 407
    Points
    407
    Par défaut
    Bonjour, merci d'avoir répondu.
    Tout d'abord, j'ai bien une instruction XtAddEventHandler mais elle appelle une callback qui ne contient que des instructions XClearWindow et XDrawString, donc pas de lien ici avec "mycallback".
    Je faisais le lien entre "mycallback" et l'action drag car des traces placées dans "mycallback" s'affiche lors du drag (à chaque delta de la souris).
    Si j'ai compris, event->xbutton.button donne le bouton de la souris. La callback "mycallback" en a besoin car elle traite plusieurs types d'actions et tous les boutons de la souris.
    Dans mon cas, je constate sous Linux que :
    bouton gauche appuyé : event->xbutton.button =1
    drag avec bouton gauche appuyé : event->xbutton.button =0
    bouton gauche relaché : event->xbutton.button =1
    sous HP-UX :
    bouton gauche appuyé : event->xbutton.button =1
    drag avec bouton gauche appuyé : event->xbutton.button =1
    bouton gauche relaché : event->xbutton.button =1

    Quant à l'instruction :
    XButtonEvent *sevent=(XButtonEvent *)call_data->event ;
    il y a une erreur de compil. sur event : "request for member "event" in something not a structure or union".
    Pour rappel, l'instruction qui fait appelle à la callback est :
    XtAddCallback(drawing_a,XmNinputCallback,mycallback,drawing_a)

    Cordialement

  4. #4
    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
    je répète ceci est normal puique X fournit des macros pour ne PAS avoir à référencer directement le numéro de bouton, mais s'en servir via Button1, Button3, etC... je ne pourrais donc que te conseiller au plus vite d'éliminer les références aux boutons (button->button ..) et de mettre les macros Button1 etc...

    D'autre part, le inputcallback est normalement utilisé pour le "click" (ButtonPress ou ButtonRelease). Le drag doit normalement s'effectuer avec l'event handler.

    Ensuite, je pense que c'est une très vieille version que tu as. Normalement maintenant les prototypes doivent être déclarés DANS la déclaration de la fonction (depuis une bonne quinzaine d'années) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void mycallback(Widget widget, XtPointer client_data, XtPointer call_data)
    Ce qui doit sans doute provoquer le diagnostic... Car sinon il doit falloir un flag spécial de compil pour faire admettre "sans prototype".

    Peux-tu préciser ce que dois faire cette callback ?
    (à la limite le code avec juste les événements et les ifs)
    "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

  5. #5
    Membre averti Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Points : 407
    Points
    407
    Par défaut
    Voici un extrait du code :
    main :
    drawing_a = XtVaCreateWidget( "drawing_a",
    xmDrawingAreaWidgetClass,
    mainWindow_radar,
    XmNwidth, radar_width,
    XmNheight, radar_height,
    XmNtranslations,XtParseTranslationTable(translations),
    NULL);

    XtAddCallback(drawing_a,XmNinputCallback ,zoom_get_parameters_in_radar_screen,drawing_a);
    XtAddEventHandler(drawing_a,PointerMotionMask,FALSE,ShowLatLongContinuously,NULL);
    XtAddEventHandler(drawing_a,LeaveWindowMask,FALSE,ShowLatLongContinuously,NULL);

    zoom_get_parameters_in_radar_screen:
    void zoom_get_parameters_in_radar_screen(widget,client_data,call_data)
    Widget widget;
    XtPointer client_data;
    XtPointer call_data;
    {
    XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
    XEvent *event = cbs->event;

    if (event->xbutton.button==1)
    {
    if (event->xany.type == ButtonPress)
    {
    ...
    }
    else if (event->xany.type == ButtonRelease && ZOOM_DEF_ACTIVE==1)
    {
    ...
    XSetFunction(display,gc,GXcopy);
    }
    else if (event->xany.type == MotionNotify && ZOOM_DEF_ACTIVE==1)
    {
    ...
    if (loc_width || loc_height)
    {
    XSetForeground(display,gc,red);
    XDrawRectangle( display, XtWindow(drawing_a), gc,
    loc_orig_x1, loc_orig_y1,
    loc_width, loc_height);
    }
    XmUpdateDisplay(drawing_a);
    }
    }
    }

    Désolé pour l'indentation, les tabulations ou les blancs n'ont pas l'air de passer.
    Les 2 callbacks (zoom_get_parameters_in_radar_screen et ShowLatLongContinuously) sont appelées sur l'action drag (je ne sais pas si c'est normal, mais c'est ce qui se passe : dans ShowLatLongContinuously le XDrawString peut t'il être pris pour un input auquel cas zoom_get_parameters_in_radar_screen est légitimement appelé); la valeur de event->xbutton.button vaut 0 pendant le drag alors que le bouton est appuyé (version Linux). Je vais remplacer par les macros, mais cela va t'il changer la valeur .
    Pour la "vieille version", s'agit t'il de X11 ? Je suis en X11R6 et les prototypes de mes fonctions ne prooque pas d'erreurs ni de warning (je compile avec gcc -Wall)
    Pour info, le but est de faire un zoom sur une image en faisant les actions bouton appuyé, drag, bouton relaché, afin de définir une zone rectangulaire qui devient la nouvelle zone affichée.
    Merci

  6. #6
    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 awalter1
    Désolé pour l'indentation, les tabulations ou les blancs n'ont pas l'air de passer.
    balise code (#) dans les boutons de création de message..

    Citation Envoyé par awalter1
    le XDrawString peut t'il être pris pour un input
    non

    Citation Envoyé par awalter1
    Pour la "vieille version", s'agit t'il de X11 ?
    non du code ... visiblement oui d'après les déclarations de fonctions.

    La syntaxe normale depuis longtemps est de mettre la déclaration des types de variables AU MOMENT où on déclare les variables...

    Si tout le code est comme ça, et si c'est long, tu peux continuer, mais il y a un flag de compile (je ne sais plus lequel) qui permet de garder ça. Mais si tu reprends le code, je pense que ce serait mieux que tu mettes à jour

    Pour faire ce que tu veux, le plus simple serait de :

    1) garder dans InputCallback juste ce qui se passe quand c'est ButtonRelease et ButtonPress (mettre/enlever les flags et les modes de copy)
    2) mettre le code "trace rectangle etc.." dans la MotionCallback , en testant sur le mode...
    3) garder à la fin de cette routine le ShowLatLongContinuously, en changeant le nom de la callback qu'elle soit quelque chose comme "ActionQuandPointeurBouge"..
    4) au moment du button release et si le mode est zoom, calculer le zoon

    Enfin oui je pense que remplacer par les macros te résoudra le problème de valeur du bouton, et correspondra à la norme.

    J'ai un exemple de code qui fait ça, si tu veux..
    "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

  7. #7
    Membre averti Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Points : 407
    Points
    407
    Par défaut
    Désolé pour le retard, mais j'étais passé sur autre chose.
    Je veux bien ton exemple de code.
    Merci

  8. #8
    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
    bon, je te donne l'exemple...

    J'ai très légèrement modifié, pour que ce soit un peu plus "objet" et dans l'esprit de X.

    Si tu ne comprends pas certaines choses, pose des questions, mais c'est assez simple...

    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
     
    /* Une structure minimum pour les paramètres */
    #define NO_MODE             0
    #define MODE_ROI_DEFINITION 1
    #define MODE_TRACKING       2
     
    typedef struct pMyStruct {
     
       int loc_x1 ;
       int loc_y1 ;
       int loc_x2 ;
       int loc_y2 ;
     
       int Graph_Mode ;
     
     } MyStruct ;
    Dans le main, déclarer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyStruct MaStructure ;
    Les fonctions :

    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
     
    /*
    ***
    ***** LA CALLBACK QUI FAIT LE "BUTTON DOWN" ou "BUTTON UP"
    ***
    */
    static void GraphInputCB ( Widget w, XtPointer *cdata,
                               XmDrawingAreaCallbackStruct *call_data )
    {
       MyStruct                *idata = (MyStruct*)cdata ;
       XEvent                  *event=(XEvent *)NULL ;
       XButtonEvent            *sevent=(XButtonEvent *)NULL ;
       int                      dx, dy, Margin = 2 ;
     
       if ( call_data->event == (XEvent *)NULL ) return ;
     
     
       event = (XEvent *)call_data->event ;
     
       if ( (event->type != ButtonPress) &&
            (event->type != ButtonRelease) ) return ;
     
       sevent = (XButtonEvent *)call_data->event ;
     
    /*
    ====  ON DEBUTE UNE ACTION
    */
       if ( sevent->type == ButtonPress )
         {
           if ( sevent->button == Button1 )
             {
    	   idata->Graph_Mode = MODE_TRACKING ;
             }
           else
           if ( sevent->button == Button3 )
             {
    	   idata->Graph_Mode = MODE_ROI_DEFINITION ;
     
               idata->loc_x1 = sevent->x ;
               idata->loc_y1 = sevent->y ;
               idata->loc_x2 = sevent->x ;
               idata->loc_y2 = sevent->y ;
             }
         }
       else
    /*
    ==== ON TERMINE UNE ACTION
    */
       if ( (sevent->type == ButtonRelease) && (idata->Graph_Mode != NO_MODE) )
         {
           if ( idata->Graph_Mode == MODE_ROI_DEFINITION )
             {
                 dx = idata->loc_x2 - idata->loc_x1 ;
                 dy = idata->loc_y2 - idata->loc_y1 ; 
     
                 if ( (abs(dx) <= Margin) && (abs(dy) <= Margin) )
                     Dezoom ( idata );
    	     else
                  {
                     /* Efface le dernier rectangle */
                     Draw_Rectangle ( idata, 
                                      idata->loc_x1,
                                      idata->loc_y1,
                                      idata->loc_x2,
                                      idata->loc_y2);
     
                     Zoom  ( idata,
                             idata->loc_x1,
                             idata->loc_y1,
                             idata->loc_x2,
                             idata->loc_y2);
                   }
           }
     
          idata->Graph_Mode = NO_MODE ;
        }
    }
     
     
     
     
    /*
    ***
    ***** LA CALLBACK QUI FAIT LE "MOVE" ou "DRAG"
    ***
    */
    static void GraphMoveEH ( Widget w, XtPointer *cdata,
    			  XEvent *sevent, Boolean *cont )
    {
       MyStruct           *idata = (MyStruct*)cdata ;
       int                 rx, ry, x, y, n ;
       unsigned  int       keys;
       Window              root, child;
     
     
       XQueryPointer ( xdata->GUI_Params.dpy, XtWindow(w),
    		   &root, &child, &rx, &ry, &x, &y, &keys );
     
    /*
    --- AREA SELECTION : definition of zoom or selection area 
    */
       if ( idata->Graph_Mode == MODE_ROI_DEFINITION )
         {  
           /* Efface l'ancien rectabgle */
           Draw_Rectangle ( idata,
    		       idata->loc_x1,
    		       idata->loc_y1,
    		       idata->loc_x2,
    		       idata->loc_y2);
     
           idata->loc_x2 = x ;
           idata->loc_y2 = y ;
     
           /* Trace le nouveau */       
           Draw_Rectangle ( idata,
    		       idata->loc_x1,
    		       idata->loc_y1,
    		       idata->loc_x2,
    		       idata->loc_y2);
         }
     
    /*
    --- Affiche la position
    */
       Affiche_Position (idata, x, y );
    }
    Et dans la routine où on crée les fenêtres et les actions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ......
    ...
     
       XtAddEventHandler ( drawing_a, 
                           PointerMotionMask | ButtonMotionMask, False,
                           (XtEventHandler) GraphMoveEH, (XtPointer)&MaStructure);
       XtAddCallback ( drawing_a, 
                       XmNinputCallback,(XtCallbackProc) GraphInputCB, XtPointer)&MaStructure);
    • La routine Affiche_Position appelle ta routine LatLong...
    • La routine Draw_Rectangle doit mettre le contexte graphique à XOR, puis la couleur , puis tracer le rectangle.
    • J'ai appelé une fonction Zoom, et l'autre Dezoom (si tu relâches au même endroit que tu as cliqué)


    (vraisemblablement à rajouter dans la structure le Display et le GC).
    "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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/09/2008, 11h57
  2. [Install] Problème de lancement sous debian sid
    Par SoaR245 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 18/02/2004, 10h01
  3. problème de compilation sous visual C++
    Par fabmili dans le forum MFC
    Réponses: 4
    Dernier message: 08/02/2004, 19h52
  4. Problème d'include sous Dev-c++ 4.9.8.0
    Par Argonz dans le forum Dev-C++
    Réponses: 16
    Dernier message: 20/11/2003, 17h36
  5. Problème avec CopyDir sous D5
    Par Houben Jacques dans le forum Langage
    Réponses: 3
    Dernier message: 26/05/2003, 22h02

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