static void CALLBACK hal_timeproc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { struct TNode *node, *nnode; if (TryEnterCriticalSection(&g_hws->hsp_DevLock)) { TTIME curtime; hal_getsystime(g_hal, &curtime); node = g_hws->hsp_ReqList.tlh_Head.tln_Succ; for (; (nnode = node->tln_Succ); node = nnode) { struct TTimeRequest *tr = (struct TTimeRequest *) node; if (TCmpTime(&curtime, &tr->ttr_Data.ttr_Time) >= 0) { TRemove(node); TAddTail(&g_ReplyList, node); } } node = g_ReplyList.tlh_Head.tln_Succ; for (; (nnode = node->tln_Succ); node = nnode) { struct TTimeRequest *tr = (struct TTimeRequest *) node; TRemove(node); if (!hal_replytimereq(tr)) TAddHead(&g_ReplyList, node); } LeaveCriticalSection(&g_hws->hsp_DevLock); } }
LOCAL void dfb_closevisual(DFBDISPLAY *mod, struct TVRequest *req) { struct DFBPen *pen; TAPTR exec = TGetExecBase(mod); DFBWINDOW *v = req->tvr_Op.CloseWindow.Window; if (v == TNULL) return; TDBPRINTF(TDB_INFO,("Visual close\n")); TRemove(&v->node); if (mod->dfb_Focused == (TAPTR) v) { /* pass focus on to the next window */ DFBWINDOW *vt = (DFBWINDOW *)TFIRSTNODE(&mod->dfb_vlist); if (vt) genimsg(mod, TNULL, vt, TITYPE_FOCUS); mod->dfb_Focused = (TAPTR) vt; } if (mod->dfb_Active == (TAPTR) v) mod->dfb_Active = TNULL; while ((pen = (struct DFBPen *) TRemHead(&v->penlist))) { /* free pens */ TRemove(&pen->node); TExecFree(mod->dfb_ExecBase, pen); } v->winsurface->Release(v->winsurface); v->window->Release(v->window); mod->dfb_fm.defref--; TExecFree(exec, v); }
EXPORT TINT hal_abortio(struct THALBase *hal, struct TTimeRequest *req) { struct HALSpecific *hws = hal->hmb_Specific; TAPTR exec = hws->hsp_ExecBase; TUINT status; #ifdef USE_MMTIMER EnterCriticalSection(&hws->hsp_DevLock); status = TExecGetMsgStatus(exec, req); if (status == (TMSG_STATUS_SENT | TMSGF_QUEUED)) { /* enforce immediate expiration */ req->ttr_Data.ttr_Time.tdt_Int64 = 0; req->ttr_Req.io_Error = TIOERR_ABORTED; TRemove(&req->ttr_Req.io_Node); while (!hal_replytimereq(req)); } LeaveCriticalSection(&hws->hsp_DevLock); #else EnterCriticalSection(&hws->hsp_DevLock); status = TExecGetMsgStatus(exec, req); if (!(status & TMSGF_RETURNED)) { if (status & TMSGF_QUEUED) { /* remove from ioport */ TAPTR ioport = TExecGetUserPort(exec, hws->hsp_DevTask); TExecRemoveMsg(exec, ioport, req); } else { /* remove from reqlist */ TRemove((struct TNode *) req); TExecSignal(exec, hws->hsp_DevTask, TTASK_SIG_USER); } } else { /* already replied */ req = TNULL; } LeaveCriticalSection(&hws->hsp_DevLock); if (req) { req->ttr_Req.io_Error = TIOERR_ABORTED; TExecReplyMsg(exec, req); } #endif return 0; }
LOCAL void dfb_freepen(DFBDISPLAY *mod, struct TVRequest *req) { struct DFBPen *pen = (struct DFBPen *) req->tvr_Op.FreePen.Pen; TRemove(&pen->node); TExecFree(mod->dfb_ExecBase, pen); }
LOCAL void dfb_hostclosefont(DFBDISPLAY *mod, TAPTR font) { struct FontNode *fn = (struct FontNode *) font; TAPTR exec = TGetExecBase(mod); if (font == mod->dfb_fm.deffont) { if (mod->dfb_fm.defref) { /* prevent freeing of default font if it's */ /* still referenced */ mod->dfb_fm.defref--; return; } } /* free dfbfont */ if (fn->font) { fn->font->Release(fn->font); fn->font = TNULL; } /* remove font from openfonts list */ TRemove(&fn->handle.thn_Node); /* free fontnode itself */ TExecFree(exec, fn); }
static void fb_dowindow(TAPTR task) { struct TExecBase *TExecBase = TGetExecBase(task); WINWINDOW *win = TGetTaskData(task); WINDISPLAY *mod = win->fbv_Display; MSG msg; TUINT sig; TDBPRINTF(TDB_INFO,("DoWindow...\n")); do { WaitMessage(); while (PeekMessage(&msg, win->fbv_HWnd, 0,0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } // PostMessage(win->fbv_HWnd, WM_USER, 0, 0); sig = TSetSignal(0, TTASK_SIG_ABORT); } while (!(sig & TTASK_SIG_ABORT)); TDBPRINTF(TDB_INFO,("Window Done\n")); TLock(mod->fbd_Lock); TRemove(&win->fbv_Node); TUnlock(mod->fbd_Lock); fb_closeall(mod, win, TTRUE); }
static THOOKENTRY TTAG rfb_fqhdestroy(struct THook *hook, TAPTR obj, TTAG msg) { if (msg == TMSG_DESTROY) { struct rfb_FontQueryHandle *fqh = obj; struct rfb_Display *mod = fqh->handle.thn_Owner; TAPTR TExecBase = mod->rfb_ExecBase; struct TNode *node, *next; node = fqh->reslist.tlh_Head.tln_Succ; for (; (next = node->tln_Succ); node = next) { struct rfb_FontQueryNode *fqn = (struct rfb_FontQueryNode *) node; /* remove from resultlist */ TRemove(&fqn->node); /* destroy fontname */ if (fqn->tags[0].tti_Value) TFree((TAPTR) fqn->tags[0].tti_Value); /* destroy node */ TFree(fqn); } /* destroy queryhandle */ TFree(fqh); } return 0; }
/* FontQueryHandle destructor ** free all memory associated with a fontqueryhandle including ** all fontquerynodes, a fontqueryhandle is obtained by calling ** dfb_hostqueryfonts() */ static THOOKENTRY TTAG dfb_fqhdestroy(struct THook *hook, TAPTR obj, TTAG msg) { if (msg == TMSG_DESTROY) { struct FontQueryHandle *fqh = obj; DFBDISPLAY *mod = fqh->handle.thn_Owner; TAPTR exec = TGetExecBase(mod); struct TNode *node, *next; node = fqh->reslist.tlh_Head; for (; (next = node->tln_Succ); node = next) { struct FontQueryNode *fqn = (struct FontQueryNode *)node; /* remove from resultlist */ TRemove(&fqn->node); /* destroy fontname */ if (fqn->tags[0].tti_Value) TExecFree(exec, (TAPTR)fqn->tags[0].tti_Value); /* destroy node */ TExecFree(exec, fqn); } /* destroy queryhandle */ TExecFree(exec, fqh); } return 0; }
LOCAL void fb_closewindow(WINDISPLAY *mod, struct TVRequest *req) { WINWINDOW *win = req->tvr_Op.CloseWindow.Window; if (win == TNULL) return; TRemove(&win->fbv_Node); fb_closeall(mod, win, TTRUE); }
static void TTASKENTRY hal_devfunc(struct TTask *task) { TAPTR exec = TGetExecBase(task); struct THALBase *hal = TExecGetHALBase(exec); struct HALSpecific *hps = hal->hmb_Specific; struct HALThread *thread = TlsGetValue(hps->hsp_TLSIndex); TAPTR port = TExecGetUserPort(exec, task); struct TTimeRequest *msg; TUINT sig = 0; TTIME waittime, curtime; struct TNode *nnode, *node; waittime.ttm_Sec = 2000000000; waittime.ttm_USec = 0; for (;;) { sig = hal_timedwaitevent(hal, thread, &waittime, TTASK_SIG_ABORT | TTASK_SIG_USER); if (sig & TTASK_SIG_ABORT) break; EnterCriticalSection(&hps->hsp_DevLock); hal_getsystime(hal, &curtime); while ((msg = TExecGetMsg(exec, port))) { TAddTime(&msg->ttr_Data.ttr_Time, &curtime); TAddTail(&hps->hsp_ReqList, (struct TNode *) msg); } waittime.ttm_Sec = 2000000000; waittime.ttm_USec = 0; node = hps->hsp_ReqList.tlh_Head; for (; (nnode = node->tln_Succ); node = nnode) { struct TTimeRequest *tr = (struct TTimeRequest *) node; TTIME *tm = &tr->ttr_Data.ttr_Time; if (TCmpTime(&curtime, tm) >= 0) { TRemove(node); tr->ttr_Req.io_Error = 0; TExecReplyMsg(exec, node); continue; } if (TCmpTime(tm, &waittime) < 0) waittime = *tm; } LeaveCriticalSection(&hps->hsp_DevLock); } TDBPRINTF(2,("goodbye from HAL device\n")); }
LOCAL TAPTR dfb_hostqueryfonts(TMOD_DFB *mod, TTAGITEM *tags) { TSTRPTR fname = TNULL; struct fnt_attr fattr; struct TNode *node, *next; struct FontQueryHandle *fqh = TNULL; TAPTR exec = TGetExecBase(mod); TDBPRINTF(10, ("***********************************************\n")); /* init fontname list */ TInitList(&fattr.fnlist); /* fetch and parse fname */ fname = (TSTRPTR) TGetTag(tags, TVisual_FontName, (TTAG) FNT_WILDCARD); if (fname) fnt_getfnnodes(mod, &fattr.fnlist, fname); /* fetch user specified attributes */ fattr.fpxsize = (TINT) TGetTag(tags, TVisual_FontPxSize, (TTAG) FNT_DEFPXSIZE); fattr.fnum = (TINT) TGetTag(tags, TVisual_FontNumResults, (TTAG) INT_MAX); /* not yet fattr.fitalic = (TBOOL) TGetTag(tags, TVisual_FontItalic, (TTAG) FNTQUERY_UNDEFINED); fattr.fbold = (TBOOL) TGetTag(tags, TVisual_FontBold, (TTAG) FNTQUERY_UNDEFINED); */ /* init result list */ fqh = TExecAlloc0(exec, mod->dfb_MemMgr, sizeof(struct FontQueryHandle)); if (fqh) { fqh->handle.thn_Owner = mod; /* connect destructor */ TInitHook(&fqh->handle.thn_Hook, fqhdestroy, fqh); TInitList(&fqh->reslist); /* init list iterator */ fqh->nptr = &fqh->reslist.tlh_Head; hostqueryfonts(mod, fqh, &fattr); TDB(10,(fnt_dumplist(&fqh->reslist))); TDBPRINTF(10, ("***********************************************\n")); } else TDBPRINTF(20, ("out of memory :(\n")); /* free memory of fnt_nodes */ for (node = fattr.fnlist.tlh_Head; (next = node->tln_Succ); node = next) { struct fnt_node *fnn = (struct fnt_node *)node; TExecFree(exec, fnn->fname); TRemove(&fnn->node); TExecFree(exec, fnn); } return fqh; }
LOCAL void fb_freepen(WINDISPLAY *mod, struct TVRequest *req) { struct TExecBase *TExecBase = TGetExecBase(mod); if (req->tvr_Op.FreePen.Pen != TVPEN_UNDEFINED) { struct FBPen *pen = (struct FBPen *) req->tvr_Op.FreePen.Pen; TRemove(&pen->node); DeleteObject(pen->pen); DeleteObject(pen->brush); TFree(pen); } }
/* removes node with given key*/ void RTreeRemove(rtree_t *tree, void *key) { assert(tree); assert(key); if(!tree) { return; } TRemove(tree, &tree->r, tree->r, key, tree->func_ptr); TBalance(tree, &tree->r); return; }
rtn_t *TRemove(rtree_t *tree, rtn_t **parent, rtn_t *root, void *key, is_before fp) { int dir = -9; rtn_t *next = NULL; if(!root) { return(NULL); } if(!(dir = fp(root->data, key))) { if(IsEqual(fp, root->data, key)) { dir = fp((*parent)->data, key); /* if root has only one child*/ if( !(root->next[dir]) || !(root->next[!dir]) ) { if(root->next[dir]) { (*parent)->next[dir] = root->next[dir]; free(root); return(NULL); } (*parent)->next[dir] = root->next[!dir]; free(root); return(NULL); } /* if root has 2 children, swap data with root next, and delete node root next */ next = Next(root, root->next[0], fp); SwapData(&(next->data), &(root->data)); free(next); return(NULL); } } TRemove(tree, &root, root->next[dir], key, fp); /* TBalance(tree, &root);*/ return(NULL); }
static THOOKENTRY TTAG fqhdestroy(struct THook *hook, TAPTR obj, TTAG msg) { if (msg == TMSG_DESTROY) { struct FontQueryHandle *fqh = obj; WINDISPLAY *mod = fqh->handle.thn_Owner; TAPTR TExecBase = TGetExecBase(mod); struct TNode *node, *next; node = fqh->reslist.tlh_Head; for (; (next = node->tln_Succ); node = next) { struct FontQueryNode *fqn = (struct FontQueryNode *)node; TRemove(&fqn->node); TFree(fqn); } } return 0; }
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 */ }