📄 srvmain.c
字号:
/*
* Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
* 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 DOS_DJGPP
typedef unsigned long DWORD; /* FIXME why is this here?*/
#endif
#if ELKS
#include <linuxmt/posix_types.h>
#include <linuxmt/time.h>
#endif
#ifdef __ECOS
# include <pkgconf/system.h>
# include <pkgconf/microwindows.h>
# ifdef CYGPKG_NET
# define NONETWORK 0
# else
# error Not yet supported.
# define NONETWORK 1
# endif
#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 */
GR_IMAGE *listimagep; /* list of all images */
GR_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 */
int 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 = 1; /* 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_TIMEOUT screensaver_delay; /* time before screensaver activates */
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*/
GR_TIMER_ID cache_timer_id; /* cached timer ID */
GR_TIMER *cache_timer; /* cached timer */
GR_TIMER *list_timer; /* list of all timers */
static int persistent_mode = 0;
static int portraitmode = MWPORTRAIT_NONE;
#if !NONETWORK
int un_sock; /* the server socket descriptor */
static void
usage(void)
{
fprintf(stderr,"Usage: %s [-e] [-p] [-N] [-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.
*/
#ifdef __ECOS
int
nanox_main(int argc, char *argv[])
#else
int
main(int argc, char *argv[])
#endif
{
int t;
int read_configfile(char *file);
progname = argv[0];
t = 1;
while ( t < argc ) {
if ( !strcmp("-e",argv[t])) {
escape_quits = 0;
t++;
continue;
}
if ( !strcmp("-p",argv[t]) ) {
persistent_mode = 1;
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 FONTMAPPER
if ( !strcmp("-c",argv[t]) ) {
if ( t+1 >= argc )
usage();
read_configfile(argv[t+1]);
t += 2;
continue;
}
#endif
usage();
}
/* Attempt to initialise the server*/
if(GsInitialize() < 0)
exit(1);
while(1)
GsSelect(0L);
return 0;
}
#endif
void
GsAcceptClientFd(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.
*/
int
GrOpen(void)
{
#if NONETWORK
escape_quits = 1;
/* Client calls this routine once. We
* init everything here
*/
if (connectcount <= 0) {
if(GsInitialize() < 0)
return -1;
GsAcceptClientFd(999);
curclient = root_client;
}
#endif
return 1;
}
/*
* Close the current connection to the server.
*/
void
GrClose(void)
{
GsClose(current_fd);
}
/*
* Drop a specific server connection.
*/
void
GsClose(int fd)
{
GsDropClient(fd);
if(!persistent_mode && connectcount == 0)
GsTerminate();
}
#if NONETWORK
/* client/server GsDropClient is in srvnet.c*/
void
GsDropClient(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;
void
GrRegisterInput(int fd)
{
FD_SET(fd, ®fdset);
if (fd > regfdmax) regfdmax = fd + 1;
}
void
GrUnregisterInput(int fd)
{
int i, max;
/* unregister all inputs if the FD is -1 */
if (fd == -1) {
FD_ZERO(®fdset);
regfdmax = -1;
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;
}
#endif /* NONETWORK && HAVESELECT */
#endif /* UNIX | DOS_DJGPP*/
/*
* This function suspends execution of the program for the specified
* number of milliseconds.
*/
void
GrDelay(GR_TIMEOUT msecs)
{
#if UNIX
struct timeval timeval;
timeval.tv_sec = msecs / 1000;
timeval.tv_usec = msecs % 1000;
select(0, NULL, NULL, NULL, &timeval);
#endif
}
#if NONETWORK
void
GrFlush(void)
{
}
void
GrMainLoop(GR_FNCALLBACKEVENT fncb)
{
GR_EVENT event;
for(;;) {
GrGetNextEvent(&event);
fncb(&event);
}
}
void
GrReqShmCmds(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 | _MINIX
void
GsSelect(GR_TIMEOUT timeout)
{
/* If mouse data present, service it*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -