⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
void
GrDelay(GR_TIMEOUT msecs)
{
	struct timeval timeval;

	timeval.tv_sec = msecs / 1000;
	timeval.tv_usec = msecs % 1000;
	select(0, NULL, NULL, NULL, &timeval);
}

/**
 * GrGetScreenInfo:
 * @sip: pointer to a GR_SCREEN_INFO structure
 *
 * Fills in the specified GR_SCREEN_INFO structure.
 */
void 
GrGetScreenInfo(GR_SCREEN_INFO *sip)
{
	AllocReq(GetScreenInfo);
	GrTypedReadBlock(sip, sizeof(GR_SCREEN_INFO),GrNumGetScreenInfo);
}

/**
 * GrGetSysColor:
 * @index: an index into the server's colour look up table
 * @Returns: the colour found at the specified index
 *
 * Returns the colour at the specified index into the server's colour look
 * up table. The colours in the table are those with names like
 * "GR_COLOR_DESKTOP", "GR_COLOR_ACTIVECAPTION", "GR_COLOR_APPWINDOW", etc.
 * as listed in nano-X.h
 */
GR_COLOR
GrGetSysColor(int index)
{
	nxGetSysColorReq *req;
	GR_COLOR color;

	req = AllocReq(GetSysColor);
	req->index = index;
	if(GrTypedReadBlock(&color, sizeof(color),GrNumGetSysColor) == -1)
		return 0;
	return color;
}

/**
 * GrGetFontInfo:
 * @fontno: the font ID number
 * @fip: pointer to a GR_FONT_INFO structure
 *
 * Fills in the specified GR_FONT_INFO structure with information regarding
 * the specified font.
 */
void 
GrGetFontInfo(GR_FONT_ID fontno, GR_FONT_INFO *fip)
{
	nxGetFontInfoReq *req;

	req = AllocReq(GetFontInfo);
	req->fontid = fontno;
	GrTypedReadBlock(fip, sizeof(GR_FONT_INFO),GrNumGetFontInfo);
}

/**
 * GrGetGCInfo:
 * @gc: a graphics context
 * @gcip: pointer to a GR_GC_INFO structure
 *
 * Fills in the specified GR_GC_INFO structure with information regarding the
 * specified graphics context.
 */
void GrGetGCInfo(GR_GC_ID gc, GR_GC_INFO *gcip)
{
	nxGetGCInfoReq *req;

	req = AllocReq(GetGCInfo);
	req->gcid = gc;
	GrTypedReadBlock(gcip, sizeof(GR_GC_INFO),GrNumGetGCInfo);
}

/**
 * GrGetGCTextSize:
 * @gc: the graphics context
 * @str: pointer to a text string
 * @count: the length of the string
 * @flags: text rendering flags (GR_TF*)
 * @retwidth: pointer to the variable the width will be returned in
 * @retheight: pointer to the variable the height will be returned in
 * @retbase: pointer to the variable the baseline height will be returned in
 *
 * Calculates the dimensions of the specified text string using the current font
 * and flags in the specified graphics context. The count argument can be -1
 * if the string is null terminated.
 */
void GrGetGCTextSize(GR_GC_ID gc, void *str, int count, int flags,
	GR_SIZE *retwidth, GR_SIZE *retheight, GR_SIZE *retbase)
{
	nxGetGCTextSizeReq *req;
	int size;

	if(count == -1 && (flags&MWTF_PACKMASK) == MWTF_ASCII)
		count = strlen((char *)str);

	size = nxCalcStringBytes(str, count, flags);

	req = AllocReqExtra(GetGCTextSize, size);
	req->gcid = gc;
	req->flags = flags;
	memcpy(GetReqData(req), str, size);
	GrTypedReadBlock(retwidth, sizeof(*retwidth),GrNumGetGCTextSize);
	GrReadBlock(retheight, sizeof(*retheight));
	GrReadBlock(retbase, sizeof(*retbase));
}

/**
 * GrRegisterInput:
 * @fd: the file descriptor to monitor
 *
 * Register an extra file descriptor to monitor in the main select() call.
 * An event will be returned when the fd has data waiting to be read if that
 * event has been selected for.
 */
void 
GrRegisterInput(int fd)
{
	ACCESS_PER_THREAD_DATA()

	if (fd < 0)
		return;
	FD_SET(fd, &regfdset);
	if (fd > regfdmax) regfdmax = fd + 1;
}

/**
 * GrUnregisterInput:
 * @fd: the file descriptor to stop monitoring
 *
 * Stop monitoring a file descriptor (previously registered with
 * GrRegisterInput()) in the main select() call.
 */
void
GrUnregisterInput(int fd)
{
	int i, max;
	ACCESS_PER_THREAD_DATA()

	/* unregister all inputs if fd is -1 */
	if (fd == -1) {
		FD_ZERO(&regfdset);
		regfdmax = -1;
		return;
	}

	FD_CLR(fd, &regfdset);
	/* recalculate the max file descriptor */
	for (i = 0, max = regfdmax, regfdmax = -1; i < max; i++)
		if (FD_ISSET(i, &regfdset))
			regfdmax = i + 1;
}

/**
 * GrPrepareSelect:
 * @maxfd: pointer to a variable which the highest in use fd will be written to
 * @rfdset: pointer to the file descriptor set structure to use
 *
 * Prepare for a GrServiceSelect function by asking the server to send the next
 * event but not waiting around for it to arrive and initialising the
 * specified fd_set structure with the client/server socket descriptor and any
 * previously registered external file descriptors. Also compares the current
 * contents of maxfd, the client/server socket descriptor, and the previously
 * registered external file descriptors, and returns the highest of them in
 * maxfd.
 */
void
GrPrepareSelect(int *maxfd,void *rfdset)
{
	fd_set *rfds = rfdset;
	int fd;

	ACCESS_PER_THREAD_DATA()

	AllocReq(GetNextEvent);
	GrFlush();

	FD_SET(nxSocket, rfds);
	if(nxSocket > *maxfd)
		*maxfd = nxSocket;

	/* handle registered input file descriptors*/
	for (fd = 0; fd < regfdmax; fd++) {
		if (FD_ISSET(fd, &regfdset)) {
			FD_SET(fd, rfds);
			if (fd > *maxfd) *maxfd = fd;
		}
	}
}

/**
 * GrServiceSelect:
 * @rfdset: pointer to the file descriptor set to monitor
 * @fncb: pointer to the function to call when an event needs handling
 *
 * Used by GrMainLoop() to call the specified callback function when an
 * event arrives or there is data waiting on an external fd specified by
 * GrRegisterInput().
 */
void
GrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb)
{
	fd_set *	rfds = rfdset;
	int		fd;
	GR_EVENT 	ev;

	ACCESS_PER_THREAD_DATA()

        /* Clean out any event that might have arrived while waiting
	 * for other data, for instance by doing Nano-X requests
	 * between GrPrepareSelect() and GrServiceSelect(), or when
	 * an event is generated in Nano-X at the same time as the
	 * client wakes up for some reason and calls Nano-X functions.
	 */
	if (evlist) {
		/*DPRINTF("nxclient: Handling queued event\n");*/
		GetNextQueuedEvent(&ev);
		CheckErrorEvent(&ev);
		fncb(&ev);
	}
	else {
		if(FD_ISSET(nxSocket, rfds)) {
			GrTypedReadBlock(&ev, sizeof(ev),GrNumGetNextEvent);
			GrCheckForClientData(&ev);
			CheckErrorEvent(&ev);
			fncb(&ev);
		}
	}

	/* check for input on registered file descriptors */
	for (fd = 0; fd < regfdmax; fd++) {
		if (FD_ISSET(fd, &regfdset) && FD_ISSET(fd, rfds)) {
			ev.type = GR_EVENT_TYPE_FDINPUT;
			ev.fdinput.fd = fd;
			fncb(&ev);
		}
	}
}

/**
 * GrMainLoop:
 * @fncb:
 *
 * A convenience function which calls the specified callback function whenever
 * an event arrives or there is data to be read on a file descriptor previously
 * specified by GrRegisterInput(). Currently never returns.
 */
void
GrMainLoop(GR_FNCALLBACKEVENT fncb)
{
	fd_set	rfds;
	int	setsize = 0;

	for(;;) {
		FD_ZERO(&rfds);
		GrPrepareSelect(&setsize, &rfds);
		if(select(setsize+1, &rfds, NULL, NULL, NULL) > 0)
			GrServiceSelect(&rfds, fncb);
	}
}

/**
 * GrGetNextEvent:
 * @ep: pointer to the GR_EVENT structure to return the event in
 *
 * Gets the next event from the event queue and places it in the specified
 * GR_EVENT structure. If the queue is currently empty, we sleep until the
 * next event arrives from the server or input is read on a file descriptor
 * previously specified by GrRegisterInput().
 */
void 
GrGetNextEvent(GR_EVENT *ep)
{
	GrGetNextEventTimeout(ep, 0L);
}

/**
 * GrGetNextEventTimeout:
 * @ep: pointer to the GR_EVENT structure to return the event in
 * @timeout: the number of milliseconds to wait before timing out
 *
 * Gets the next event from the event queue and places it in the specified
 * GR_EVENT structure. If the queue is currently empty, we sleep until the
 * next event arrives from the server, input is read on a file descriptor
 * previously specified by GrRegisterInput(), or a timeout occurs. Note
 * that a value of 0 for the timeout parameter doesn't mean "timeout after 0
 * milliseconds" but is in fact a magic number meaning "never time out".
 */
void
GrGetNextEventTimeout(GR_EVENT *ep, GR_TIMEOUT timeout)
{
	fd_set		rfds;
	int		setsize = 0;
	int		e;
	struct timeval	to;
	ACCESS_PER_THREAD_DATA()

	if (evlist) {
		/*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/
		GetNextQueuedEvent(ep);
		CheckErrorEvent(ep);
		return;
	}

	FD_ZERO(&rfds);
	/*
	 * This will cause a GrGetNextEvent to be sent down the wire.
	 * If we timeout before the server responds, and then
	 * call this procedure again, and the server has more than
	 * one event waiting for this process, then more than one
	 * event will be written on the socket by the server.  At
	 * that point, a single stored event won't work, and the
	 * client needs an event queue.
	 */
	GrPrepareSelect(&setsize, &rfds);
	if (timeout) {
		to.tv_sec = timeout / 1000;
		to.tv_usec = (timeout % 1000) * 1000;
	}

	if((e = select(setsize+1, &rfds, NULL, NULL, timeout ? &to : NULL))>0) {
		int fd;

		if(FD_ISSET(nxSocket, &rfds)) {
			/*
			 * This will never be GR_EVENT_NONE with the current
			 * implementation.
			 */
		        GrTypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent);
			GrCheckForClientData(ep);
			CheckErrorEvent(ep);
			return;
		}

		/* check for input on registered file descriptors */
		for (fd = 0; fd < regfdmax; fd++) {
			if (FD_ISSET(fd, &regfdset) && FD_ISSET(fd, &rfds)) {
				ep->type = GR_EVENT_TYPE_FDINPUT;
				ep->fdinput.fd = fd;
				break;
			}
		}
	}
	else if (e == 0) {
		/*
		 * Timeout has occured. We currently return a timeout event
		 * regardless of whether the client has selected for it.
		 */
		ep->type = GR_EVENT_TYPE_TIMEOUT;
	} else {
		if(errno == EINTR) {
			ep->type = GR_EVENT_TYPE_NONE;
		} else {
			EPRINTF("nxclient: select failed\n");
			GrClose();
			exit(1);
		}
	}
}

/**
 * GrCheckNextEvent:
 * @ep: pointer to the GR_EVENT structure to return the event in
 *
 * Gets the next event from the event queue if there is one, or returns
 * immediately with an event type of GR_EVENT_TYPE_NONE if it is empty.
 */
void 
GrCheckNextEvent(GR_EVENT *ep)
{
	ACCESS_PER_THREAD_DATA()
	if (evlist) {
		/*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/
		GetNextQueuedEvent(ep);
		CheckErrorEvent(ep);
		return;
	}

	AllocReq(CheckNextEvent);
	GrTypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent);
	GrCheckForClientData(ep);
	CheckErrorEvent(ep);
}

/**
 * GrPeekEvent:
 * @ep: pointer to the GR_EVENT structure to return the event in
 * @Returns: 1 if an event was returned, or 0 if the queue was empty
 *
 * Fills in the specified event structure with a copy of the next event on the
 * queue, without actually removing it from the queue. An event type of
 * GR_EVENT_TYPE_NONE is given if the queue is empty.
 */
int 
GrPeekEvent(GR_EVENT *ep)
{
	int ret;
	ACCESS_PER_THREAD_DATA()

	if (evlist) {
		*ep = evlist->event;
		CheckErrorEvent(ep);
		return 1;
	}

	AllocReq(PeekEvent);
	GrTypedReadBlock(ep, sizeof(*ep),GrNumPeekEvent);
	GrCheckForClientData(ep);
	ret = GrReadByte();
	CheckErrorEvent(ep);
	return ret;
}

/**
 * GrPeekWaitEvent:
 * @ep: pointer to the GR_EVENT structure to return the event in
 *
 * Wait until an event is available for a client, and then peek at it.
 */
void
GrPeekWaitEvent(GR_EVENT *ep)
{
	EVENT_LIST *	elp;
	ACCESS_PER_THREAD_DATA()

	if (evlist) {
		*ep = evlist->event;
		CheckErrorEvent(ep);
		return;
	}

	/* no events, wait for next event*/
	GrGetNextEvent(ep);

	/* add event back on head of list*/
	elp = malloc(sizeof(EVENT_LIST));
	if (elp) {
		elp->event = *ep;
		elp->next = evlist;
	}

	/* peek at it*/
	GrPeekEvent(ep);
}

/**
 * GrSelectEvents:
 * @wid: the ID of the window to set the event mask of
 * @eventmask: a bit field specifying the desired event mask
 *
 * Select the event types which should be returned for the specified window.
 */
void 
GrSelectEvents(GR_WINDOW_ID wid, GR_EVENT_MASK eventmask)
{
	
	nxSelectEventsReq *req;

	req = AllocReq(SelectEvents);
	req->windowid = wid;
	req->eventmask = eventmask;
}

/**
 * GrNewWindow:
 * @parent: the ID of the parent window
 * @x: the X coordinate of the new window relative to the parent window
 * @y: the Y coordinate of the new window relative to the parent window
 * @width: the width of the new window
 * @height: the height of the new window
 * @bordersize: the width of the window border
 * @background: the colour of the window background
 * @bordercolor: the colour of the window border
 * @Returns: the ID of the newly created window

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -