📄 grphshm.cpp
字号:
/********************************************************************** * File: grphshm.c (Formerly graphshm.c) * Description: Functions for the shared memory sbdaemon connection. * Author: Ray Smith * Created: Thu May 24 14:09:38 BST 1990 * * (C) Copyright 1990, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#include "mfcpch.h"#include "evntlst.h"#ifdef __UNIX__#include <sys/ipc.h>#include <sys/shm.h>//#include <osfcn.h>#include <errno.h>//#include "pipes.h"#include "fileerr.h"//#include "grpherr.h"//#include "basefile.h"#include <unistd.h>#elif defined(__MSW32__)#include <io.h>#include <fcntl.h>#include <process.h>#include <stdio.h>#else#endif#include <string.h>#include "grphics.h"#include "grphshm.h"#define EXTERNEXTERN SHMINFO shminfo; /*shared memory */EXTERN WINFD sbfds[MAXWINDOWS]; /*file descriptors */EXTERN INT16 maxsbfd = 0; /*no of fds in use */#ifdef __MSW32__ //event thread idEXTERN DWORD event_id = (DWORD) - 1;#endif/********************************************************************** * start_sbdaemon * * Creates the shared memory segment and starts up the sbdaemon telling * it info about the segment. This only needs to be called once. * It is called automatically from create_window at the first creation attempt. **********************************************************************/void start_sbdaemon() { /*start the daemon */ #if defined (__UNIX__) || defined(__MSW32__) char *shmaddr; /*address to attach */ char *sbenv; /*SB_DISPLAY_ADDR */ INT32 sbaddr; /*starbase address */ INT32 wmshm; //windows shared mem char arg1[MAX_PATH]; /*shmid argument */ char arg2[MAX_PATH]; /*shmstart argument */ char arg3[MAX_PATH]; /*shmsize argument */ const char *argv[5]; /*args of sbdaemon */ /*for pipe usage */ static char pipebuffer[PIPESIZE]; sbenv = getenv (SBADDR); /*get SB_DISPLAY_ADDR */ if (sbenv == NULL || sscanf (sbenv, INT32FORMAT, &sbaddr) != 1) sbaddr = SBDEFAULT; shmaddr = getenv (WMSHM); if (shmaddr == NULL || sscanf (shmaddr, INT32FORMAT, &wmshm) != 1) wmshm = WMSHMDEFAULT; /*default address */ shmaddr = (char *) sbaddr - (wmshm + SHMSIZE + SHMOFFSET); if (!remote_display (arg1)) { shminfo.shmsize = SHMSIZE; /*size of segment */ #ifdef __UNIX__ shminfo.shmid = shmget (IPC_PRIVATE, SHMSIZE, USER_RW); /*get shm segment */ // if (shminfo.shmid==-1) // NO_SHM_SEGMENT.error("start_sbdaemon",ABORT,"Errno=%d",errno); #ifdef hp9000s800 /*attach it */ shminfo.shmstart = shmat (shminfo.shmid, 0, 0); if ((int) shminfo.shmstart == -1) #else /*attach it */ shminfo.shmstart = shmat (shminfo.shmid, shmaddr, 0); // if (shminfo.shmstart!=shmaddr) #endif // SHM_ATTACH_FAILED.error("start_sbdaemon",ABORT,"Errno=%d",errno); #else SECURITY_ATTRIBUTES security;//for handles security.nLength = sizeof (security); security.lpSecurityDescriptor = NULL; //make it inheritable security.bInheritHandle = TRUE; //anonymous shminfo.shmid = CreateFileMapping ((HANDLE) 0xffffffff, &security, PAGE_READWRITE, 0, shminfo.shmsize + 3 * sizeof (INT32) + EVENTSIZE * sizeof (SBD_GRAPHICS_EVENT), NULL); if (shminfo.shmid == NULL) { shminfo.shmstart = NULL; return; //quietly fail } shminfo.shmstart = MapViewOfFile (shminfo.shmid, FILE_MAP_WRITE, 0, 0, 0); if (shminfo.shmstart == NULL) return; EVENT_TAIL = 0; EVENT_HEAD = 0; #endif /*set up args */ sprintf (arg1, "%d", shminfo.shmid); sprintf (arg2, "%p", shminfo.shmstart); sprintf (arg3, INT32FORMAT, shminfo.shmsize); argv[0] = SBDAEMON; /*set up argv */ argv[1] = arg1; argv[2] = arg2; argv[3] = arg3; argv[4] = NULL; } else { shmaddr = NULL; //remote fprintf (stderr, "start_sbdaemon:using %s to connect to machine %s\n", REMSH, arg1); #ifdef __UNIX__ shminfo.shmid = -1; #else shminfo.shmid = NULL; #endif /*not using shm */ shminfo.shmstart = pipebuffer; shminfo.shmsize = PIPESIZE; /*size of pipe buffer */ #ifdef __UNIX__ /*command on host */ sprintf (arg2, "%s=0x%x; export %s; %s -1 0 " INT32FORMAT " %s", SBADDR, sbaddr, SBADDR, SBDAEMON, shminfo.shmsize, getenv (DISP)); #else /*command on host */ sprintf (arg2, "%s -1 0 %d %s", SBDAEMON, shminfo.shmsize, getenv (DISP)); #endif argv[0] = REMSH; /*set up argv */ argv[1] = arg1; /*host to use */ argv[2] = arg2; argv[3] = NULL; } shminfo.usedsize = 0; /*none used yet */ #ifdef __UNIX__ // shminfo.pid=two_way_pipe(argv[0],argv,shminfo.fds); /*start daemon*/ #else if (two_way_pipe (argv[0], argv, shminfo.fds) != 0) { cleanup_sbdaemon(); } else { //anonymous event_sem = CreateSemaphore (NULL, 1, 1, NULL); //xiaofan _beginthread (event_reader, 0, &shminfo.fds[INFD]); } #endif #endif}/********************************************************************** * cleanup_sbdaemon * * Free system resources for when the daemon has failed or been killed. **********************************************************************/void cleanup_sbdaemon() { /*forget about the daemon */ #ifdef __MSW32__ if (shminfo.fds[INFD] != NULL) { CloseHandle (shminfo.fds[INFD]); shminfo.fds[INFD] = 0; } if (shminfo.fds[OUTFD] != NULL) { CloseHandle (shminfo.fds[OUTFD]); shminfo.fds[OUTFD] = 0; } if (shminfo.shmstart != NULL) { UnmapViewOfFile (shminfo.shmstart); shminfo.shmstart = NULL; } if (shminfo.shmid != NULL) { CloseHandle (shminfo.shmid); shminfo.shmid = NULL; } if (event_sem != NULL) { CloseHandle(event_sem); event_sem = NULL; } #elif defined(__UNIX__) if (shminfo.fds[INFD] > 0) { close (shminfo.fds[INFD]); shminfo.fds[INFD] = 0; } if (shminfo.fds[OUTFD] > 0) { close (shminfo.fds[OUTFD]); shminfo.fds[OUTFD] = 0; } shminfo.shmstart = NULL; #endif}/********************************************************************** * remote_display * * Returns TRUE if the DISPLAY environment variable points to a * Remote display, and sets the name to the name of the host. * Otherwise, returns FALSE. **********************************************************************/BOOL8 remote_display( //check for remote char *name //name of host ) { #if defined (__UNIX__) || defined(__MSW32__) char *xenv; /*DISPLAY environ */ char *nameend; //end of name #ifdef __UNIX__ char thishost[MAX_PATH]; //current host #endif xenv = getenv (DISP); /*get display variable */ if (xenv != NULL) { strcpy(name, xenv); nameend = strchr (name, ':'); if (nameend != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -