📄 srvmain.c
字号:
if(rootwp->psd->PreSelect) rootwp->psd->PreSelect(rootwp->psd); /* Set up the FDs for use in the main select(): */ FD_ZERO(&rfds); if(mouse_fd >= 0) { FD_SET(mouse_fd, &rfds); if (mouse_fd > setsize) setsize = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, &rfds); if (keyb_fd > setsize) setsize = keyb_fd; }#if NONETWORK /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, &rfds); if (fd > setsize) setsize = fd; }#else /* not NONETWORK */ /* handle client socket connections*/ FD_SET(un_sock, &rfds); if (un_sock > setsize) setsize = un_sock; curclient = root_client; while(curclient) { if(curclient->waiting_for_event && curclient->eventhead) { curclient->waiting_for_event = FALSE; GrGetNextEventWrapperFinish(curclient->id); return; } FD_SET(curclient->id, &rfds); if(curclient->id > setsize) setsize = curclient->id; curclient = curclient->next; }#endif /* NONETWORK */ /* Set up the timeout for the main select(): */ if (timeout == (GR_TIMEOUT) -1L) { /* poll*/ tout.tv_sec = 0; tout.tv_usec = 0; to = &tout; } else {#if MW_FEATURE_TIMERS if(GdGetNextTimeout(&tout, timeout) == TRUE) to = &tout; else#endif /* MW_FEATURE_TIMERS */ to = NULL; } /* Wait for some input on any of the fds in the set or a timeout: */ if((e = select(setsize+1, &rfds, NULL, NULL, to)) > 0) { /* If data is present on the mouse fd, service it: */ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds)) while(GsCheckMouseEvent()) continue; /* If data is present on the keyboard fd, service it: */ if(keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds)) while(GsCheckKeyboardEvent()) continue;#if NONETWORK /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { GR_EVENT_FDINPUT * gp; if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, &rfds)) continue; gp =(GR_EVENT_FDINPUT *)GsAllocEvent(curclient); if(gp) { gp->type = GR_EVENT_TYPE_FDINPUT; gp->fd = fd; } }#else /* not NONETWORK */ /* If a client is trying to connect, accept it: */ if(FD_ISSET(un_sock, &rfds)) GsAcceptClient(); /* If a client is sending us a command, handle it: */ curclient = root_client; while(curclient) { GR_CLIENT *curclient_next; /* curclient may be freed in GsDropClient*/ curclient_next = curclient->next; if(FD_ISSET(curclient->id, &rfds)) GsHandleClient(curclient->id); curclient = curclient_next; }#endif /* NONETWORK */ } else if (e == 0) {#if NONETWORK /* * Timeout has occured. Currently return * a timeout event regardless of whether * client has selected for it. * Note: this will be changed back to GR_EVENT_TYPE_NONE * for the GrCheckNextEvent/LINK_APP_TO_SERVER case */#if MW_FEATURE_TIMERS if(GdTimeout() == TRUE)#endif { GR_EVENT_GENERAL * gp; gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient); if(gp) gp->type = GR_EVENT_TYPE_TIMEOUT; }#else /* not NONETWORK */#if MW_FEATURE_TIMERS GdTimeout();#endif#endif /* NONETWORK */ } else if(errno != EINTR) EPRINTF("Select() call in main failed\n");}#if NONETWORK/* * 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. */voidGrPrepareSelect(int *maxfd, void *rfdset){ fd_set *rfds = (fd_set *) rfdset; int fd; SERVER_LOCK(); /* perform pre-select duties, if any*/ if(rootwp->psd->PreSelect) rootwp->psd->PreSelect(rootwp->psd); if(mouse_fd >= 0) { FD_SET(mouse_fd, rfds); if (mouse_fd > *maxfd) *maxfd = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, rfds); if (keyb_fd > *maxfd) *maxfd = keyb_fd; } /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, rfds); if (fd > *maxfd) *maxfd = fd; } SERVER_UNLOCK();}/* * 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. */voidGrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb){ fd_set * rfds = rfdset; GR_EVENT_LIST * elp; GR_EVENT ev; int fd; SERVER_LOCK(); /* If data is present on the mouse fd, service it: */ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, rfds)) while(GsCheckMouseEvent()) continue; /* If data is present on the keyboard fd, service it: */ if(keyb_fd >= 0 && FD_ISSET(keyb_fd, rfds)) while(GsCheckKeyboardEvent()) continue; /* Dispatch all queued events */ while((elp = curclient->eventhead) != NULL) { ev = elp->event; /* Remove first event from queue*/ curclient->eventhead = elp->next; if (curclient->eventtail == elp) curclient->eventtail = NULL; elp->next = eventfree; eventfree = elp; fncb(&ev); } /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, rfds)) continue; ev.type = GR_EVENT_TYPE_FDINPUT; ev.fdinput.fd = fd; fncb(&ev); } SERVER_UNLOCK();}#endif /* NONETWORK */#endif /* UNIX && defined(HAVESELECT)*/#if VTSWITCHstatic voidCheckVtChange(void *arg){ if(MwCheckVtChange()) GsRedrawScreen(); GdAddTimer(50, CheckVtChange, NULL);}#endif /* * Initialize the graphics and mouse devices at startup. * Returns nonzero with a message printed if the initialization failed. */intGsInitialize(void){ GR_WINDOW *wp; /* root window */ PSD psd; GR_CURSOR_ID cid; static MWIMAGEBITS cursorbits[16] = { 0xe000, 0x9800, 0x8600, 0x4180, 0x4060, 0x2018, 0x2004, 0x107c, 0x1020, 0x0910, 0x0988, 0x0544, 0x0522, 0x0211, 0x000a, 0x0004 }; static MWIMAGEBITS cursormask[16] = { 0xe000, 0xf800, 0xfe00, 0x7f80, 0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc, 0x1fe0, 0x0ff0, 0x0ff8, 0x077c, 0x073e, 0x021f, 0x000e, 0x0004 }; /* If needed, initialize the server mutex. */ SERVER_LOCK_INIT(); setbuf(stdout, NULL); setbuf(stderr, NULL); wp = (GR_WINDOW *) malloc(sizeof(GR_WINDOW)); if (wp == NULL) { EPRINTF("Cannot allocate root window\n"); return -1; } startTicks = GsGetTickCount();#ifndef MW_NOSIGNALS /* catch terminate signal to restore tty state*/ signal(SIGTERM, (void *)GsTerminate);#endif#if MW_FEATURE_TIMERS screensaver_delay = 0;#endif screensaver_active = GR_FALSE; selection_owner.wid = 0; selection_owner.typelist = NULL;#if !NONETWORK#ifndef MW_NOSIGNALS /* ignore pipe signal, sent when clients exit*/ signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN);#endif if (GsOpenSocket() < 0) { EPRINTF("Cannot bind to named socket\n"); free(wp); return -1; }#endif if ((keyb_fd = GdOpenKeyboard()) == -1) { EPRINTF("Cannot initialise keyboard\n"); /*GsCloseSocket();*/ free(wp); return -1; } if ((psd = GdOpenScreen()) == NULL) { EPRINTF("Cannot initialise screen\n"); /*GsCloseSocket();*/ GdCloseKeyboard(); free(wp); return -1; } GdSetPortraitMode(psd, portraitmode); if ((mouse_fd = GdOpenMouse()) == -1) { EPRINTF("Cannot initialise mouse\n"); /*GsCloseSocket();*/ GdCloseScreen(psd); GdCloseKeyboard(); free(wp); return -1; } /* * Create std font. */#if (HAVE_BIG5_SUPPORT | HAVE_GB2312_SUPPORT | HAVE_JISX0213_SUPPORT | HAVE_KSC5601_SUPPORT) /* system fixed font looks better when mixed with builtin fixed fonts*/ stdfont = GdCreateFont(psd, MWFONT_SYSTEM_FIXED, 0, NULL);#else stdfont = GdCreateFont(psd, MWFONT_SYSTEM_VAR, 0, NULL);#endif /* * Initialize the root window. */ wp->psd = psd; wp->id = GR_ROOT_WINDOW_ID; wp->parent = NULL; /* changed: was = NULL*/ wp->owner = NULL; wp->children = NULL; wp->siblings = NULL; wp->next = NULL; wp->x = 0; wp->y = 0; wp->width = psd->xvirtres; wp->height = psd->yvirtres; wp->bordersize = 0; wp->background = BLACK; wp->bordercolor = wp->background; wp->nopropmask = 0; wp->bgpixmap = NULL; wp->bgpixmapflags = GR_BACKGROUND_TILE; wp->eventclients = NULL; wp->cursorid = 0; wp->mapped = GR_TRUE; wp->realized = GR_TRUE; wp->output = GR_TRUE; wp->props = 0; wp->title = NULL; wp->clipregion = NULL; listpp = NULL; listwp = wp; rootwp = wp; focuswp = wp; mousewp = wp; focusfixed = GR_FALSE; /* * Initialize and position the default cursor. */ curcursor = NULL; cursorx = -1; cursory = -1; GdShowCursor(psd); GrMoveCursor(psd->xvirtres / 2, psd->yvirtres / 2); cid = GrNewCursor(16, 16, 0, 0, WHITE, BLACK, cursorbits, cursormask); GrSetWindowCursor(GR_ROOT_WINDOW_ID, cid); stdcursor = GsFindCursor(cid);#if VTSWITCH MwInitVt(); /* Check for VT change every 50 ms: */ GdAddTimer(50, CheckVtChange, NULL);#endif psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1, GdFindColor(psd, wp->background)); /* * Tell the mouse driver some things. */ curbuttons = 0; GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1); GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2); /* Force root window screen paint*/ GsRedrawScreen(); /* * Force the cursor to appear on the screen at startup. * (not required with above GsRedrawScreen) GdHideCursor(psd); GdShowCursor(psd); */ /* * All done. */ connectcount = 0; return 0;}/* * Here to close down the server. */voidGsTerminate(void){#if !NONETWORK GsCloseSocket();#endif GdCloseScreen(rootwp->psd); GdCloseMouse(); GdCloseKeyboard();#if VTSWITCH MwRedrawVt(mwvterm);#endif exit(0);}/* * Return # milliseconds elapsed since start of Microwindows * Granularity is 25 msec */GR_TIMEOUTGsGetTickCount(void){#if MSDOS#include <time.h> return (unsigned long)(clock() * 1000 / CLOCKS_PER_SEC);#else#if _MINIX struct tms t; return (unsigned long)times(&t) * 16;#else#if UNIX struct timeval t; gettimeofday(&t, NULL); return ((t.tv_sec * 1000) + (t.tv_usec / 25000) * 25) - startTicks;#else return 0L;#endif#endif#endif}voidGrBell(void){ SERVER_LOCK(); write(2, "\7", 1); SERVER_UNLOCK();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -