📄 srvmain.c
字号:
/* * Copyright (c) 1999, 2000, 2001, 2003 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V. * Copyright (c) 1991 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * Main module of graphics server. */#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>#ifdef __PACIFIC__#include <unixio.h>#else#include <errno.h>#include <sys/types.h>#endif#ifdef DOS_TURBOC#include <io.h>#endif#define MWINCLUDECOLORS#include "serv.h"#if UNIX | DOS_DJGPP#include <unistd.h>#if _MINIX#include <sys/times.h>#else#include <sys/time.h>#endif#endif#if ELKS#include <linuxmt/posix_types.h>#include <linuxmt/time.h>#endif/* * External definitions defined here. */GR_WINDOW_ID cachewindowid; /* cached window id */GR_WINDOW_ID cachepixmapid; /* cached pixmap id */GR_GC_ID cachegcid; /* cached graphics context id */GR_WINDOW *cachewp; /* cached window pointer */GR_GC *cachegcp; /* cached graphics context */GR_PIXMAP *cachepp; /* cached pixmap */GR_PIXMAP *listpp; /* List of all pixmaps */GR_WINDOW *listwp; /* list of all windows */GR_WINDOW *rootwp; /* root window pointer */GR_GC *listgcp; /* list of all gc */GR_REGION *listregionp; /* list of all regions */GR_FONT *listfontp; /* list of all fonts */#if MW_FEATURE_IMAGESGR_IMAGE *listimagep; /* list of all images */#endifGR_CURSOR *listcursorp; /* list of all cursors */GR_CURSOR *stdcursor; /* root window cursor */GR_GC *curgcp; /* currently enabled gc */GR_WINDOW *clipwp; /* window clipping is set for */GR_WINDOW *focuswp; /* focus window for keyboard */GR_WINDOW *mousewp; /* window mouse is currently in */GR_WINDOW *grabbuttonwp; /* window grabbed by button */GR_CURSOR *curcursor; /* currently enabled cursor */GR_COORD cursorx; /* current x position of cursor */GR_COORD cursory; /* current y position of cursor */GR_BUTTON curbuttons; /* current state of buttons */GR_CLIENT *curclient; /* client currently executing for */GR_EVENT_LIST *eventfree; /* list of free events */GR_BOOL focusfixed; /* TRUE if focus is fixed on a window */PMWFONT stdfont; /* default font*/int escape_quits = TRUE; /* terminate when pressing ESC */char *progname; /* Name of this program.. */int current_fd; /* the fd of the client talking to */int connectcount = 0; /* number of connections to server */GR_CLIENT *root_client; /* root entry of the client table */GR_CLIENT *current_client; /* the client we are currently talking*/char *current_shm_cmds;int current_shm_cmds_size;int keyb_fd; /* the keyboard file descriptor */int mouse_fd; /* the mouse file descriptor */char *curfunc; /* the name of the current server func*/GR_BOOL screensaver_active; /* time before screensaver activates */GR_SELECTIONOWNER selection_owner; /* the selection owner and typelist */GR_TIMEOUT startTicks; /* ms time server started*/int autoportrait = FALSE; /* auto portrait mode switching*/MWCOORD nxres; /* requested server x resolution*/MWCOORD nyres; /* requested server y resolution*/#if MW_FEATURE_TIMERSGR_TIMEOUT screensaver_delay; /* time before screensaver activates */GR_TIMER_ID cache_timer_id; /* cached timer ID */GR_TIMER *cache_timer; /* cached timer */GR_TIMER *list_timer; /* list of all timers */#endif /* MW_FEATURE_TIMERS */GR_GRABBED_KEY *list_grabbed_keys = NULL; /* list of all grabbed keys */static int persistent_mode = FALSE;static int portraitmode = MWPORTRAIT_NONE;SERVER_LOCK_DECLARE /* Mutex for all public functions (only if NONETWORK and THREADSAFE) */#if !NONETWORKint un_sock; /* the server socket descriptor */static voidusage(void){ printf("Usage: %s [-e] [-p] [-A] [-NLRD] [-x#] [-y#] [-c <fontconfig-file> ...]\n", progname); exit(1);}/* * This is the main server loop which initialises the server, services * the clients, and shuts the server down when there are no more clients. */intmain(int argc, char *argv[]){ int t; progname = argv[0]; t = 1; while ( t < argc ) { if ( !strcmp("-e",argv[t])) { escape_quits = FALSE; ++t; continue; } if ( !strcmp("-p",argv[t]) ) { persistent_mode = TRUE; ++t; continue; } if ( !strcmp("-A",argv[t]) ) { autoportrait = TRUE; ++t; continue; } if ( !strcmp("-N",argv[t]) ) { portraitmode = MWPORTRAIT_NONE; ++t; continue; } if ( !strcmp("-L",argv[t]) ) { portraitmode = MWPORTRAIT_LEFT; ++t; continue; } if ( !strcmp("-R",argv[t]) ) { portraitmode = MWPORTRAIT_RIGHT; ++t; continue; } if ( !strcmp("-D",argv[t]) ) { portraitmode = MWPORTRAIT_DOWN; ++t; continue; } if ( !strcmp("-x",argv[t]) ) { if (++t >= argc) usage(); nxres = atoi(argv[t]); ++t; continue; } if ( !strcmp("-y",argv[t]) ) { if (++t >= argc) usage(); nyres = atoi(argv[t]); ++t; continue; }#if FONTMAPPER if ( !strcmp("-c",argv[t]) ) { int read_configfile(char *file); if (++t >= argc) usage(); read_configfile(argv[t]); ++t; continue; }#endif usage(); } /* Attempt to initialise the server*/ if(GsInitialize() < 0) exit(1); while(1) GsSelect(0L); return 0;}#endifvoidGsAcceptClientFd(int i){ GR_CLIENT *client, *cl; if(!(client = malloc(sizeof(GR_CLIENT)))) { close(i); return; } client->id = i; client->eventhead = NULL; client->eventtail = NULL; /*client->errorevent.type = GR_EVENT_TYPE_NONE;*/ client->next = NULL; client->prev = NULL; client->waiting_for_event = FALSE; client->shm_cmds = 0; if(connectcount++ == 0) root_client = client; else { cl = root_client; while(cl->next) cl = cl->next; client->prev = cl; cl->next = client; }}/* * Open a connection from a new client to the server. * Returns -1 on failure. */intGrOpen(void){#if NONETWORK SERVER_LOCK(); escape_quits = 1; /* Client calls this routine once. We * init everything here */ if (connectcount <= 0) { if(GsInitialize() < 0) { SERVER_UNLOCK(); return -1; } GsAcceptClientFd(999); curclient = root_client; } SERVER_UNLOCK();#endif return 1;}/* * Close the current connection to the server. */voidGrClose(void){ SERVER_LOCK(); GsClose(current_fd); SERVER_UNLOCK();}/* * Drop a specific server connection. */voidGsClose(int fd){ GsDropClient(fd); if(!persistent_mode && connectcount == 0) GsTerminate();}#if NONETWORK/* client/server GsDropClient is in srvnet.c*/voidGsDropClient(int fd){ --connectcount;}#endif#if UNIX | DOS_DJGPP#if NONETWORK && defined(HAVESELECT)/* * Register the specified file descriptor to return an event * when input is ready. */static int regfdmax = -1;static fd_set regfdset;voidGrRegisterInput(int fd){ SERVER_LOCK(); FD_SET(fd, ®fdset); if (fd >= regfdmax) regfdmax = fd + 1; SERVER_UNLOCK();}voidGrUnregisterInput(int fd){ int i, max; SERVER_LOCK(); /* unregister all inputs if the FD is -1 */ if (fd == -1) { FD_ZERO(®fdset); regfdmax = -1; SERVER_UNLOCK(); return; } FD_CLR(fd, ®fdset); /* recalculate the max file descriptor */ for (i = 0, max = regfdmax, regfdmax = -1; i < max; i++) if (FD_ISSET(i, ®fdset)) regfdmax = i + 1; SERVER_UNLOCK();}#endif /* NONETWORK && HAVESELECT */#endif /* UNIX | DOS_DJGPP*//* * This function suspends execution of the program for the specified * number of milliseconds. */voidGrDelay(GR_TIMEOUT msecs){#if UNIX struct timeval timeval; timeval.tv_sec = msecs / 1000; timeval.tv_usec = (msecs % 1000) * 1000; select(0, NULL, NULL, NULL, &timeval);#endif}#if NONETWORKvoidGrFlush(void){}voidGrMainLoop(GR_FNCALLBACKEVENT fncb){ GR_EVENT event; for(;;) { GrGetNextEvent(&event); fncb(&event); }}voidGrReqShmCmds(long shmsize){ /* no action required, no client/server*/}#endif#if VXWORKS#define POLLTIME 100 /* polling sleep interval (in msec) */#define MAX_MOUSEEVENTS 10 /* max number of mouse event to get in 1 select */#define MAX_KEYBDEVENTS 10 /* max number of mouse event to get in 1 select */extern void GdSleep(int dwMilliseconds);void GsSelect(GR_TIMEOUT timeout){ int mouseevents = 0; int keybdevents = 0; GR_TIMEOUT waittime = 0; GR_EVENT_GENERAL *gp; /* input gathering loop */ while (1) { /* perform pre-select duties, if any */ if(scrdev.PreSelect) { scrdev.PreSelect(&scrdev); } /* If mouse data present, service it */ while (mousedev.Poll() > 0) { GsCheckMouseEvent(); if (mouseevents++ > MAX_MOUSEEVENTS) { /* don't handle too many events at one shot */ break; } } /* If keyboard data present, service it */ while (kbddev.Poll() > 0) { GsCheckKeyboardEvent(); if (keybdevents++ > MAX_KEYBDEVENTS) { /* don't handle too many events at one shot */ break; } } /* did we process any input yet? */ if ((mouseevents > 0) || (keybdevents > 0)) { /* yep -- return without sleeping */ return; } /* give up time-slice & sleep for a bit */ GdSleep(POLLTIME); waittime += POLLTIME; /* have we timed out? */ if (waittime >= timeout) { /* special case: polling when timeout == 0 -- don't send timeout event */ if (timeout != 0) { /* Timeout has occured. ** Currently return a timeout event regardless of whether client ** has selected for it. */ if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) != NULL) { gp->type = GR_EVENT_TYPE_TIMEOUT; } } return; } }}#elif MSDOS | _MINIXvoidGsSelect(GR_TIMEOUT timeout){ /* If mouse data present, service it*/ if(mousedev.Poll()) while(GsCheckMouseEvent()) continue; /* If keyboard data present, service it*/ if(kbddev.Poll()) while(GsCheckKeyboardEvent()) continue;}#elif UNIX && defined(HAVESELECT)voidGsSelect(GR_TIMEOUT timeout){ fd_set rfds; int e; int setsize = 0; struct timeval tout; struct timeval *to;#if NONETWORK int fd;#endif /* perform pre-select duties, if any*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -