void nxmu_requestbkgd(FAR struct nxfe_conn_s *conn, FAR struct nxbe_state_s *be, FAR const struct nx_callback_s *cb, FAR void *arg) { #ifdef CONFIG_DEBUG if (!conn || !be || !cb) { errno = EINVAL; } #endif /* Set the client's callback vtable and and replace the server * connection with the clients connection. */ be->bkgd.cb = cb; be->bkgd.arg = arg; be->bkgd.conn = conn; /* Report the size/position of the background window to the client */ nxfe_reportposition((NXWINDOW)&be->bkgd); /* Redraw the background window */ nxfe_redrawreq(&be->bkgd, &be->bkgd.bounds); /* Provide the mouse settings */ #ifdef CONFIG_NX_XYINPUT nxmu_mousereport(&be->bkgd); #endif }
int nx_constructwindow(NXHANDLE handle, NXWINDOW hwnd, FAR const struct nx_callback_s *cb, FAR void *arg) { FAR struct nxfe_state_s *fe = (FAR struct nxfe_state_s *)handle; FAR struct nxbe_window_s *wnd = (FAR struct nxbe_window_s *)hwnd; FAR struct nxbe_state_s *be = &fe->be; #ifdef CONFIG_DEBUG if (!wnd) { set_errno(EINVAL); return ERROR; } if (!fe || !cb) { kufree(wnd); errno = EINVAL; return ERROR; } #endif /* Initialize the window structure */ wnd->be = be; wnd->cb = cb; wnd->arg = arg; /* Insert the new window at the top on the display. topwnd is * never NULL (it may point only at the background window, however) */ wnd->above = NULL; wnd->below = be->topwnd; be->topwnd->above = wnd; be->topwnd = wnd; /* Report the initialize size/position of the window */ nxfe_reportposition((NXWINDOW)wnd); /* Provide the initial mouse settings */ #ifdef CONFIG_NX_XYINPUT nxsu_mousereport(wnd); #endif return OK; }
int nx_getposition(NXWINDOW hwnd) { #ifdef CONFIG_DEBUG if (!hwnd) { errno = EINVAL; return ERROR; } #endif /* This is very awkward since the requested values are available * immediately in the window structure. However, this round about way of * doing things makes the single user interface bug-for-bug compatible with * the multi-user interface. */ nxfe_reportposition((FAR struct nxbe_window_s *)hwnd); return OK; }
int nx_requestbkgd(NXHANDLE handle, FAR const struct nx_callback_s *cb, FAR void *arg) { FAR struct nxfe_state_s *fe = (FAR struct nxfe_state_s *)handle; FAR struct nxbe_state_s *be = &fe->be; #ifdef CONFIG_DEBUG if (!fe || !cb) { errno = EINVAL; return ERROR; } #endif /* Replace the NX background windo callbacks with the client's callbacks */ be->bkgd.cb = cb; be->bkgd.arg = arg; /* Report the size/position of the background window to the client */ nxfe_reportposition((NXWINDOW)&be->bkgd); /* Redraw the background window */ nxfe_redrawreq(&be->bkgd, &be->bkgd.bounds); /* Provide the mouse settings to the client */ #ifdef CONFIG_NX_XYINPUT nxsu_mousereport(&be->bkgd); #endif /* In this single-user mode, we could return the background window * handle here. However, we cannot do that in the multi-user case * because that handle is known only to the server. Instead, the * background window handle is returned to the client via a redraw * callback. So we will do the same in the single-user case for * compatibility. */ return OK; }
void nxbe_setsize(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_size_s *size) { struct nxgl_rect_s bounds; #ifdef CONFIG_DEBUG if (!wnd) { return; } #endif /* Save the before size of the window's bounding box */ nxgl_rectcopy(&bounds, &wnd->bounds); /* Add the window origin to the supplied size get the new window bounding box */ wnd->bounds.pt2.x = wnd->bounds.pt1.x + size->w - 1; wnd->bounds.pt2.y = wnd->bounds.pt1.y + size->h - 1; /* Clip the new bounding box so that lies within the background screen */ nxgl_rectintersect(&wnd->bounds, &wnd->bounds, &wnd->be->bkgd.bounds); /* We need to update the larger of the two rectangles. That will be the * union of the before and after sizes. */ nxgl_rectunion(&bounds, &bounds, &wnd->bounds); /* Report the new size/position */ nxfe_reportposition(wnd); /* Then redraw this window AND all windows below it. Having resized the * window, we may have exposed previoulsy obscured portions of windows * below this one. */ nxbe_redrawbelow(wnd->be, wnd, &bounds); }
void nxbe_setposition(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_point_s *pos) { struct nxgl_rect_s before; struct nxgl_rect_s rect; #ifdef CONFIG_DEBUG if (!wnd) { return; } #endif /* Back out the old window origin position from the bounding box */ nxgl_rectoffset(&rect, &wnd->bounds, -wnd->bounds.pt1.x, -wnd->bounds.pt1.y); /* Add the new window origin into the bounding box */ nxgl_rectcopy(&before, &wnd->bounds); nxgl_rectoffset(&wnd->bounds, &rect, pos->x, pos->y); /* Get the union of the 'before' bounding box and the 'after' bounding * this union is the region of the display that must be updated. */ nxgl_rectunion(&rect, &before, &wnd->bounds); nxgl_rectintersect(&rect, &rect, &wnd->be->bkgd.bounds); /* Report the new size/position */ nxfe_reportposition(wnd); /* Then redraw this window AND all windows below it. Having moved the * window, we may have exposed previoulsy obscured portions of windows * below this one. */ nxbe_redrawbelow(wnd->be, wnd, &rect); }
int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) { struct nxfe_state_s fe; FAR struct nxsvrmsg_s *msg; uint8_t buffer[NX_MXSVRMSGLEN]; int nbytes; int ret; /* Initialization *********************************************************/ /* Sanity checking */ #ifdef CONFIG_DEBUG if (!mqname || !dev) { errno = EINVAL; return ERROR; } #endif /* Initialize and configure the server */ ret = nxmu_setup(mqname, dev, &fe); if (ret < 0) { return ret; /* nxmu_setup sets errno */ } /* Produce the initial, background display */ nxbe_redraw(&fe.be, &fe.be.bkgd, &fe.be.bkgd.bounds); /* Message Loop ***********************************************************/ /* Then loop forever processing incoming messages */ for (;;) { /* Receive the next server message */ nbytes = mq_receive(fe.conn.crdmq, buffer, NX_MXSVRMSGLEN, 0); if (nbytes < 0) { if (errno != EINTR) { gdbg("mq_receive failed: %d\n", errno); goto errout; /* mq_receive sets errno */ } continue; } /* Dispatch the message appropriately */ DEBUGASSERT(nbytes >= sizeof(struct nxsvrmsg_s)); msg = (FAR struct nxsvrmsg_s *)buffer; gvdbg("Received opcode=%d nbytes=%d\n", msg->msgid, nbytes); switch (msg->msgid) { /* Messages sent from clients to the NX server *********************/ case NX_SVRMSG_CONNECT: /* Establish connection with new NX server client */ { FAR struct nxsvrmsg_s *connmsg = (FAR struct nxsvrmsg_s *)buffer; nxmu_connect(connmsg->conn); } break; case NX_SVRMSG_DISCONNECT: /* Tear down connection with terminating client */ { FAR struct nxsvrmsg_s *disconnmsg = (FAR struct nxsvrmsg_s *)buffer; nxmu_disconnect(disconnmsg->conn); } break; case NX_SVRMSG_OPENWINDOW: /* Create a new window */ { FAR struct nxsvrmsg_openwindow_s *openmsg = (FAR struct nxsvrmsg_openwindow_s *)buffer; nxmu_openwindow(&fe.be, openmsg->wnd); } break; case NX_SVRMSG_CLOSEWINDOW: /* Close an existing window */ { FAR struct nxsvrmsg_closewindow_s *closemsg = (FAR struct nxsvrmsg_closewindow_s *)buffer; nxbe_closewindow(closemsg->wnd); } break; case NX_SVRMSG_BLOCKED: /* Block messsages to a window */ { FAR struct nxsvrmsg_blocked_s *blocked = (FAR struct nxsvrmsg_blocked_s *)buffer; nxmu_blocked(blocked->wnd, blocked->arg); } break; case NX_SVRMSG_REQUESTBKGD: /* Give access to the background window */ { FAR struct nxsvrmsg_requestbkgd_s *rqbgmsg = (FAR struct nxsvrmsg_requestbkgd_s *)buffer; nxmu_requestbkgd(rqbgmsg->conn, &fe.be, rqbgmsg->cb, rqbgmsg->arg); } break; case NX_SVRMSG_RELEASEBKGD: /* End access to the background window */ { nxmu_releasebkgd(&fe); } break; case NX_SVRMSG_SETPOSITION: /* Change window position */ { FAR struct nxsvrmsg_setposition_s *setposmsg = (FAR struct nxsvrmsg_setposition_s *)buffer; nxbe_setposition(setposmsg->wnd, &setposmsg->pos); } break; case NX_SVRMSG_SETSIZE: /* Change window size */ { FAR struct nxsvrmsg_setsize_s *setsizemsg = (FAR struct nxsvrmsg_setsize_s *)buffer; nxbe_setsize(setsizemsg->wnd, &setsizemsg->size); } break; case NX_SVRMSG_GETPOSITION: /* Get the window size/position */ { FAR struct nxsvrmsg_getposition_s *getposmsg = (FAR struct nxsvrmsg_getposition_s *)buffer; nxfe_reportposition(getposmsg->wnd); } break; case NX_SVRMSG_RAISE: /* Move the window to the top of the display */ { FAR struct nxsvrmsg_raise_s *raisemsg = (FAR struct nxsvrmsg_raise_s *)buffer; nxbe_raise(raisemsg->wnd); } break; case NX_SVRMSG_LOWER: /* Lower the window to the bottom of the display */ { FAR struct nxsvrmsg_lower_s *lowermsg = (FAR struct nxsvrmsg_lower_s *)buffer; nxbe_lower(lowermsg->wnd); } break; case NX_SVRMSG_SETPIXEL: /* Set a single pixel in the window with a color */ { FAR struct nxsvrmsg_setpixel_s *setmsg = (FAR struct nxsvrmsg_setpixel_s *)buffer; nxbe_setpixel(setmsg->wnd, &setmsg->pos, setmsg->color); } break; case NX_SVRMSG_FILL: /* Fill a rectangular region in the window with a color */ { FAR struct nxsvrmsg_fill_s *fillmsg = (FAR struct nxsvrmsg_fill_s *)buffer; nxbe_fill(fillmsg->wnd, &fillmsg->rect, fillmsg->color); } break; case NX_SVRMSG_GETRECTANGLE: /* Get a rectangular region from the window */ { FAR struct nxsvrmsg_getrectangle_s *getmsg = (FAR struct nxsvrmsg_getrectangle_s *)buffer; nxbe_getrectangle(getmsg->wnd, &getmsg->rect, getmsg->plane, getmsg->dest, getmsg->deststride); if (getmsg->sem_done) { sem_post(getmsg->sem_done); } } break; case NX_SVRMSG_FILLTRAP: /* Fill a trapezoidal region in the window with a color */ { FAR struct nxsvrmsg_filltrapezoid_s *trapmsg = (FAR struct nxsvrmsg_filltrapezoid_s *)buffer; nxbe_filltrapezoid(trapmsg->wnd, &trapmsg->clip, &trapmsg->trap, trapmsg->color); } break; case NX_SVRMSG_MOVE: /* Move a rectangular region within the window */ { FAR struct nxsvrmsg_move_s *movemsg = (FAR struct nxsvrmsg_move_s *)buffer; nxbe_move(movemsg->wnd, &movemsg->rect, &movemsg->offset); } break; case NX_SVRMSG_BITMAP: /* Copy a rectangular bitmap into the window */ { FAR struct nxsvrmsg_bitmap_s *bmpmsg = (FAR struct nxsvrmsg_bitmap_s *)buffer; nxbe_bitmap(bmpmsg->wnd, &bmpmsg->dest, bmpmsg->src, &bmpmsg->origin, bmpmsg->stride); if (bmpmsg->sem_done) { sem_post(bmpmsg->sem_done); } } break; case NX_SVRMSG_SETBGCOLOR: /* Set the color of the background */ { FAR struct nxsvrmsg_setbgcolor_s *bgcolormsg = (FAR struct nxsvrmsg_setbgcolor_s *)buffer; /* Has the background color changed? */ if (!nxgl_colorcmp(fe.be.bgcolor, bgcolormsg->color)) { /* Yes.. fill the background */ nxgl_colorcopy(fe.be.bgcolor, bgcolormsg->color); nxbe_fill(&fe.be.bkgd, &fe.be.bkgd.bounds, bgcolormsg->color); } } break; #ifdef CONFIG_NX_XYINPUT case NX_SVRMSG_MOUSEIN: /* New mouse report from mouse client */ { FAR struct nxsvrmsg_mousein_s *mousemsg = (FAR struct nxsvrmsg_mousein_s *)buffer; nxmu_mousein(&fe, &mousemsg->pt, mousemsg->buttons); } break; #endif #ifdef CONFIG_NX_KBD case NX_SVRMSG_KBDIN: /* New keyboard report from keyboard client */ { FAR struct nxsvrmsg_kbdin_s *kbdmsg = (FAR struct nxsvrmsg_kbdin_s *)buffer; nxmu_kbdin(&fe, kbdmsg->nch, kbdmsg->ch); } break; #endif case NX_SVRMSG_REDRAWREQ: /* Request re-drawing of rectangular region */ { FAR struct nxsvrmsg_redrawreq_s *redrawmsg = (FAR struct nxsvrmsg_redrawreq_s *)buffer; nxfe_redrawreq(redrawmsg->wnd, &redrawmsg->rect); } break; /* Messages sent to the background window **************************/ case NX_CLIMSG_REDRAW: /* Re-draw the background window */ { FAR struct nxclimsg_redraw_s *redraw = (FAR struct nxclimsg_redraw_s *)buffer; DEBUGASSERT(redraw->wnd == &fe.be.bkgd); gvdbg("Re-draw background rect={(%d,%d),(%d,%d)}\n", redraw->rect.pt1.x, redraw->rect.pt1.y, redraw->rect.pt2.x, redraw->rect.pt2.y); nxbe_fill(&fe.be.bkgd, &redraw->rect, fe.be.bgcolor); } break; case NX_CLIMSG_MOUSEIN: /* Ignored */ case NX_CLIMSG_KBDIN: break; case NX_CLIMSG_CONNECTED: /* Shouldn't happen */ case NX_CLIMSG_DISCONNECTED: default: gdbg("Unrecognized command: %d\n", msg->msgid); break; } } errout: nxmu_shutdown(&fe); return OK; }