예제 #1
0
LOCAL void
dfb_setattrs(DFBDISPLAY *mod, struct TVRequest *req)
{
	struct attrdata data;
	struct THook hook;
	DFBWINDOW *v = req->tvr_Op.SetAttrs.Window;

	data.v = v;
	data.num = 0;
	data.mod = mod;
	data.sizechanged = TFALSE;
	TInitHook(&hook, setattrfunc, &data);

	TForEachTag(req->tvr_Op.SetAttrs.Tags, &hook);
	req->tvr_Op.SetAttrs.Num = data.num;

	if (data.sizechanged)
	{
		TIMSG *imsg;

		v->wminwidth = v->wminwidth <= 0 ? 1 : v->wminwidth;
		v->wminheight = v->wminheight <= 0 ? 1 : v->wminheight;
		v->wmaxwidth = v->wmaxwidth <= 0 ? 1000000 : v->wmaxwidth;
		v->wmaxheight = v->wmaxheight <= 0 ? 1000000 : v->wmaxheight;

		if (v->wmaxwidth > 0)
			v->winwidth = TMIN(v->winwidth, v->wmaxwidth);
		if (v->wmaxheight > 0)
			v->winheight = TMIN(v->winheight, v->wmaxheight);
		if (v->wminwidth > 0)
			v->winwidth = TMAX(v->winwidth, v->wminwidth);
		if (v->wminheight > 0)
			v->winheight = TMAX(v->winheight, v->wminheight);

		v->window->Resize(v->window, v->winwidth, v->winheight);

		if ((v->eventmask & TITYPE_NEWSIZE) &&
			getimsg(mod, v, &imsg, TITYPE_NEWSIZE))
		{
			imsg->timsg_Width = v->winwidth;
			imsg->timsg_Height = v->winheight;
			TAddTail(&v->imsgqueue, &imsg->timsg_Node);
		}

		if ((v->eventmask & TITYPE_REFRESH) &&
			getimsg(mod, v, &imsg, TITYPE_REFRESH))
		{
			imsg->timsg_X = v->winleft;
			imsg->timsg_Y = v->wintop;
			imsg->timsg_Width = v->winwidth;
			imsg->timsg_Height = v->winheight;
			TAddTail(&v->imsgqueue, &imsg->timsg_Node);
		}
	}
}
예제 #2
0
파일: exec_mod.c 프로젝트: ld-test/tekui
LOCAL void
exec_returnmsg(TEXECBASE *exec, TAPTR mem, TUINT status)
{
	struct TMessage *msg = TGETMSGPTR(mem);
	struct TMsgPort *replyport = msg->tmsg_RPort;
	if (replyport)
	{
		TAPTR hal = exec->texb_HALBase;

		THALLock(hal, &replyport->tmp_Lock);
		TAddTail(&replyport->tmp_MsgList, (struct TNode *) msg);
		msg->tmsg_Flags = status;
		if (replyport->tmp_Hook)
			TCALLHOOKPKT(replyport->tmp_Hook, replyport, (TTAG) msg);
		THALUnlock(hal, &replyport->tmp_Lock);

		THALSignal(hal, &replyport->tmp_SigTask->tsk_Thread,
			replyport->tmp_Signal);
	}
	else
	{
		exec_Free(exec, mem);	/* free one-way msg transparently */
		TDBPRINTF(TDB_TRACE,("message returned to memory manager\n"));
	}
}
예제 #3
0
파일: exec_mod.c 프로젝트: ld-test/tekui
static TBOOL
exec_init(TEXECBASE *exec, TTAGITEM *tags)
{
	TAPTR *halp, hal;

	halp = (TAPTR *) TGetTag(tags, TExecBase_HAL, TNULL);
	if (!halp)
		return TFALSE;
	hal = *halp;

	THALFillMem(hal, exec, sizeof(TEXECBASE), 0);
	exec->texb_HALBase = hal;

	if (THALInitLock(hal, &exec->texb_Lock))
	{
		if (exec_initmm(exec, &exec->texb_MsgMemManager, TNULL, TMMT_Message,
			TNULL))
		{
			if (exec_initmm(exec, &exec->texb_BaseMemManager, TNULL,
				TMMT_MemManager, TNULL))
			{
				exec->texb_Module.tmd_Handle.thn_Hook.thk_Data = exec;
				exec->texb_Module.tmd_Handle.thn_Name = TMODNAME_EXEC;
				exec->texb_Module.tmd_Handle.thn_Owner =
					(struct TModule *) exec;
				exec->texb_Module.tmd_ModSuper = (struct TModule *) exec;
				exec->texb_Module.tmd_InitTask = TNULL; /* inserted later */
				exec->texb_Module.tmd_HALMod = TNULL; /* inserted later */
				exec->texb_Module.tmd_NegSize =
					EXEC_NUMVECTORS * sizeof(TAPTR);
				exec->texb_Module.tmd_PosSize = sizeof(TEXECBASE);
				exec->texb_Module.tmd_RefCount = 1;
				exec->texb_Module.tmd_Flags =
					TMODF_INITIALIZED | TMODF_VECTORTABLE;

				TInitList(&exec->texb_IntModList);
				exec->texb_InitModNode.tmin_Modules = (struct TInitModule *)
					TGetTag(tags, TExecBase_ModInit, TNULL);
				if (exec->texb_InitModNode.tmin_Modules)
				{
					TAddTail(&exec->texb_IntModList,
						&exec->texb_InitModNode.tmin_Node);
				}

				TInitList(&exec->texb_AtomList);
				TInitList(&exec->texb_TaskList);
				TInitList(&exec->texb_TaskInitList);
				TInitList(&exec->texb_TaskExitList);
				TInitList(&exec->texb_ModList);
				TAddHead(&exec->texb_ModList, (struct TNode *) exec);
				TAddHead(&exec->texb_ModList, (struct TNode *) hal);

				return TTRUE;
			}
			TDESTROY(&exec->texb_MsgMemManager);
		}
		THALDestroyLock(hal, &exec->texb_Lock);
	}
	return TFALSE;
}
예제 #4
0
파일: hal.c 프로젝트: callcc/tekui
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);
	}
}
예제 #5
0
파일: hal.c 프로젝트: ld-test/tekui
static TBOOL hal_replytimereq(struct TTimeRequest *tr)
{
	TBOOL success = TFALSE;
	struct TMessage *msg = TGETMSGPTR(tr);
	struct TMsgPort *mp = msg->tmsg_RPort;
	CRITICAL_SECTION *mplock = THALGetObject((TAPTR) &mp->tmp_Lock,
		CRITICAL_SECTION);
	if (TryEnterCriticalSection(mplock))
	{
		struct TTask *sigtask = mp->tmp_SigTask;
		struct HALThread *t =
			THALGetObject((TAPTR) &sigtask->tsk_Thread, struct HALThread);
		if (TryEnterCriticalSection(&t->hth_SigLock))
		{
			tr->ttr_Req.io_Error = 0;
			msg->tmsg_Flags = TMSG_STATUS_REPLIED | TMSGF_QUEUED;
			TAddTail(&mp->tmp_MsgList, &msg->tmsg_Node);
			if (mp->tmp_Signal & ~t->hth_SigState)
			{
				t->hth_SigState |= mp->tmp_Signal;
				SetEvent(t->hth_SigEvent);
			}
			LeaveCriticalSection(&t->hth_SigLock);
			success = TTRUE;
		}
		LeaveCriticalSection(mplock);
	}
	return success;
}
예제 #6
0
LOCAL TINT rfb_sendevent(struct rfb_Display *mod, TUINT type, TUINT code,
	TINT x, TINT y)
{
	TIMSG *msg;

	if (!rfb_getimsg(mod, TNULL, &msg, type))
		return 0;
	msg->timsg_Code = code;
	msg->timsg_MouseX = x;
	msg->timsg_MouseY = y;
	TINT res = 1;

	switch (type)
	{
		case TITYPE_MOUSEMOVE:
			rfb_passevent_mousemove(mod, msg);
			break;
		case TITYPE_MOUSEBUTTON:
			rfb_passevent_mousebutton(mod, msg);
			break;
		case TITYPE_KEYUP:
		case TITYPE_KEYDOWN:
			rfb_passevent_keyboard(mod, msg);
			break;
		default:
			TDBPRINTF(TDB_ERROR, ("illegal message type\n"));
			res = 0;
	}
	/* put back prototype message */
	TAddTail(&mod->rfb_IMsgPool, &msg->timsg_Node);
	return res;
}
예제 #7
0
LOCAL TAPTR
dfb_hostopenfont(DFBDISPLAY *mod, TTAGITEM *tags)
{
	struct fnt_attr fattr;
	struct FontNode *fn;
	TAPTR font = TNULL;
	TAPTR exec = TGetExecBase(mod);

	/* fetch user specified attributes */
	fattr.fname = (TSTRPTR) TGetTag(tags, TVisual_FontName, (TTAG) FNT_DEFNAME);
	fattr.fpxsize = (TINT) TGetTag(tags, TVisual_FontPxSize, (TTAG) FNT_DEFPXSIZE);

	/* not yet
	fattr.fitalic = (TBOOL) TGetTag(tags, TVisual_FontItalic, (TTAG) TFALSE);
	fattr.fbold = (TBOOL) TGetTag(tags, TVisual_FontBold, (TTAG) TFALSE);
	fattr.fscale = (TBOOL) TGetTag(tags, TVisual_FontScaleable, (TTAG) TFALSE);
	*/

	if (fattr.fname)
	{
		fn = TExecAlloc0(exec, mod->dfb_MemMgr, sizeof(struct FontNode));
		if (fn)
		{
			fn->handle.thn_Owner = mod;

			if (hostopenfont(mod, fn, &fattr))
			{
				/* load succeeded, save font attributes */
				fn->pxsize = fattr.fpxsize;
				fn->font->GetHeight(fn->font, &fn->height);
				fn->font->GetAscender(fn->font, &fn->ascent);
				fn->font->GetDescender(fn->font, &fn->descent);

				/* not yet
				if (fattr.fitalic)
					fn->attr = FNT_ITALIC;
				if (fattr.fbold)
					fn->attr |= FNT_BOLD;
				*/

				/* append to the list of open fonts */
				TDBPRINTF(TDB_INFO, ("O '%s' %dpx\n", fattr.fname, fattr.fpxsize));
				TAddTail(&mod->dfb_fm.openfonts, &fn->handle.thn_Node);
				font = (TAPTR)fn;
			}
			else
			{
				/* load failed, free fontnode */
				TDBPRINTF(TDB_INFO,("X unable to load '%s'\n", fattr.fname));
				TExecFree(exec, fn);
			}
		}
		else
			TDBPRINTF(TDB_FAIL,("out of memory :(\n"));
	}
	else
		TDBPRINTF(TDB_ERROR,("X invalid fontname '%s' specified\n", fattr.fname));

	return font;
}
예제 #8
0
LOCAL void rfb_putbackmsg(struct rfb_Display *mod, TIMSG *msg)
{
	TAPTR TExecBase = TGetExecBase(mod);

	TLock(mod->rfb_InstanceLock);
	TAddTail(&mod->rfb_IMsgPool, &msg->timsg_Node);
	TUnlock(mod->rfb_InstanceLock);
}
예제 #9
0
파일: hal.c 프로젝트: ld-test/tekui
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"));
}
예제 #10
0
/* parses a single fontname or a comma separated list of fontnames
** and returns a list of fontnames, spaces are NOT filtered, so
** "helvetica, fixed" will result in "helvetica" and " fixed"
*/
static void
fnt_getfnnodes(DFBDISPLAY *mod, struct TList *fnlist, TSTRPTR fname)
{
	TINT i, p = 0;
	TBOOL lastrun = TFALSE;
	TINT fnlen = strlen(fname);
	TAPTR exec = TGetExecBase(mod);

	for (i = 0; i < fnlen; i++)
	{
		if (i == fnlen-1) lastrun = TTRUE;

		if (fname[i] == ',' || lastrun)
		{
			TINT len = (i > p) ? (lastrun ? (i-p+1) : (i-p)) : fnlen+1;
			TSTRPTR ts = TExecAlloc0(exec, mod->dfb_MemMgr, len+1);

			if (ts)
			{
				struct fnt_node *fnn;

				TExecCopyMem(exec, fname+p, ts, len);

				fnn = TExecAlloc0(exec, mod->dfb_MemMgr, sizeof(struct fnt_node));
				if (fnn)
				{
					/* add fnnode to fnlist */
					fnn->fname = ts;
					TAddTail(fnlist, &fnn->node);
				}
				else
				{
					TDBPRINTF(TDB_FAIL,("out of memory :(\n"));
					break;
				}
			}
			else
			{
				TDBPRINTF(TDB_FAIL,("out of memory :(\n"));
				break;
			}

			p = i+1;
		}
	}
}
예제 #11
0
static void fnt_getfnnodes(struct rfb_Display *mod, struct TList *fnlist,
	TSTRPTR fname)
{
	TINT i, p = 0;
	TBOOL lastrun = TFALSE;
	TINT fnlen = strlen(fname);
	TAPTR TExecBase = mod->rfb_ExecBase;

	for (i = 0; i < fnlen; i++)
	{
		if (i == fnlen - 1)
			lastrun = TTRUE;

		if (fname[i] == ',' || lastrun)
		{
			TINT len = (i > p) ? (lastrun ? (i - p + 1) : (i - p)) : fnlen + 1;
			TSTRPTR ts = TAlloc0(mod->rfb_MemMgr, len + 1);

			if (ts)
			{
				struct fnt_node *fnn;

				memcpy(ts, fname + p, len);
				fnn = TAlloc0(mod->rfb_MemMgr, sizeof(struct fnt_node));
				if (fnn)
				{
					/* add fnnode to fnlist */
					fnn->fname = ts;
					TAddTail(fnlist, &fnn->node);
				}
				else
				{
					TDBPRINTF(20, ("out of memory :(\n"));
					break;
				}
			}
			else
			{
				TDBPRINTF(20, ("out of memory :(\n"));
				break;
			}

			p = i + 1;
		}
	}
}
예제 #12
0
LOCAL void
dfb_allocpen(DFBDISPLAY *mod, struct TVRequest *req)
{
	DFBWINDOW *v = req->tvr_Op.AllocPen.Window;
	TUINT rgb = req->tvr_Op.AllocPen.RGB;
	struct DFBPen *pen = TExecAlloc(mod->dfb_ExecBase, mod->dfb_MemMgr,
		sizeof(struct DFBPen));
	if (pen)
	{
		pen->a = rgb >> 24;
		pen->r = ((rgb >> 16) & 0xff);
		pen->g = ((rgb >> 8) & 0xff);
		pen->b = rgb & 0xff;
		TAddTail(&v->penlist, &pen->node);
		req->tvr_Op.AllocPen.Pen = (TVPEN) pen;
		return;
	}
	req->tvr_Op.AllocPen.Pen = TVPEN_UNDEFINED;
}
예제 #13
0
LOCAL void
fb_allocpen(WINDISPLAY *mod, struct TVRequest *req)
{
	struct TExecBase *TExecBase = TGetExecBase(mod);
	WINWINDOW *v = req->tvr_Op.AllocPen.Window;
	TUINT rgb = req->tvr_Op.AllocPen.RGB;
	struct FBPen *pen = TAlloc(mod->fbd_MemMgr, sizeof(struct FBPen));
	if (pen)
	{
		COLORREF col = RGB2COLORREF(rgb);
		pen->rgb = rgb;
		pen->col = col;
		pen->brush = CreateSolidBrush(col);
		pen->pen = CreatePen(PS_SOLID, 0, col);
		TAddTail(&v->penlist, &pen->node);
		req->tvr_Op.AllocPen.Pen = (TVPEN) pen;
		return;
	}
	req->tvr_Op.AllocPen.Pen = TVPEN_UNDEFINED;
}
예제 #14
0
파일: exec_mod.c 프로젝트: ld-test/tekui
LOCAL TUINT exec_sendmsg(TEXECBASE *TExecBase, struct TTask *task,
	struct TMsgPort *port, TAPTR mem)
{
	TAPTR hal = TExecBase->texb_HALBase;
	struct TMessage *msg = TGETMSGPTR(mem);
	TAPTR reply;

	/* replyport is task's syncport */
	msg->tmsg_RPort = &task->tsk_SyncPort;

	/* sender is local address space */
	msg->tmsg_Sender = TNULL;

	THALLock(hal, &port->tmp_Lock);
	TAddTail(&port->tmp_MsgList, (struct TNode *) msg);
	msg->tmsg_Flags = TMSG_STATUS_SENT | TMSGF_QUEUED;
	if (port->tmp_Hook)
		TCALLHOOKPKT(port->tmp_Hook, port, (TTAG) msg);
	THALUnlock(hal, &port->tmp_Lock);

	THALSignal(hal, &port->tmp_SigTask->tsk_Thread, port->tmp_Signal);

	for (;;)
	{
		THALWait(TExecBase->texb_HALBase, task->tsk_SyncPort.tmp_Signal);
		reply = TGetMsg(msg->tmsg_RPort);
		if (reply)
		{
			TUINT status = msg->tmsg_Flags;
			TDBASSERT(99, reply == mem);
			msg->tmsg_Flags = 0;
			return status;
		}
		TDBPRINTF(TDB_FAIL,("signal on syncport, no message!\n"));
	}
}
예제 #15
0
LOCAL TAPTR rfb_hostopenfont(struct rfb_Display *mod, TTAGITEM *tags)
{
	struct fnt_attr fattr;
	struct rfb_FontNode *fn;
	TAPTR font = TNULL;

	/* fetch user specified attributes */
	fattr.fname = (TSTRPTR) TGetTag(tags, TVisual_FontName,
		(TTAG) FNT_DEFNAME);
	fattr.fpxsize = (TINT) TGetTag(tags, TVisual_FontPxSize,
		(TTAG) FNT_DEFPXSIZE);

	if (fattr.fname)
	{
		fn = TExecAlloc0(mod->rfb_ExecBase, mod->rfb_MemMgr,
			sizeof(struct rfb_FontNode));
		if (fn)
		{
			fn->handle.thn_Owner = mod;
			if (hostopenfont(mod, fn, &fattr))
			{
				/* load succeeded, save font attributes */
				fn->pxsize = fattr.fpxsize;
				fn->height = fn->face->size->metrics.height >> 6;
				fn->ascent = fn->face->size->metrics.ascender >> 6;
				fn->descent = fn->face->size->metrics.descender >> 6;

				/* append to the list of open fonts */
				TDBPRINTF(TDB_INFO, ("O '%s' %dpx\n", fattr.fname,
						fattr.fpxsize));
				TAddTail(&mod->rfb_FontManager.openfonts,
					&fn->handle.thn_Node);
				font = (TAPTR) fn;
			}
			else
			{
예제 #16
0
static TBOOL x11_processkey(struct X11Display *mod, struct X11Window *v,
	XKeyEvent *ev, TBOOL keydown)
{
	KeySym keysym;
	XComposeStatus compose;
	char buffer[10];

	TIMSG *imsg;
	TUINT evtype = 0;
	TUINT newqual;
	TUINT evmask = v->eventmask;
	TBOOL newkey = TFALSE;

	x11_setmousepos(mod, v, ev->x, ev->y);

	XLookupString(ev, buffer, 10, &keysym, &compose);

	switch (keysym)
	{
		case XK_Shift_L:
			newqual = TKEYQ_LSHIFT;
			break;
		case XK_Shift_R:
			newqual = TKEYQ_RSHIFT;
			break;
		case XK_Control_L:
			newqual = TKEYQ_LCTRL;
			break;
		case XK_Control_R:
			newqual = TKEYQ_RCTRL;
			break;
		case XK_Alt_L:
			newqual = TKEYQ_LALT;
			break;
		case XK_Alt_R:
			newqual = TKEYQ_RALT;
			break;
		default:
			newqual = 0;
	}

	if (newqual != 0)
	{
		if (keydown)
			mod->x11_KeyQual |= newqual;
		else
			mod->x11_KeyQual &= ~newqual;
	}

	if (keydown && (evmask & TITYPE_KEYDOWN))
		evtype = TITYPE_KEYDOWN;
	else if (!keydown && (evmask & TITYPE_KEYUP))
		evtype = TITYPE_KEYUP;

	if (evtype && x11_getimsg(mod, v, &imsg, evtype))
	{
		imsg->timsg_Qualifier = mod->x11_KeyQual;

		if (keysym >= XK_F1 && keysym <= XK_F12)
		{
			imsg->timsg_Code = (TUINT) (keysym - XK_F1) + TKEYC_F1;
			newkey = TTRUE;
		}
		else if (keysym < 256)
		{
			/* cooked ASCII/Latin-1 code */
			imsg->timsg_Code = keysym;
			newkey = TTRUE;
		}
		else if (keysym >= XK_KP_0 && keysym <= XK_KP_9)
		{
			imsg->timsg_Code = (TUINT) (keysym - XK_KP_0) + 48;
			imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
			newkey = TTRUE;
		}
		else
		{
			newkey = TTRUE;
			switch (keysym)
			{
				case XK_Left:
					imsg->timsg_Code = TKEYC_CRSRLEFT;
					break;
				case XK_Right:
					imsg->timsg_Code = TKEYC_CRSRRIGHT;
					break;
				case XK_Up:
					imsg->timsg_Code = TKEYC_CRSRUP;
					break;
				case XK_Down:
					imsg->timsg_Code = TKEYC_CRSRDOWN;
					break;

				case XK_Escape:
					imsg->timsg_Code = TKEYC_ESC;
					break;
				case XK_Delete:
					imsg->timsg_Code = TKEYC_DEL;
					break;
				case XK_BackSpace:
					imsg->timsg_Code = TKEYC_BCKSPC;
					break;
				case XK_ISO_Left_Tab:
				case XK_Tab:
					imsg->timsg_Code = TKEYC_TAB;
					break;
				case XK_Return:
					imsg->timsg_Code = TKEYC_RETURN;
					break;

				case XK_Help:
					imsg->timsg_Code = TKEYC_HELP;
					break;
				case XK_Insert:
					imsg->timsg_Code = TKEYC_INSERT;
					break;
				case XK_Page_Up:
					imsg->timsg_Code = TKEYC_PAGEUP;
					break;
				case XK_Page_Down:
					imsg->timsg_Code = TKEYC_PAGEDOWN;
					break;
				case XK_Home:
					imsg->timsg_Code = TKEYC_POSONE;
					break;
				case XK_End:
					imsg->timsg_Code = TKEYC_POSEND;
					break;
				case XK_Print:
					imsg->timsg_Code = TKEYC_PRINT;
					break;
				case XK_Scroll_Lock:
					imsg->timsg_Code = TKEYC_SCROLL;
					break;
				case XK_Pause:
					imsg->timsg_Code = TKEYC_PAUSE;
					break;
				case XK_KP_Enter:
					imsg->timsg_Code = TKEYC_RETURN;
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Decimal:
					imsg->timsg_Code = '.';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Add:
					imsg->timsg_Code = '+';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Subtract:
					imsg->timsg_Code = '-';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Multiply:
					imsg->timsg_Code = '*';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				case XK_KP_Divide:
					imsg->timsg_Code = '/';
					imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK;
					break;
				default:
					if (keysym > 31 && keysym <= 0x20ff)
						imsg->timsg_Code = keysym;
					else if (keysym >= 0x01000100 && keysym <= 0x0110ffff)
						imsg->timsg_Code = keysym - 0x01000000;
					else
						newkey = TFALSE;
					break;
			}
		}

		if (!newkey && newqual)
		{
			imsg->timsg_Code = TKEYC_NONE;
			newkey = TTRUE;
		}

		if (newkey)
		{
			ptrdiff_t len =
				(ptrdiff_t) utf8encode(imsg->timsg_KeyCode, imsg->timsg_Code) -
				(ptrdiff_t) imsg->timsg_KeyCode;
			imsg->timsg_KeyCode[len] = 0;
			TAddTail(&v->imsgqueue, &imsg->timsg_Node);
		}
		else
		{
			/* put back message: */
			TAddTail(&mod->x11_imsgpool, &imsg->timsg_Node);
		}
	}

	return newkey;
}
예제 #17
0
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;
}
예제 #18
0
LOCAL void
fb_openwindow(WINDISPLAY *mod, struct TVRequest *req)
{
	struct TExecBase *TExecBase = TGetExecBase(mod);
	TTAGITEM *tags = req->tvr_Op.OpenWindow.Tags;
	WINWINDOW *win;

	req->tvr_Op.OpenWindow.Window = TNULL;

	for (;;)
	{
		RECT wrect;
		BITMAPINFOHEADER *bmi;
		TUINT style;
		TUINT exstyle;
		TIMSG *imsg;
		const char *classname;
		TSTRPTR title;

		win = TAlloc0(mod->fbd_MemMgr, sizeof(WINWINDOW));
		if (win == TNULL)
			break;

		TInitList(&win->penlist);

		InitializeCriticalSection(&win->fbv_LockExtents);

		win->fbv_Width = (TUINT) TGetTag(tags, TVisual_Width, FB_DEF_WIDTH);
		win->fbv_Height = (TUINT) TGetTag(tags, TVisual_Height, FB_DEF_HEIGHT);
		win->fbv_Left = (TUINT) TGetTag(tags, TVisual_WinLeft, 0xffffffff);
		win->fbv_Top = (TUINT) TGetTag(tags, TVisual_WinTop, 0xffffffff);
		win->fbv_Title = (TSTRPTR) TGetTag(tags, TVisual_Title,
			(TTAG) "TEKlib Visual");
		win->fbv_Borderless = TGetTag(tags, TVisual_Borderless, TFALSE);
		win->fbv_UserData = TGetTag(tags, TVisual_UserData, TNULL);

		win->fbv_MinWidth = (TINT) TGetTag(tags, TVisual_MinWidth, (TTAG) -1);
		win->fbv_MinHeight = (TINT) TGetTag(tags, TVisual_MinHeight, (TTAG) -1);
		win->fbv_MaxWidth = (TINT) TGetTag(tags, TVisual_MaxWidth, (TTAG) -1);
		win->fbv_MaxHeight = (TINT) TGetTag(tags, TVisual_MaxHeight, (TTAG) -1);

		if (win->fbv_Borderless)
		{
			style = (WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) & ~WS_BORDER;
			classname = FB_DISPLAY_CLASSNAME_POPUP;
			title = NULL;
			exstyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
		}
		else
		{
			style = WS_OVERLAPPEDWINDOW;
			classname = FB_DISPLAY_CLASSNAME;
			title = win->fbv_Title;
			exstyle = 0;
		}

		wrect.left = wrect.right = wrect.top = wrect.bottom = 0;
		AdjustWindowRectEx(&wrect, style, FALSE, exstyle);
		win->fbv_BorderWidth = wrect.right - wrect.left;
		win->fbv_BorderHeight = wrect.bottom - wrect.top;
		win->fbv_BorderLeft = -wrect.left;
		win->fbv_BorderTop = -wrect.top;

		if (!win->fbv_Borderless)
		{
			TINT m1, m2, m3, m4;
			win_getminmax(win, &m1, &m2, &m3, &m4, TTRUE);
			win->fbv_Width = TCLAMP(m1, (TINT) win->fbv_Width, m3);
			win->fbv_Height = TCLAMP(m2, (TINT) win->fbv_Height, m4);
		}

		if (win->fbv_Left != 0xffffffff && win->fbv_Top != 0xffffffff)
		{
			wrect.left = win->fbv_Left;
			wrect.top = win->fbv_Top;
			wrect.right = win->fbv_Left + win->fbv_Width;
			wrect.bottom = win->fbv_Top + win->fbv_Height;
			if (!AdjustWindowRectEx(&wrect, style, FALSE, exstyle))
				break;

			win->fbv_Left = wrect.left;
			win->fbv_Top = wrect.top;
			win->fbv_HWnd = CreateWindowEx(exstyle, classname,
				title, style, win->fbv_Left, win->fbv_Top,
				wrect.right - wrect.left - win->fbv_BorderWidth, 
				wrect.bottom - wrect.top - win->fbv_BorderHeight,
				(HWND) NULL, (HMENU) NULL, mod->fbd_HInst, (LPVOID) NULL);
		}
		else
		{
			win->fbv_HWnd = CreateWindowEx(exstyle, classname,
				title, style, CW_USEDEFAULT, CW_USEDEFAULT,
				win->fbv_Width, win->fbv_Height,
				(HWND) NULL, (HMENU) NULL, mod->fbd_HInst, (LPVOID) NULL);
		}

		if (win->fbv_HWnd == TNULL)
			break;

		GetWindowRect(win->fbv_HWnd, &wrect);
		win->fbv_Left = wrect.left + win->fbv_BorderLeft;
		win->fbv_Top = wrect.top + win->fbv_BorderHeight;
		win->fbv_Width = wrect.right - wrect.left - win->fbv_BorderWidth;
		win->fbv_Height = wrect.bottom - wrect.top - win->fbv_BorderHeight;

		SetWindowLongPtr(win->fbv_HWnd, GWLP_USERDATA, (LONG_PTR) win);

		win->fbv_HDC = GetDC(win->fbv_HWnd);
		win->fbv_Display = mod;
		win->fbv_InputMask = (TUINT) TGetTag(tags, TVisual_EventMask, 0);
		win->fbv_IMsgPort = req->tvr_Op.OpenWindow.IMsgPort;

		bmi = &win->fbv_DrawBitMap;
		bmi->biSize = sizeof(BITMAPINFOHEADER);
		bmi->biPlanes = 1;
		bmi->biBitCount = 32;
		bmi->biCompression = BI_RGB;
		bmi->biSizeImage = 0;
		bmi->biXPelsPerMeter = 1;
		bmi->biYPelsPerMeter = 1;
		bmi->biClrUsed = 0;
		bmi->biClrImportant = 0;

		TInitList(&win->fbv_IMsgQueue);

		req->tvr_Op.OpenWindow.Window = win;

		/* init default font */
		win->fbv_CurrentFont = mod->fbd_FontManager.deffont;
		mod->fbd_FontManager.defref++;

		if (win->fbv_InputMask & TITYPE_INTERVAL)
			++mod->fbd_NumInterval;

		/* register default font */
		/*TDBPRINTF(TDB_TRACE,("Add window: %p\n", win->window));*/

		/* add window on top of window stack: */
		TAddHead(&mod->fbd_VisualList, &win->fbv_Node);

		SetBkMode(win->fbv_HDC, TRANSPARENT);
		
		ShowWindow(win->fbv_HWnd, SW_SHOWNORMAL);
		UpdateWindow(win->fbv_HWnd);

		if ((win->fbv_InputMask & TITYPE_FOCUS) &&
			(fb_getimsg(mod, win, &imsg, TITYPE_FOCUS)))
		{
			imsg->timsg_Code = 1;
			TAddTail(&win->fbv_IMsgQueue, &imsg->timsg_Node);
		}
		if ((win->fbv_InputMask & TITYPE_REFRESH) &&
			(fb_getimsg(mod, win, &imsg, TITYPE_REFRESH)))
		{
			imsg->timsg_X = 0;
			imsg->timsg_Y = 0;
			imsg->timsg_Width = win->fbv_Width;
			imsg->timsg_Height = win->fbv_Height;
			TAddTail(&win->fbv_IMsgQueue, &imsg->timsg_Node);
		}
		
		return;
	}

	TDBPRINTF(TDB_ERROR,("Window open failed\n"));
	fb_closeall(mod, win, TFALSE);
}
예제 #19
0
static int CALLBACK fontenumcb(
    ENUMLOGFONTEX *lpelfe,
    NEWTEXTMETRICEX *lpntme,
    int fonttype,
    LPARAM param)
{
    LOGFONT *lf = &lpelfe->elfLogFont;
    TSTRPTR fullname = (TSTRPTR) lpelfe->elfFullName;
    TSTRPTR style = (TSTRPTR) lpelfe->elfStyle;
    TSTRPTR script = (TSTRPTR) lpelfe->elfScript;
    struct FontQueryHandle *fqh = (struct FontQueryHandle *) param;
    WINDISPLAY *mod = fqh->handle.thn_Owner;
    struct TExecBase *TExecBase = TGetExecBase(mod);
    struct FontQueryNode *fqn;

    if (fqh->match_depth == 0)
    {
        LOGFONT logfont;
        memcpy(&logfont, lf, sizeof(LOGFONT));
        fqh->match_depth = 1;
        TDBPRINTF(TDB_INFO,("fontenum - entering recursion\n"));
        logfont.lfCharSet = ANSI_CHARSET;
        logfont.lfPitchAndFamily = 0;
        EnumFontFamiliesEx(
            mod->fbd_DeviceHDC,
            &logfont,
            (FONTENUMPROCA) fontenumcb,
            (LPARAM) fqh, 0);
        fqh->match_depth = 0;
        return TTRUE;
    }


    if (fqh->fscale && !(fonttype & TRUETYPE_FONTTYPE))
        return TTRUE;
    if (fqh->fitalic && !lf->lfItalic)
        return TTRUE;
    if (fqh->fbold && (lf->lfWeight < FW_BOLD))
        return TTRUE;

    TDBPRINTF(TDB_INFO,("entry:'%s' style:'%s' script:'%s' type:%04x weight:%d italic:%d recurs:%d, size:%d\n",
                        fullname, style, script, fonttype, lf->lfWeight, !!lf->lfItalic,
                        fqh->match_depth, lf->lfHeight));

    fqn = TAlloc(TNULL,
                 sizeof(struct FontQueryNode) + strlen(fullname) + 1);
    if (fqn == TNULL)
        return TFALSE;

    strcpy((char *) (fqn + 1), fullname);
    fqn->tags[0].tti_Tag = TVisual_FontName;
    fqn->tags[0].tti_Value = (TTAG) (fqn + 1);
    fqn->tags[1].tti_Tag = TVisual_FontItalic;
    fqn->tags[1].tti_Value = !!lf->lfItalic;
    fqn->tags[2].tti_Tag = TVisual_FontBold;
    fqn->tags[2].tti_Value = (lf->lfWeight >= FW_BOLD);
    fqn->tags[3].tti_Tag = TTAG_DONE;

    TAddTail(&fqh->reslist, &fqn->node);
    return TTRUE;
}
예제 #20
0
static void
hostqueryfonts(DFBDISPLAY *mod, struct FontQueryHandle *fqh, struct fnt_attr *fattr)
{
	TINT i, nfont, fcount = 0;
	struct TNode *node, *next;
	TAPTR exec = TGetExecBase(mod);
	struct dirent **dirlist;
	TUINT matchflg = 0;

	/* scan default font directory */
	nfont = scandir(FNT_DEFDIR, &dirlist, 0, alphasort);
	if (nfont < 0)
	{
		perror("scandir");
		return;
	}

	if (nfont > 0)
	{
		/* found fonts in default font directory */
		for (node = fattr->fnlist.tlh_Head; (next = node->tln_Succ); node = next)
		{
			struct fnt_node *fnn = (struct fnt_node *)node;

			/* build matchflag, font pxsize attribute is ignored,
			   because it's not relevant when matching ttf fonts */

			matchflg = FNT_MATCH_NAME;

			/* not yet
			if (fattr->fitalic != FNTQUERY_UNDEFINED)
				matchflg |= FNT_MATCH_SLANT;
			if (fattr->fbold != FNTQUERY_UNDEFINED)
				matchflg |= FNT_MATCH_WEIGHT;
			*/

			for (i = 0; i < nfont; i++)
			{
				if (fnt_matchfont(mod, dirlist[i]->d_name, fnn->fname,
					fattr, matchflg) == matchflg)
				{
					struct FontQueryNode *fqnode;

					/* create fqnode and fill in attributes */
					fqnode = fnt_getfqnode(mod, dirlist[i]->d_name, fattr->fpxsize);
					if (!fqnode)	break;

					/* compare fqnode with nodes in result list */
					if (fnt_checkfqnode(&fqh->reslist, fqnode) == 0)
					{
						if (fcount < fattr->fnum)
						{
							/* fqnode is unique, add to result list */
							TAddTail(&fqh->reslist, &fqnode->node);
							fcount++;
						}
						else
						{
							/* max count of desired results reached */
							TExecFree(exec, (TSTRPTR)fqnode->tags[0].tti_Value);
							TExecFree(exec, fqnode);
							break;
						}
					}
					else
					{
						/* fqnode is not unique, destroy it */
						TDBPRINTF(TDB_ERROR,("X node is not unique\n"));
						TExecFree(exec, (TSTRPTR)fqnode->tags[0].tti_Value);
						TExecFree(exec, fqnode);
					}
				}
			}

			if (fcount == fattr->fnum)
				break;

		} /* end of fnlist iteration */

	} /* endif fonts found */
	else
		TDBPRINTF(TDB_WARN,("X no fonts found in '%s'\n", FNT_DEFDIR));

	while (nfont--)
		free(dirlist[nfont]);
	free(dirlist);
}
예제 #21
0
파일: hal.c 프로젝트: callcc/tekui
EXPORT void
hal_beginio(struct THALBase *hal, struct TTimeRequest *req)
{
	struct HALSpecific *hws = hal->hmb_Specific;
	TAPTR exec = hws->hsp_ExecBase;
	TTIME curtime;
	TINT64 x = 0;

	switch (req->ttr_Req.io_Command)
	{
		/* execute asynchronously */
		case TTREQ_WAITLOCALDATE:
			/* microseconds west of GMT: */
			x = hal_getdstfromlocaldate(hal, &req->ttr_Data.ttr_Date);
			x *= 1000000;
		case TTREQ_WAITUNIVERSALDATE:
			x += req->ttr_Data.ttr_Date.tdt_Int64;
			x -= 11644473600000000ULL;
			req->ttr_Data.ttr_Date.tdt_Int64 = x;
			#ifndef USE_MMTIMER
			hal_getsystime(hal, &curtime);
			TSubTime(&req->ttr_Data.ttr_Time, &curtime);
			#endif
			goto addtimereq;

		case TTREQ_WAITTIME:
			#ifdef USE_MMTIMER
			hal_getsystime(hal, &curtime);
			TAddTime(&req->ttr_Data.ttr_Time, &curtime);
			#endif

		addtimereq:
		{
			#ifdef USE_MMTIMER
			struct TMessage *msg = TGETMSGPTR(req);
			EnterCriticalSection(&hws->hsp_DevLock);
			msg->tmsg_Flags = TMSG_STATUS_SENT | TMSGF_QUEUED;
			msg->tmsg_RPort = req->ttr_Req.io_ReplyPort;
			TAddTail(&hws->hsp_ReqList, (struct TNode *) req);
			LeaveCriticalSection(&hws->hsp_DevLock);
			#else
			TExecPutMsg(exec, TExecGetUserPort(exec, hws->hsp_DevTask),
				req->ttr_Req.io_ReplyPort, req);
			#endif
			return;
		}

		/* execute synchronously */
		default:
		case TTREQ_GETUNIVERSALDATE:
		{
			TINT timezone_bias;
			hal_getsysdate(hal, &req->ttr_Data.ttr_Date, &timezone_bias);
			break;
		}

		case TTREQ_GETLOCALDATE:
			hal_getsysdate(hal, &req->ttr_Data.ttr_Date, TNULL);
			break;

		case TTREQ_GETSYSTEMTIME:
			hal_getsystime(hal, &req->ttr_Data.ttr_Time);
			break;

		#if 0
		case TTREQ_GETDSFROMDATE:
			req->ttr_Data.ttr_DSSec =
				hal_dsfromdate(hal, &req->ttr_Data.ttr_Date.ttr_Date);
			break;
		#endif
	}

	req->ttr_Req.io_Error = 0;

	if (!(req->ttr_Req.io_Flags & TIOF_QUICK))
	{
		/* async operation indicated; reply to self */
		TExecReplyMsg(exec, req);
	}
}
예제 #22
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 */
}