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

📄 client.c

📁 一个linux下的根文件系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 */voidGrDelay(GR_TIMEOUT msecs){	struct timeval timeval;	timeval.tv_sec = msecs / 1000;	timeval.tv_usec = (msecs % 1000) * 1000;	select(0, NULL, NULL, NULL, &timeval);}/** * Fills in the specified GR_SCREEN_INFO structure. * * @param sip Pointer to a GR_SCREEN_INFO structure * * @ingroup nanox_general */void GrGetScreenInfo(GR_SCREEN_INFO *sip){	LOCK(&nxGlobalLock);	AllocReq(GetScreenInfo);	TypedReadBlock(sip, sizeof(GR_SCREEN_INFO),GrNumGetScreenInfo);	UNLOCK(&nxGlobalLock);}/** * Returns the colour at the specified index into the server's color 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 * * @param index An index into the server's colour look up table. * @return      The color found at the specified index. * * @ingroup nanox_color */GR_COLORGrGetSysColor(int index){	nxGetSysColorReq *req;	GR_COLOR color;	LOCK(&nxGlobalLock);	req = AllocReq(GetSysColor);	req->index = index;	if(TypedReadBlock(&color, sizeof(color),GrNumGetSysColor) == -1)		color = 0;	UNLOCK(&nxGlobalLock);	return color;}/** * Gets information about a font. * * @param font The font ID to query. * @param fip    Pointer to the GR_FONT_INFO structure to store the result. * * @ingroup nanox_font */void GrGetFontInfo(GR_FONT_ID font, GR_FONT_INFO *fip){	nxGetFontInfoReq *req;	LOCK(&nxGlobalLock);	req = AllocReq(GetFontInfo);	req->fontid = font;	TypedReadBlock(fip, sizeof(GR_FONT_INFO),GrNumGetFontInfo);	UNLOCK(&nxGlobalLock);}/** * Fills in the specified GR_GC_INFO structure with information regarding the * specified graphics context. * * @param gc   A graphics context. * @param gcip Pointer to a GR_GC_INFO structure to store the result. * * @ingroup nanox_draw */voidGrGetGCInfo(GR_GC_ID gc, GR_GC_INFO *gcip){	nxGetGCInfoReq *req;	LOCK(&nxGlobalLock);	req = AllocReq(GetGCInfo);	req->gcid = gc;	TypedReadBlock(gcip, sizeof(GR_GC_INFO),GrNumGetGCInfo);	UNLOCK(&nxGlobalLock);}/** * Calculates the dimensions of a specified text string.  Uses the current font * and flags in the specified graphics context. The count argument can be -1 * if the string is null terminated. * * @param gc        The graphics context. * @param str       Pointer to a text string. * @param count     The length of the string. * @param flags     Text rendering flags. (GR_TF*). * @param retwidth  Pointer to the variable the width will be returned in. * @param retheight Pointer to the variable the height will be returned in. * @param retbase   Pointer to the variable the baseline height will be returned in. * * @ingroup nanox_font */voidGrGetGCTextSize(GR_GC_ID gc, void *str, int count, GR_TEXTFLAGS flags,	GR_SIZE *retwidth, GR_SIZE *retheight, GR_SIZE *retbase){	nxGetGCTextSizeReq *req;	int size;	/* use strlen as char count when ascii or dbcs*/	if(count == -1 && (flags&MWTF_PACKMASK) == MWTF_ASCII)		count = strlen((char *)str);	size = nxCalcStringBytes(str, count, flags);	LOCK(&nxGlobalLock);	req = AllocReqExtra(GetGCTextSize, size);	req->gcid = gc;	req->flags = flags;	req->charcount = count;	memcpy(GetReqData(req), str, size);	TypedReadBlock(retwidth, sizeof(*retwidth),GrNumGetGCTextSize);	ReadBlock(retheight, sizeof(*retheight));	ReadBlock(retbase, sizeof(*retbase));	UNLOCK(&nxGlobalLock);}/** * 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. * * @param fd The file descriptor to monitor. * * @ingroup nanox_event */void GrRegisterInput(int fd){	ACCESS_PER_THREAD_DATA()	if (fd < 0)		return;	LOCK(&nxGlobalLock);	FD_SET(fd, &regfdset);	if (fd >= regfdmax) regfdmax = fd + 1;	UNLOCK(&nxGlobalLock);}/** * Stop monitoring a file descriptor previously registered with * GrRegisterInput(). * * @param fd The file descriptor to stop monitoring. * * @ingroup nanox_event */voidGrUnregisterInput(int fd){	int i, max;	ACCESS_PER_THREAD_DATA()	LOCK(&nxGlobalLock);	/* unregister all inputs if fd is -1 */	if (fd == -1) {		FD_ZERO(&regfdset);		regfdmax = -1;		UNLOCK(&nxGlobalLock);		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;	UNLOCK(&nxGlobalLock);}/** * Prepare for the client to call select().  Asks the server to send the next * event but does not wait around for it to arrive.  Initializes 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. * * Usually used in conjunction with GrServiceSelect(). * * Note that in a multithreaded client, the application must ensure that * no Nano-X calls are made between the calls to GrPrepareSelect() and * GrServiceSelect(), else there will be race conditions. * * @param maxfd  Pointer to a variable which the highest in use fd will be *               written to.  Must contain a valid value on input - will only *               be overwritten if the new value is higher than the old *               value. * @param rfdset Pointer to the file descriptor set structure to use.  Must *               be valid on input - file descriptors will be added to this *               set without clearing the previous contents. * * @ingroup nanox_event */voidGrPrepareSelect(int *maxfd,void *rfdset){	fd_set *rfds = rfdset;	int fd;	ACCESS_PER_THREAD_DATA()	LOCK(&nxGlobalLock);	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;		}	}	UNLOCK(&nxGlobalLock);}/** * Handles events after the client has done a select() call. * * Calls the specified callback function is an event has arrived, or if * there is data waiting on an external fd specified by GrRegisterInput(). * * Used by GrMainLoop(). * * @param rfdset Pointer to the file descriptor set containing those file *               descriptors that are ready for reading. * @param fncb   Pointer to the function to call when an event needs handling. * * @ingroup nanox_event */voidGrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb){	fd_set *	rfds = rfdset;	int		fd;	GR_EVENT 	ev;	ACCESS_PER_THREAD_DATA()	LOCK(&nxGlobalLock);        /* 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)) {			TypedReadBlock(&ev, sizeof(ev),GrNumGetNextEvent);			CheckForClientData(&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);		}	}	UNLOCK(&nxGlobalLock);}/** * An infinite loop that dispatches events.  Calls the specified callback * function whenever an event arrives or there is data to be read on a file * descriptor registered with GrRegisterInput(). Never returns. * * @param fncb Pointer to the function to call when an event needs handling. * * @ingroup nanox_event */voidGrMainLoop(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);	}}/** * Queue an event in FIFO for later retrieval. * * @param ep The event to queue * * @internal */static voidQueueEvent(GR_EVENT *ep){	EVENT_LIST *	elp;	EVENT_LIST *	prevelp;        ACCESS_PER_THREAD_DATA()	elp = malloc(sizeof(EVENT_LIST));	if (elp) {		elp->event = *ep;		elp->next = NULL;		/* add as last entry on list*/		if (!evlist) {			evlist = elp;			return;		}		prevelp = evlist;		while (prevelp->next)			prevelp = prevelp->next;		prevelp->next = elp;	}}/** * Retrieve first event in FIFO event queue.  FIFO must not be empty. * * @param ep Destination for event. * * @internal */static voidGetNextQueuedEvent(GR_EVENT *ep){	EVENT_LIST	*elp;        ACCESS_PER_THREAD_DATA()	*ep = evlist->event;	elp = evlist;	evlist = evlist->next;	free(elp);}/** * Gets the next event from the event queue.  If the queue is currently * empty, sleeps until the next event arrives from the server or input * is read on a file descriptor previously specified by GrRegisterInput(). * * @param ep Pointer to the GR_EVENT structure to return the event in. * * @ingroup nanox_event */void GrGetNextEvent(GR_EVENT *ep){	GrGetNextEventTimeout(ep, 0L);}/** * Gets the next event from the event queue, with a time limit.  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". * * @param ep      Pointer to the GR_EVENT structure to return the event in. * @param timeout The number of milliseconds to wait before timing out, or *                0 for forever. * * @ingroup nanox_event */voidGrGetNextEventTimeout(GR_EVENT * ep, GR_TIMEOUT timeout){	LOCK(&nxGlobalLock);	if (evlist) {		/*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/		GetNextQueuedEvent(ep);		CheckErrorEvent(ep);		UNLOCK(&nxGlobalLock);		return;	}	_GrGetNextEventTimeout(ep,timeout);	UNLOCK(&nxGlobalLock);}/** * Sleep until the next event arrives, possibly with a time limit. * The SERVER_LOCK() must be held and the event queue must be empty * before calling this function. * * Sleeps 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". * * @param ep      Pointer to the GR_EVENT structure to return the event in. * @param timeout The number of milliseconds to wait before timing out, or *                0 for forever. * * @internal */static void_GrGetNextEventTimeout(GR_EVENT *ep, GR_TIMEOUT timeout){	fd_set		rfds;	int		setsize = 0;	int		e;	struct timeval	to;	ACCESS_PER_THREAD_DATA()	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.			 */		        TypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent);			CheckForClientData(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);		}	}}/** * Gets a copy of the next event on the queue, without actually * removing it from the queue.  Does not block - an event type of * GR_EVENT_TYPE_NONE is given if the queue is empty. * * @param ep Pointer to the GR_EVENT structure to return the event in. * @return   1 if an event was returned, or 0 if the queue was empty. * * @ingroup nanox_event */int GrPeekEvent(GR_EVENT *ep){	int ret;	ACCESS_PER_THREAD_DATA()	LOCK(&nxGlobalLock);	if (evlist) {		*ep = evlist->event;		CheckErrorEvent(ep);		UNLOCK(&nxGlobalLock);		return 1;	}	ret = _GrPeekEvent(ep);	UNLOCK(&nxGlobalLock);	return ret;}

⌨️ 快捷键说明

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