LOCAL void fbp_doexpose(struct rfb_Display *mod, struct rfb_Window *v, struct Region *L, struct THook *exposehook) { TINT wx = v->rfbw_WinRect.r[0]; TINT wy = v->rfbw_WinRect.r[1]; struct TNode *next, *node = L->rg_Rects.rl_List.tlh_Head.tln_Succ; for (; (next = node->tln_Succ); node = next) { struct RectNode *rn = (struct RectNode *) node; TINT *r = rn->rn_Rect; r[0] -= wx; r[1] -= wy; r[2] -= wx; r[3] -= wy; TCallHookPkt(exposehook, v, (TTAG) r); } }
LOCAL void fb_copyarea(WINDISPLAY *mod, struct TVRequest *req) { WINWINDOW *win = req->tvr_Op.CopyArea.Window; struct THook *exposehook = (struct THook *) TGetTag(req->tvr_Op.CopyArea.Tags, TVisual_ExposeHook, TNULL); TINT *sr = req->tvr_Op.CopyArea.Rect; TINT dx = req->tvr_Op.CopyArea.DestX - sr[0]; TINT dy = req->tvr_Op.CopyArea.DestY - sr[1]; RECT r; r.left = sr[4]; r.top = sr[5]; r.right = sr[4] + sr[2]; r.bottom = sr[5] + sr[3]; if (exposehook) { RGNDATAHEADER *rdh = (RGNDATAHEADER *) win->fbv_RegionData; RECT *rd = (RECT *) (rdh + 1); HRGN updateregion = CreateRectRgn(0, 0, 0, 0); ScrollDC(win->fbv_HDC, dx, dy, &r, &r, updateregion, NULL); if (GetRegionData(updateregion, 1024, (LPRGNDATA) rdh)) { TUINT i; for (i = 0; i < rdh->nCount; ++i) TCallHookPkt(exposehook, win, (TTAG) (rd + i)); } else { TDBPRINTF(TDB_WARN,("Regiondata buffer too small\n")); InvalidateRgn(win->fbv_HWnd, updateregion, FALSE); } DeleteObject(updateregion); } else ScrollDC(win->fbv_HDC, dx, dy, &r, &r, NULL, NULL); win->fbv_Dirty = TTRUE; }
static TBOOL x11_processvisualevent(struct X11Display *mod, struct X11Window *v, TAPTR msgstate, XEvent *ev) { TAPTR TExecBase = TGetExecBase(mod); TIMSG *imsg; switch (ev->type) { case ClientMessage: if ((v->eventmask & TITYPE_CLOSE) && (Atom) ev->xclient.data.l[0] == v->atom_wm_delete_win) { if (x11_getimsg(mod, v, &imsg, TITYPE_CLOSE)) TAddTail(&v->imsgqueue, &imsg->timsg_Node); } break; case ConfigureNotify: if (mod->x11_RequestInProgress && (v->flags & X11WFL_WAIT_RESIZE)) { TReplyMsg(mod->x11_RequestInProgress); mod->x11_RequestInProgress = TNULL; v->flags &= ~X11WFL_WAIT_RESIZE; TDBPRINTF(TDB_INFO, ("Released request (ConfigureNotify)\n")); } v->winleft = ev->xconfigure.x; v->wintop = ev->xconfigure.y; if ((v->winwidth != ev->xconfigure.width || v->winheight != ev->xconfigure.height)) { v->flags |= X11WFL_WAIT_EXPOSE; v->winwidth = ev->xconfigure.width; v->winheight = ev->xconfigure.height; if (v->eventmask & TITYPE_NEWSIZE) { if (x11_getimsg(mod, v, &imsg, TITYPE_NEWSIZE)) { imsg->timsg_Width = v->winwidth; imsg->timsg_Height = v->winheight; TAddTail(&v->imsgqueue, &imsg->timsg_Node); } TDBPRINTF(TDB_TRACE, ("Configure: NEWSIZE: %d %d\n", v->winwidth, v->winheight)); } } break; case EnterNotify: case LeaveNotify: if (v->eventmask & TITYPE_MOUSEOVER) { if (x11_getimsg(mod, v, &imsg, TITYPE_MOUSEOVER)) { imsg->timsg_Code = (ev->type == EnterNotify); TAddTail(&v->imsgqueue, &imsg->timsg_Node); } } break; case MapNotify: if (mod->x11_RequestInProgress) { TReplyMsg(mod->x11_RequestInProgress); mod->x11_RequestInProgress = TNULL; v->flags |= X11WFL_WAIT_EXPOSE; TDBPRINTF(TDB_TRACE, ("Released request (MapNotify)\n")); } break; case Expose: if (v->flags & X11WFL_WAIT_EXPOSE) v->flags &= ~X11WFL_WAIT_EXPOSE; else if ((v->eventmask & TITYPE_REFRESH) && x11_getimsg(mod, v, &imsg, TITYPE_REFRESH)) { imsg->timsg_X = ev->xexpose.x; imsg->timsg_Y = ev->xexpose.y; imsg->timsg_Width = ev->xexpose.width; imsg->timsg_Height = ev->xexpose.height; TAddTail(&v->imsgqueue, &imsg->timsg_Node); TDBPRINTF(TDB_TRACE, ("Expose: REFRESH: %d %d %d %d\n", imsg->timsg_X, imsg->timsg_Y, imsg->timsg_Width, imsg->timsg_Height)); } break; case GraphicsExpose: if (mod->x11_CopyExposeHook) { TINT rect[4]; rect[0] = ev->xgraphicsexpose.x; rect[1] = ev->xgraphicsexpose.y; rect[2] = rect[0] + ev->xgraphicsexpose.width - 1; rect[3] = rect[1] + ev->xgraphicsexpose.height - 1; TCallHookPkt(mod->x11_CopyExposeHook, mod->x11_RequestInProgress->tvr_Op.CopyArea.Window, (TTAG) rect); } if (ev->xgraphicsexpose.count > 0) break; /* no more graphics expose events, fallthru: */ case NoExpose: if (mod->x11_RequestInProgress) { TReplyMsg(mod->x11_RequestInProgress); mod->x11_RequestInProgress = TNULL; mod->x11_CopyExposeHook = TNULL; TDBPRINTF(TDB_TRACE, ("Released request (NoExpose)\n")); } else TDBPRINTF(TDB_INFO, ("NoExpose: TITYPE_REFRESH not set\n")); break; case FocusIn: case FocusOut: mod->x11_KeyQual = 0; if (v->eventmask & TITYPE_FOCUS) { if (x11_getimsg(mod, v, &imsg, TITYPE_FOCUS)) { imsg->timsg_Code = (ev->type == FocusIn); TAddTail(&v->imsgqueue, &imsg->timsg_Node); } } break; case MotionNotify: { struct TNode *next, *node = mod->x11_vlist.tlh_Head.tln_Succ; x11_setmousepos(mod, v, ev->xmotion.x, ev->xmotion.y); v->mousex = mod->x11_ScreenMouseX - v->winleft; v->mousey = mod->x11_ScreenMouseY - v->wintop; for (; (next = node->tln_Succ); node = next) { struct X11Window *v = (struct X11Window *) node; if (v->eventmask & TITYPE_MOUSEMOVE && x11_getimsg(mod, v, &imsg, TITYPE_MOUSEMOVE)) TAddTail(&v->imsgqueue, &imsg->timsg_Node); } break; } case ButtonRelease: case ButtonPress: x11_setmousepos(mod, v, ev->xbutton.x, ev->xbutton.y); if (v->eventmask & TITYPE_MOUSEBUTTON) { if (x11_getimsg(mod, v, &imsg, TITYPE_MOUSEBUTTON)) { unsigned int button = ev->xbutton.button; if (ev->type == ButtonPress) { switch (button) { case Button1: imsg->timsg_Code = TMBCODE_LEFTDOWN; break; case Button2: imsg->timsg_Code = TMBCODE_MIDDLEDOWN; break; case Button3: imsg->timsg_Code = TMBCODE_RIGHTDOWN; break; case Button4: imsg->timsg_Code = TMBCODE_WHEELUP; break; case Button5: imsg->timsg_Code = TMBCODE_WHEELDOWN; break; } } else { switch (button) { case Button1: imsg->timsg_Code = TMBCODE_LEFTUP; break; case Button2: imsg->timsg_Code = TMBCODE_MIDDLEUP; break; case Button3: imsg->timsg_Code = TMBCODE_RIGHTUP; break; } } TAddTail(&v->imsgqueue, &imsg->timsg_Node); } } break; case KeyRelease: x11_processkey(mod, v, (XKeyEvent *) ev, TFALSE); break; case KeyPress: x11_processkey(mod, v, (XKeyEvent *) ev, TTRUE); break; case SelectionRequest: { XSelectionRequestEvent *req = (XSelectionRequestEvent *) ev; XEvent replyevent; XSelectionEvent *reply = &replyevent.xselection; memset(&replyevent, 0, sizeof replyevent); reply->type = SelectionNotify; reply->serial = ev->xany.send_event; reply->send_event = True; reply->display = req->display; reply->requestor = req->requestor; reply->selection = req->selection; reply->property = req->property; reply->target = None; reply->time = req->time; if (req->target == mod->x11_XA_TARGETS) { XChangeProperty(mod->x11_Display, req->requestor, req->property, XA_ATOM, 32, PropModeReplace, (unsigned char *) &mod->x11_XA_UTF8_STRING, 1); } else if (req->target == mod->x11_XA_UTF8_STRING) { XSelectionEvent *rcopy = TAlloc(TNULL, sizeof *reply); if (rcopy && x11_getimsg(mod, v, &imsg, TITYPE_REQSELECTION)) { *rcopy = *reply; imsg->timsg_Requestor = (TTAG) rcopy; imsg->timsg_Code = req->selection == mod->x11_XA_PRIMARY ? 2 : 1; TAddTail(&v->imsgqueue, &imsg->timsg_Node); break; } TFree(rcopy); } else reply->property = None; XSendEvent(mod->x11_Display, req->requestor, 0, NoEventMask, &replyevent); XSync(mod->x11_Display, False); break; } } return TFALSE; }