📄 srvnet.c
字号:
/*
* Copyright (c) 1999-2001 Greg Haerr <greg@censoft.com>
* Copyright (c) 1999 Alex Holden <alex@linuxhacker.org>
* Copyright (c) 2000 Vidar Hokstad
* Copyright (c) 2000 Morten Rolland <mortenro@screenmedia.no>
* Portions Copyright (c) 1991 David I. Bell
*
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* Completely rewritten for speed by Greg Haerr
*
* This is the server side of the network interface, which accepts
* connections from clients, receives functions from them, and dispatches
* events to them.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#if HAVE_SHAREDMEM_SUPPORT
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#if ELKS
#include <linuxmt/na.h>
#elif __ECOS
#include <netinet/in.h>
#else
#include <sys/un.h>
#endif
#include "serv.h"
#include "nxproto.h"
/* fix bad MIPS sys headers...*/
#ifndef SOCK_STREAM
#define SOCK_STREAM 2 /* <asm/socket.h>*/
#endif
extern int un_sock;
extern GR_CLIENT *root_client;
extern int current_fd;
static int GsWriteType(int,short);
/*
* Wrapper functions called after full packet read
*/
static void
GrOpenWrapper(void *r)
{
nxOpenReq *req = r;
/* store process id of client*/
curclient->processid = req->pid;
GrOpen();
}
static void
GrCloseWrapper(void *r)
{
GrClose();
}
static void
GrGetScreenInfoWrapper(void *r)
{
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
GsWriteType(current_fd,GrNumGetScreenInfo);
GsWrite(current_fd, &si, sizeof(si));
}
static void
GrGetSysColorWrapper(void *r)
{
nxGetSysColorReq *req = r;
GR_COLOR color = GrGetSysColor(req->index);
GsWriteType(current_fd, GrNumGetSysColor);
GsWrite(current_fd, &color, sizeof(color));
}
static void
GrNewWindowWrapper(void *r)
{
nxNewWindowReq *req = r;
GR_WINDOW_ID wid;
wid = GrNewWindow(req->parentid, req->x, req->y, req->width,
req->height, req->bordersize, req->backgroundcolor,
req->bordercolor);
GsWriteType(current_fd,GrNumNewWindow);
GsWrite(current_fd, &wid, sizeof(wid));
}
static void
GrNewPixmapWrapper(void *r)
{
nxNewPixmapReq *req = r;
GR_WINDOW_ID wid;
/* FIXME: Add support for passing info about shared memory
* segment
*/
wid = GrNewPixmap(req->width, req->height, 0);
GsWriteType(current_fd,GrNumNewPixmap);
GsWrite(current_fd, &wid, sizeof(wid));
}
static void
GrNewInputWindowWrapper(void *r)
{
nxNewInputWindowReq *req = r;
GR_WINDOW_ID wid;
wid = GrNewInputWindow(req->parentid, req->x, req->y, req->width,
req->height);
GsWriteType(current_fd,GrNumNewInputWindow);
GsWrite(current_fd, &wid, sizeof(wid));
}
static void
GrDestroyWindowWrapper(void *r)
{
nxDestroyWindowReq *req = r;
GrDestroyWindow(req->windowid);
}
static void
GrNewGCWrapper(void *r)
{
GR_GC_ID gc = GrNewGC();
GsWriteType(current_fd,GrNumNewGC);
GsWrite(current_fd, &gc, sizeof(gc));
}
static void
GrCopyGCWrapper(void *r)
{
nxCopyGCReq *req = r;
GR_GC_ID gcnew;
gcnew = GrCopyGC(req->gcid);
GsWriteType(current_fd,GrNumCopyGC);
GsWrite(current_fd, &gcnew, sizeof(gcnew));
}
static void
GrGetGCInfoWrapper(void *r)
{
nxGetGCInfoReq *req = r;
GR_GC_INFO gcinfo;
GrGetGCInfo(req->gcid, &gcinfo);
GsWriteType(current_fd,GrNumGetGCInfo);
GsWrite(current_fd, &gcinfo, sizeof(gcinfo));
}
static void
GrDestroyGCWrapper(void *r)
{
nxDestroyGCReq *req = r;
GrDestroyGC(req->gcid);
}
static void
GrNewRegionWrapper(void *r)
{
GR_REGION_ID region = GrNewRegion();
GsWriteType(current_fd, GrNumNewRegion);
GsWrite(current_fd, ®ion, sizeof(region));
}
static void
GrDestroyRegionWrapper(void *r)
{
nxDestroyRegionReq *req = r;
GrDestroyRegion(req->regionid);
}
static void
GrIntersectRegionWrapper(void *r)
{
nxIntersectRegionReq *req = r;
GrIntersectRegion(req->regionid, req->srcregionid1,
req->srcregionid2);
}
static void
GrUnionRectWithRegionWrapper(void *r)
{
nxUnionRectWithRegionReq *req = r;
GrUnionRectWithRegion(req->regionid, &(req->rect));
}
static void
GrUnionRegionWrapper(void *r)
{
nxUnionRegionReq *req = r;
GrUnionRegion(req->regionid, req->srcregionid1, req->srcregionid2);
}
static void
GrSubtractRegionWrapper(void *r)
{
nxSubtractRegionReq *req = r;
GrSubtractRegion(req->regionid, req->srcregionid1, req->srcregionid2);
}
static void
GrXorRegionWrapper(void *r)
{
nxXorRegionReq *req = r;
GrXorRegion(req->regionid, req->srcregionid1, req->srcregionid2);
}
static void
GrPointInRegionWrapper(void *r)
{
nxPointInRegionReq *req = r;
GR_BOOL ret_value = GrPointInRegion(req->regionid, req->x, req->y);
GsWriteType(current_fd, GrNumPointInRegion);
GsWrite(current_fd, &ret_value, sizeof(ret_value));
}
static void
GrRectInRegionWrapper(void *r)
{
nxRectInRegionReq *req = r;
unsigned short ret_value;
ret_value = (unsigned short)GrRectInRegion(req->regionid,
req->x, req->y, req->w, req->h);
GsWriteType(current_fd, GrNumRectInRegion);
GsWrite(current_fd, &ret_value, sizeof(ret_value));
}
static void
GrEmptyRegionWrapper(void *r)
{
nxEmptyRegionReq *req = r;
GR_BOOL ret_value;
ret_value = GrEmptyRegion(req->regionid);
GsWriteType(current_fd, GrNumEmptyRegion);
GsWrite(current_fd, &ret_value, sizeof(ret_value));
}
static void
GrEqualRegionWrapper(void *r)
{
nxEqualRegionReq *req = r;
GR_BOOL ret_value;
ret_value = GrEqualRegion(req->region1, req->region2);
GsWriteType(current_fd, GrNumEqualRegion);
GsWrite(current_fd, &ret_value, sizeof(ret_value));
}
static void
GrOffsetRegionWrapper(void *r)
{
nxOffsetRegionReq *req = r;
GrOffsetRegion(req->region, req->dx, req->dy);
}
static void
GrSetGCRegionWrapper(void *r)
{
nxSetGCRegionReq *req = r;
GrSetGCRegion(req->gcid, req->regionid);
}
static void
GrSetGCClipOriginWrapper(void *r)
{
nxSetGCClipOriginReq *req = r;
GrSetGCClipOrigin(req->gcid, req->xoff, req->yoff);
}
static void
GrGetRegionBoxWrapper(void *r)
{
nxRectInRegionReq *req = r;
GR_BOOL ret_value;
GR_RECT ret_rect;
ret_value = GrGetRegionBox(req->regionid, &ret_rect);
GsWriteType(current_fd, GrNumGetRegionBox);
GsWrite(current_fd, &ret_rect, sizeof(ret_rect));
GsWriteType(current_fd, GrNumGetRegionBox);
GsWrite(current_fd, &ret_value, sizeof(ret_value));
}
static void
GrNewPolygonRegionWrapper(void *r)
{
GR_REGION_ID region;
nxNewPolygonRegionReq *req = r;
int count;
/* FIXME: unportable method, depends on sizeof(int) in GR_POINT*/
count = GetReqVarLen(req) / sizeof(GR_POINT);
region = GrNewPolygonRegion(req->mode, count,
(GR_POINT *)GetReqData(req));
GsWriteType(current_fd, GrNumNewPolygonRegion);
GsWrite(current_fd, ®ion, sizeof(region));
}
static void
GrMapWindowWrapper(void *r)
{
nxMapWindowReq *req = r;
GrMapWindow(req->windowid);
}
static void
GrUnmapWindowWrapper(void *r)
{
nxUnmapWindowReq *req = r;
GrUnmapWindow(req->windowid);
}
static void
GrRaiseWindowWrapper(void *r)
{
nxRaiseWindowReq *req = r;
GrRaiseWindow(req->windowid);
}
static void
GrLowerWindowWrapper(void *r)
{
nxLowerWindowReq *req = r;
GrLowerWindow(req->windowid);
}
static void
GrMoveWindowWrapper(void *r)
{
nxMoveWindowReq *req = r;
GrMoveWindow(req->windowid, req->x, req->y);
}
static void
GrResizeWindowWrapper(void *r)
{
nxResizeWindowReq *req = r;
GrResizeWindow(req->windowid, req->width, req->height);
}
static void
GrReparentWindowWrapper(void *r)
{
nxReparentWindowReq *req = r;
GrReparentWindow(req->windowid, req->parentid, req->x, req->y);
}
static void
GrGetWindowInfoWrapper(void *r)
{
nxGetWindowInfoReq *req = r;
GR_WINDOW_INFO wi;
GrGetWindowInfo(req->windowid, &wi);
GsWriteType(current_fd,GrNumGetWindowInfo);
GsWrite(current_fd, &wi, sizeof(wi));
}
static void
GrGetFontInfoWrapper(void *r)
{
nxGetFontInfoReq *req = r;
GR_FONT_INFO fi;
GrGetFontInfo(req->fontid, &fi);
GsWriteType(current_fd,GrNumGetFontInfo);
GsWrite(current_fd, &fi, sizeof(fi));
}
static void
GrGetFocusWrapper(void *r)
{
GR_WINDOW_ID wid = GrGetFocus();
GsWriteType(current_fd, GrNumGetFocus);
GsWrite(current_fd, &wid, sizeof(wid));
}
static void
GrSetFocusWrapper(void *r)
{
nxSetFocusReq *req = r;
GrSetFocus(req->windowid);
}
static void
GrSetWindowCursorWrapper(void *r)
{
nxSetWindowCursorReq *req = r;
GrSetWindowCursor(req->windowid, req->cursorid);
}
static void
GrClearAreaWrapper(void *r)
{
nxClearAreaReq *req = r;
GrClearArea(req->windowid, req->x, req->y, req->width,
req->height, req->exposeflag);
}
static void
GrSelectEventsWrapper(void *r)
{
nxSelectEventsReq *req = r;
GrSelectEvents(req->windowid, req->eventmask);
}
static void
GrGetNextEventWrapper(void *r)
{
#if 1
/* tell main loop to call Finish routine on event*/
curclient->waiting_for_event = TRUE;
#else
GR_EVENT evt;
/* first check if any event ready*/
GrCheckNextEvent(&evt);
if(evt.type == GR_EVENT_TYPE_NONE) {
/* tell main loop to call Finish routine on event*/
curclient->waiting_for_event = TRUE;
return;
}
GsWriteType(current_fd, GrNumGetNextEvent);
GsWrite(current_fd, &evt, sizeof(evt));
if(evt.type == GR_EVENT_TYPE_CLIENT_DATA) {
GsWrite(fd, evt.data, evt.datalen);
free(evt.data);
}
#endif
}
/* Complete the GrGetNextEvent call from client.
* The client is still waiting on a read at this point.
*/
void
GrGetNextEventWrapperFinish(int fd)
{
GR_EVENT evt;
GR_EVENT_CLIENT_DATA *cde;
/* get the event and pass it to client*/
/* this will never be GR_EVENT_TYPE_NONE*/
GrCheckNextEvent(&evt);
GsWriteType(fd,GrNumGetNextEvent);
GsWrite(fd, &evt, sizeof(evt));
if(evt.type == GR_EVENT_TYPE_CLIENT_DATA) {
cde = (GR_EVENT_CLIENT_DATA *)&evt;
if(cde->data) {
GsWrite(fd, cde->data, cde->datalen);
free(cde->data);
} cde->datalen = 0;
}
}
static void
GrCheckNextEventWrapper(void *r)
{
GR_EVENT evt;
GR_EVENT_CLIENT_DATA *cde;
GrCheckNextEvent(&evt);
GsWriteType(current_fd,GrNumGetNextEvent);
GsWrite(current_fd, &evt, sizeof(evt));
if(evt.type == GR_EVENT_TYPE_CLIENT_DATA) {
cde = (GR_EVENT_CLIENT_DATA *)&evt;
if(cde->data) {
GsWrite(current_fd, cde->data, cde->datalen);
free(cde->data);
} cde->datalen = 0;
}
}
static void
GrPeekEventWrapper(void *r)
{
GR_EVENT evt;
GR_CHAR ret;
GR_EVENT_CLIENT_DATA *cde;
ret = GrPeekEvent(&evt);
GsWriteType(current_fd,GrNumPeekEvent);
GsWrite(current_fd, &evt, sizeof(evt));
if(evt.type == GR_EVENT_TYPE_CLIENT_DATA) {
cde = (GR_EVENT_CLIENT_DATA *)&evt;
if(cde->data) {
GsWrite(current_fd, cde->data, cde->datalen);
free(cde->data);
} cde->datalen = 0;
}
GsWrite(current_fd, &ret, sizeof(GR_CHAR));
}
static void
GrLineWrapper(void *r)
{
nxLineReq *req = r;
GrLine(req->drawid, req->gcid, req->x1, req->y1, req->x2, req->y2);
}
static void
GrPointWrapper(void *r)
{
nxPointReq *req = r;
GrPoint(req->drawid, req->gcid, req->x, req->y);
}
static void
GrPointsWrapper(void *r)
{
nxPointsReq *req = r;
int count;
count = GetReqVarLen(req) / sizeof(GR_POINT);
GrPoints(req->drawid, req->gcid, count, (GR_POINT *)GetReqData(req));
}
static void
GrRectWrapper(void *r)
{
nxRectReq *req = r;
GrRect(req->drawid, req->gcid, req->x, req->y, req->width, req->height);
}
static void
GrFillRectWrapper(void *r)
{
nxFillRectReq *req = r;
GrFillRect(req->drawid, req->gcid, req->x, req->y, req->width,
req->height);
}
static void
GrPolyWrapper(void *r)
{
nxPolyReq *req = r;
int count;
count = GetReqVarLen(req) / sizeof(GR_POINT);
GrPoly(req->drawid, req->gcid, count, (GR_POINT *)GetReqData(req));
}
/* FIXME: fails with pointtable size > 64k if sizeof(int) == 2*/
static void
GrFillPolyWrapper(void *r)
{
nxPolyReq *req = r;
int count;
count = GetReqVarLen(req) / sizeof(GR_POINT);
GrFillPoly(req->drawid, req->gcid, count, (GR_POINT *)GetReqData(req));
}
static void
GrEllipseWrapper(void *r)
{
nxEllipseReq *req = r;
GrEllipse(req->drawid, req->gcid, req->x, req->y, req->rx, req->ry);
}
static void
GrFillEllipseWrapper(void *r)
{
nxFillEllipseReq *req = r;
GrFillEllipse(req->drawid, req->gcid, req->x, req->y, req->rx, req->ry);
}
static void
GrArcWrapper(void *r)
{
nxArcReq *req = r;
GrArc(req->drawid, req->gcid, req->x, req->y, req->rx, req->ry,
req->ax, req->ay, req->bx, req->by, req->type);
}
static void
GrArcAngleWrapper(void *r)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -