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); } }
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; }
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); }
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; }
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; }
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; }