Menu

#36 Mouse co-ordinates in Fortran

None
closed
nobody
5
2019-06-03
2015-09-26
B Thomas
No

Is there a way to obtain the co-ordinates of mouse clicks and distinguish between different mouse buttons in Fortran ? Kindly do consider this feature. This will make PLplot a complete replacement of the PGplot for Fortran.

Discussion

  • GregJung

    GregJung - 2015-10-03

    Cursor input is not a big aspect of the plplot drivers; a left-button-down and character input events are the extent of what wingcc, xwin.c (the windows and x-windows driver routines) care about.

    To get the control you want you can do direct Xlib calls as shown from {GDL-sourceforge}/gdlxstream.cpp:

    //simple GetGin that reproduces IDL's own.
    //However, trapping controlC should be done inside, to clean properly.

    bool GDLXStream::GetGin(PLGraphicsIn *gin, int mode) {
    
      enum CursorOpt {
        NOWAIT = 0,
        WAIT, //1
        CHANGE, //2
        DOWN, //3
        UP //4
      };
      XwDev *dev = (XwDev *) pls->dev;
      XwDisplay *xwd = (XwDisplay *) dev->xwd;
      Window root, child;
      int root_x, root_y, oldx, oldy;
      unsigned int ostate;
      XQueryPointer(xwd->display, dev->window, &root, &child,
              &root_x, &root_y, &oldx, &oldy, &ostate);
      gin->pX = oldx;
      gin->pY = dev->height - oldy;
      gin->state = ostate;
      gin->dX = (PLFLT) gin->pX / (dev->width - 1);
      gin->dY = (PLFLT) gin->pY / (dev->height - 1);
      gin->string[0] = '\0';
      gin->keysym = 0x20;
      gin->button = 0;
      if (ostate & Button1Mask) gin->button = 1;
      if (ostate & Button2Mask) gin->button = 2;
      if (ostate & Button3Mask) gin->button = 3;
      if (ostate & Button4Mask) gin->button = 4;
      if (ostate & Button5Mask) gin->button = 5; //IDL does not support buttons 4-5 but we may?
      //return if NOWAIT
      setFocus(false);  // first try to get out of focus.
      if (mode == NOWAIT) return true;
    
      unsigned long event_mask = (PointerMotionMask|ButtonMotionMask);
      switch (mode) {
        case WAIT:
          if (gin->button > 0) return true; //else wait below for a down...
        case DOWN:
          event_mask |= ButtonPressMask;
          break;
        case UP:
        case CHANGE:
          event_mask |= (ButtonPressMask | ButtonReleaseMask);
      }
    
      XEvent event;
      XRaiseWindow(xwd->display, dev->window);
      XSelectInput(xwd->display, dev->window, event_mask);
      XSync(xwd->display, true);  //useful?
      while (1) {
        XWindowEvent(xwd->display, dev->window, event_mask, &event);
    
        switch (event.type) {
            int nchars;
            KeySym mykey;
          case ButtonRelease:
            gin->pX = event.xbutton.x;
            gin->pY = event.xbutton.y;
            gin->state = event.xbutton.state;
            gin->button = event.xbutton.button;
            gin->string[0] = '\0';
            gin->keysym = 0x20;
            if (mode==UP || mode==CHANGE) goto end;
            break;
          case ButtonPress:
            gin->pX = event.xbutton.x;
            gin->pY = event.xbutton.y;
            gin->state = event.xbutton.state;
            gin->button = event.xbutton.button;
            gin->string[0] = '\0';
            gin->keysym = 0x20;
            if (mode==WAIT || mode==DOWN || mode==CHANGE) goto end;
            break;
          case MotionNotify:
            if (mode==CHANGE) {
              gin->pX = event.xmotion.x;
              gin->pY = event.xmotion.y;
              gin->state = event.xmotion.state;
              gin->string[0] = '\0';
              gin->keysym = 0x20;
              goto end;
            }
            break;
          default:
            break;
        }
      }
    end:
      gin->pY = dev->height - gin->pY;
      gin->dX = (PLFLT) gin->pX / (dev->width - 1);
      gin->dY = (PLFLT) gin->pY / (dev->height - 1);
      return true;
    }
    

    A windows method is also to be found in the same code base, at gdlwinstream.cpp.

     

    Last edit: GregJung 2015-10-03
  • Alan W. Irwin

    Alan W. Irwin - 2019-06-03
    • status: open --> closed
    • Group: -->
     
  • Alan W. Irwin

    Alan W. Irwin - 2019-06-03

    Closed (too old).

     

Log in to post a comment.