static void rfb_processevent(struct rfb_Display *mod) { TAPTR TExecBase = TGetExecBase(mod); TIMSG *msg; if (mod->rfb_RndIMsgPort == TNULL) return; while ((msg = TGetMsg(mod->rfb_RndIMsgPort))) { /*struct rfb_Window *v = (struct rfb_Window *) msg->timsg_Instance; */ TIMSG *imsg; switch (msg->timsg_Type) { case TITYPE_INTERVAL: TDBPRINTF(TDB_WARN, ("unhandled event: INTERVAL\n")); break; case TITYPE_REFRESH: { TINT drect[4]; drect[0] = msg->timsg_X; drect[1] = msg->timsg_Y; drect[2] = msg->timsg_X + msg->timsg_Width - 1; drect[3] = msg->timsg_Y + msg->timsg_Height - 1; rfb_damage(mod, drect, TNULL); rfb_flush_clients(mod, TTRUE); break; } case TITYPE_NEWSIZE: if ((mod->rfb_Flags & RFBFL_BUFFER_OWNER) && (mod->rfb_Flags & RFBFL_BUFFER_CAN_RESIZE)) { region_free(&mod->rfb_RectPool, &mod->rfb_DirtyRegion); mod->rfb_Flags &= ~RFBFL_DIRTY; TINT neww = mod->rfb_Width = msg->timsg_Width; TINT newh = mod->rfb_Height = msg->timsg_Height; TUINT pixfmt = mod->rfb_PixBuf.tpb_Format; TUINT bpp = TVPIXFMT_BYTES_PER_PIXEL(pixfmt); TUINT bpl = bpp * neww; struct TVPixBuf newbuf; newbuf.tpb_BytesPerLine = bpl; newbuf.tpb_Format = mod->rfb_PixBuf.tpb_Format; newbuf.tpb_Data = TAlloc(mod->rfb_MemMgr, bpl * newh); if (newbuf.tpb_Data == TNULL) break; struct TNode *next, *node = mod->rfb_VisualList.tlh_Head.tln_Succ; for (; (next = node->tln_Succ); node = next) { struct rfb_Window *v = (struct rfb_Window *) node; rfb_setrealcliprect(mod, v); TINT w0 = REGION_RECT_WIDTH(&v->rfbw_ScreenRect); TINT h0 = REGION_RECT_HEIGHT(&v->rfbw_ScreenRect); if ((v->rfbw_Flags & RFBWFL_FULLSCREEN)) { v->rfbw_ScreenRect.r[0] = 0; v->rfbw_ScreenRect.r[1] = 0; v->rfbw_ScreenRect.r[2] = neww - 1; v->rfbw_ScreenRect.r[3] = newh - 1; } TINT ww = REGION_RECT_WIDTH(&v->rfbw_ScreenRect); TINT wh = REGION_RECT_HEIGHT(&v->rfbw_ScreenRect); if (v->rfbw_MinWidth > 0 && ww < v->rfbw_MinWidth) v->rfbw_ScreenRect.r[0] = v->rfbw_ScreenRect.r[2] - v->rfbw_MinWidth; if (v->rfbw_MinHeight > 0 && wh < v->rfbw_MinHeight) v->rfbw_ScreenRect.r[1] = v->rfbw_ScreenRect.r[3] - v->rfbw_MinHeight; ww = REGION_RECT_WIDTH(&v->rfbw_ScreenRect); wh = REGION_RECT_HEIGHT(&v->rfbw_ScreenRect); if (v->rfbw_Flags & RFBWFL_BACKBUFFER) rfb_resizewinbuffer(mod, v, w0, h0, ww, wh); else v->rfbw_PixBuf = newbuf; rfb_setwinrect(mod, v); if (ww != w0 || wh != h0) { if (rfb_getimsg(mod, v, &imsg, TITYPE_NEWSIZE)) { imsg->timsg_Width = ww; imsg->timsg_Height = wh; TPutMsg(v->rfbw_IMsgPort, TNULL, imsg); } } } TFree(mod->rfb_PixBuf.tpb_Data); mod->rfb_PixBuf = newbuf; struct Rect drect; REGION_RECT_SET(&drect, 0, 0, neww - 1, newh - 1); rfb_damage(mod, drect.r, TNULL); } else TDBPRINTF(TDB_WARN, ("Cannot resize this framebuffer\n")); break; case TITYPE_CLOSE: { /* send to root window */ TLock(mod->rfb_InstanceLock); struct rfb_Window *v = (struct rfb_Window *) TLASTNODE(&mod->rfb_VisualList); if (rfb_getimsg(mod, v, &imsg, TITYPE_CLOSE)) TPutMsg(v->rfbw_IMsgPort, TNULL, imsg); TUnlock(mod->rfb_InstanceLock); break; } case TITYPE_FOCUS: TDBPRINTF(TDB_INFO, ("unhandled event: FOCUS\n")); break; case TITYPE_MOUSEOVER: TDBPRINTF(TDB_INFO, ("unhandled event: MOUSEOVER\n")); break; case TITYPE_KEYUP: case TITYPE_KEYDOWN: rfb_passevent_keyboard(mod, msg); break; case TITYPE_MOUSEMOVE: rfb_passevent_mousemove(mod, msg); break; case TITYPE_MOUSEBUTTON: rfb_passevent_mousebutton(mod, msg); break; } TReplyMsg(msg); } }
static void rfb_processevent(RFBDISPLAY *mod) { TAPTR TExecBase = TGetExecBase(mod); TIMSG *msg; if (mod->rfb_RndIMsgPort == TNULL) return; while ((msg = TGetMsg(mod->rfb_RndIMsgPort))) { /*RFBWINDOW *v = (RFBWINDOW *) msg->timsg_Instance;*/ TIMSG *imsg; switch (msg->timsg_Type) { case TITYPE_INTERVAL: TDBPRINTF(TDB_WARN,("unhandled event: INTERVAL\n")); break; case TITYPE_REFRESH: { TINT drect[4]; drect[0] = msg->timsg_X; drect[1] = msg->timsg_Y; drect[2] = msg->timsg_X + msg->timsg_Width - 1; drect[3] = msg->timsg_Y + msg->timsg_Height - 1; rfb_damage(mod, drect, TNULL); break; } case TITYPE_NEWSIZE: TDBPRINTF(TDB_WARN,("unhandled event: NEWSIZE\n")); break; case TITYPE_CLOSE: { /* send to root window */ TLock(mod->rfb_InstanceLock); RFBWINDOW *v = (RFBWINDOW *) TLASTNODE(&mod->rfb_VisualList); if (rfb_getimsg(mod, v, &imsg, TITYPE_CLOSE)) TPutMsg(v->rfbw_IMsgPort, TNULL, imsg); TUnlock(mod->rfb_InstanceLock); break; } case TITYPE_FOCUS: TDBPRINTF(TDB_INFO,("unhandled event: FOCUS\n")); break; case TITYPE_MOUSEOVER: TDBPRINTF(TDB_INFO,("unhandled event: MOUSEOVER\n")); break; case TITYPE_KEYUP: case TITYPE_KEYDOWN: /* pass keyboard events to focused window, else to the * hovered window (also setting the focus): */ if (!rfb_passevent_to_focus(mod, msg)) rfb_passevent_by_mousexy(mod, msg, TTRUE); break; case TITYPE_MOUSEMOVE: /* pass mouse movements to focused and hovered window: */ if (rfb_passevent_by_mousexy(mod, msg, TFALSE) != mod->rfb_FocusWindow) rfb_passevent_to_focus(mod, msg); break; case TITYPE_MOUSEBUTTON: { /* set focus on mousebutton down */ TBOOL focus = msg->timsg_Code & (TMBCODE_LEFTDOWN | TMBCODE_RIGHTDOWN | TMBCODE_MIDDLEDOWN); rfb_passevent_by_mousexy(mod, msg, focus); break; } } TReplyMsg(msg); } }
LOCAL TBOOL fbp_copyarea_int(struct rfb_Display *mod, struct rfb_Window *v, TINT dx, TINT dy, TINT *dr) { struct RectPool *pool = &mod->rfb_RectPool; struct Region R; if (!rfb_getlayermask(mod, &R, dr, v, 0, 0)) return TFALSE; if (R.rg_Rects.rl_NumNodes == 0) { region_free(pool, &R); return TFALSE; } TINT yinc = dy < 0 ? -1 : 1; TINT y, i, h; TINT dy0 = dr[1]; TINT dy1 = dr[3]; h = dy1 - dy0 + 1; if (yinc > 0) { TINT t = dy0; dy0 = dy1; dy1 = t; } TINT bpp = TVPIXFMT_BYTES_PER_PIXEL(v->rfbw_PixBuf.tpb_Format); if (R.rg_Rects.rl_NumNodes == 1) { /* optimization for a single rectangle */ struct RectNode *rn = (struct RectNode *) TFIRSTNODE(&R.rg_Rects.rl_List); TINT x0 = rn->rn_Rect[0]; TINT y0 = rn->rn_Rect[1]; TINT x1 = rn->rn_Rect[2]; TINT y1 = rn->rn_Rect[3]; h = y1 - y0 + 1; dy0 = y0; dy1 = y1; if (yinc > 0) { TINT t = dy0; dy0 = dy1; dy1 = t; } #if defined(ENABLE_VNCSERVER) if (mod->rfb_VNCTask && !(v->rfbw_Flags & RFBWFL_BACKBUFFER)) rfb_vnc_copyrect(mod, v, dx, dy, x0, y0, x1, y1, yinc); else #endif { /* update own buffer */ for (i = 0, y = dy0; i < h; ++i, y -= yinc) CopyLineOver(v, x0 - dx, y - dy, x0, y, (x1 - x0 + 1) * bpp); } /* update sub device */ TINT d[4]; d[0] = rn->rn_Rect[0]; d[1] = rn->rn_Rect[1]; d[2] = rn->rn_Rect[2]; d[3] = rn->rn_Rect[3]; if (v->rfbw_Flags & RFBWFL_BACKBUFFER) rfb_markdirty(mod, v, d); else rfb_copyrect_sub(mod, d, dx, dy); } else { struct TNode *n; struct TList r, t; TInitList(&r); TInitList(&t); while ((n = TRemHead(&R.rg_Rects.rl_List))) TAddTail(&r, n); for (i = 0, y = dy0; i < h; ++i, y -= yinc) { struct TNode *rnext, *rnode = r.tlh_Head.tln_Succ; for (; (rnext = rnode->tln_Succ); rnode = rnext) { struct RectNode *rn = (struct RectNode *) rnode; if (y >= rn->rn_Rect[1] && y <= rn->rn_Rect[3]) { struct TNode *prednode = TNULL; struct TNode *tnext, *tnode = t.tlh_Head.tln_Succ; for (; (tnext = tnode->tln_Succ); tnode = tnext) { struct RectNode *tn = (struct RectNode *) tnode; if (rn->rn_Rect[2] < tn->rn_Rect[0]) break; prednode = tnode; } TRemove(rnode); TInsert(&t, rnode, prednode); /* insert after prednode */ } } while (!TISLISTEMPTY(&t)) { TINT x0, x1; if (dx < 0) { struct RectNode *E = (struct RectNode *) TRemHead(&t); x0 = E->rn_Rect[0]; x1 = E->rn_Rect[2]; TAddTail(&r, &E->rn_Node); while (!TISLISTEMPTY(&t)) { struct RectNode *N = (struct RectNode *) TFIRSTNODE(&t); if (N->rn_Rect[0] == x1 + 1) { x1 = N->rn_Rect[2]; TAddTail(&r, TRemHead(&t)); continue; } break; } } else { struct RectNode *E = (struct RectNode *) TRemTail(&t); x0 = E->rn_Rect[0]; x1 = E->rn_Rect[2]; TAddTail(&r, &E->rn_Node); while (!TISLISTEMPTY(&t)) { struct RectNode *N = (struct RectNode *) TLASTNODE(&t); if (N->rn_Rect[2] == x0 - 1) { x0 = N->rn_Rect[0]; TAddTail(&r, TRemTail(&t)); continue; } break; } } CopyLineOver(v, x0 - dx, y - dy, x0, y, (x1 - x0 + 1) * bpp); } } while ((n = TRemHead(&r))) { struct RectNode *rn = (struct RectNode *) n; /* this would be incorrect, unfortunately: */ /* rfb_copyrect_sub(mod, rn->rn_Rect, dx, dy); */ rfb_markdirty(mod, v, rn->rn_Rect); TAddTail(&R.rg_Rects.rl_List, n); } } region_free(pool, &R); return TTRUE; /* do expose */ }