예제 #1
0
static void nxtk_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
                          uint8_t buttons, FAR void *arg)
{
  FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hwnd;
  struct nxgl_point_s abspos;
  struct nxgl_point_s relpos;

  /* Raise the window to the top if any mouse button was pressed or if auto-raise
   * is configured.  Do this before reporting the mouse event (because processing
   * of the mouse event could change the ordering again).
   */

  /* REVISIT:  This does not work correctly.  In a scenario where (1) there are
   * multiple queued touchscreen events and (2) the result of the first input
   * was to switch windows, then this autoraise implementation will cause the
   * window to revert to the previous window.  Not good behavior.
   */

#ifndef CONFIG_NX_MULTIUSER /* Queuing only happens in multi-user mode */
#ifdef CONFIG_NXTK_AUTORAISE
  if (fwnd->wnd.above != NULL)
#else
  if (buttons != 0 && fwnd->wnd.above != NULL)
#endif
    {
       nx_raise((NXWINDOW)&fwnd->wnd);
    }
#endif

  /* When we get here, the mouse position that we receive has already been
   * offset by the window origin.  Here we need to detect mouse events in
   * the various regions of the windows:  The toolbar, the client window,
   * or the frame.  And then offset the position accordingly.
   */

  /* The fwrect and tbrect boxes are both in absolute display coordinates. So
   * the easiest thing to do is to restore the mouse position to absolute
   * display coordiantes before making the comparisons and adjustments.
   */

  nxgl_vectoradd(&abspos, pos, &fwnd->wnd.bounds.pt1);

  /* Is the mouse position inside of the client window region? */

  if (fwnd->fwcb->mousein && nxgl_rectinside(&fwnd->fwrect, &abspos))
    {
      nxgl_vectsubtract(&relpos, &abspos, &fwnd->fwrect.pt1);
      fwnd->fwcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->fwarg);
    }

  /* If the mouse position inside the toobar region? */

  else if (fwnd->tbcb->mousein && nxgl_rectinside(&fwnd->tbrect, &abspos))
    {
      nxgl_vectsubtract(&relpos, &abspos, &fwnd->tbrect.pt1);
      fwnd->tbcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->tbarg);
    }
}
예제 #2
0
int nxmu_mousereport(struct nxbe_window_s *wnd)
{
  struct nxclimsg_mousein_s outmsg;

  /* Does this window support mouse callbacks? */

  if (wnd->cb->mousein)
    {
      /* Yes.. Is the mouse position visible in this window? */

      if (nxbe_visible(wnd, &g_mpos))
        {
          /* Yes... Convert the mouse position to window relative
           * coordinates and send it to the client
           */

          outmsg.msgid   = NX_CLIMSG_MOUSEIN;
          outmsg.wnd     = wnd;
          outmsg.buttons = g_mbutton;
          nxgl_vectsubtract(&outmsg.pos, &g_mpos, &wnd->bounds.pt1);

          return nxmu_sendclientwindow(wnd, &outmsg, sizeof(struct nxclimsg_mousein_s));
        }
    }

  /* No error occurred, but the mouse report was not sent */

  return 1;
}
예제 #3
0
int nxtk_setposition(NXTKWINDOW hfwnd, FAR const struct nxgl_point_s *pos)
{
  FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hfwnd;
  struct nxgl_point_s offset;
  struct nxgl_point_s newpos;

  /* Calculate the offset that is requested and add that to the window origin. */

  nxgl_vectsubtract(&offset, pos, &fwnd->fwrect.pt1);
  nxgl_vectoradd(&newpos, &offset, &fwnd->wnd.bounds.pt1);

  /* Then set that position */

  return nx_setposition((NXWINDOW)hfwnd, &newpos);
}
예제 #4
0
int nxtk_bitmapwindow(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *dest,
                      FAR const void **src,
                      FAR const struct nxgl_point_s *origin, unsigned int stride)
{
  FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hfwnd;
  struct nxgl_point_s wndorigin;
  struct nxgl_rect_s clipdest;

#ifdef CONFIG_DEBUG_FEATURES
  if (!hfwnd || !dest || !src || !origin)
    {
      set_errno(EINVAL);
      return ERROR;
    }
#endif

  /* Clip the rectangle so that it lies within the sub-window bounds
   * then move the rectangle to that it is relative to the containing
   * window.
   */

  nxtk_subwindowclip(fwnd, &clipdest, dest, &fwnd->fwrect);

  /* Now, move the bitmap origin so that it is relative to the containing
   * window, not the sub-window.
   *
   * Temporarily, position the origin in absolute screen coordinates
   */

  nxgl_vectoradd(&wndorigin, origin, &fwnd->fwrect.pt1);

  /* Then move the origin so that is relative to the containing window, not the
   * client subwindow
   */

  nxgl_vectsubtract(&wndorigin, &wndorigin, &fwnd->wnd.bounds.pt1);

  /* Then copy the bitmap */

  nx_bitmap((NXWINDOW)hfwnd, &clipdest, src, &wndorigin, stride);
  return OK;
}
예제 #5
0
int nxsu_mousereport(struct nxbe_window_s *wnd)
{
  struct nxgl_point_s relpos;

  /* Does this window support mouse callbacks? */

  if (wnd->cb->mousein)
    {
      /* Yes.. Is the mouse position visible in this window? */

      if (nxbe_visible(wnd, &g_mpos))
        {
          /* Yes... Convert the mouse position to window relative coordinates */

          nxgl_vectsubtract(&relpos, &g_mpos, &wnd->bounds.pt1);
          wnd->cb->mousein((NXWINDOW)wnd, &relpos, g_mbutton, wnd->arg);
          return OK;
        }
    }

  /* No error occurred, but the mouse report was not sent */

  return 1;
}
예제 #6
0
int nxmu_mousein(FAR struct nxfe_state_s *fe,
                 FAR const struct nxgl_point_s *pos, int buttons)
{
  struct nxbe_window_s *wnd;
  nxgl_coord_t x = pos->x;
  nxgl_coord_t y = pos->y;
  uint8_t oldbuttons;
  int ret;

  /* Clip x and y to within the bounding rectangle */

  if (x < 0)
    {
      x = 0;
    }
  else if (x >= g_mrange.x)
    {
      x = g_mrange.x - 1;
    }

  if (y < 0)
    {
      y = 0;
    }
  else if (y >= g_mrange.y)
    {
      y = g_mrange.y - 1;
    }

  /* Look any change in values */

  if (x != g_mpos.x || y != g_mpos.y || buttons != g_mbutton)
    {
      /* Update the mouse value */

      oldbuttons = g_mbutton;
      g_mpos.x   = x;
      g_mpos.y   = y;
      g_mbutton  = buttons;

      /* If a button is already down, regard this as part of a mouse drag
       * event. Pass all the following events to the window where the drag
       * started in.
       */

      if (oldbuttons && g_mwnd && g_mwnd->cb->mousein)
        {
          struct nxclimsg_mousein_s outmsg;
          outmsg.msgid   = NX_CLIMSG_MOUSEIN;
          outmsg.wnd     = g_mwnd;
          outmsg.buttons = g_mbutton;
          nxgl_vectsubtract(&outmsg.pos, &g_mpos, &g_mwnd->bounds.pt1);

          return nxmu_sendclientwindow(g_mwnd, &outmsg, sizeof(struct nxclimsg_mousein_s));
        }

      /* Pick the window to receive the mouse event.  Start with the top
       * window and go down.  Stop with the first window that gets the mouse
       * report
       */

      for (wnd = fe->be.topwnd; wnd; wnd = wnd->below)
        {
          /* The background window normally has no callback structure (unless
           * a client has taken control of the background via nx_requestbkgd()).
           */

          if (wnd->cb)
            {
              ret = nxmu_mousereport(wnd);
              if (ret == 0)
                {
                  break;
                }
            }
        }

      g_mwnd = wnd;
    }

  return OK;
}