#include "mfcpch.h"
#include "evntlst.h"
#include <string.h>
#include "grphics.h"
#include "grphshm.h"
Go to the source code of this file.
#define EXTERN |
* (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.
Definition at line 43 of file grphshm.cpp.
void cleanup_sbdaemon | ( | ) |
Forget about the daemon.
Free system resources for when the daemon has failed or been killed.
Definition at line 182 of file grphshm.cpp.
References event_sem, SHMINFO::fds, INFD, NULL, OUTFD, SHMINFO::shmid, shminfo, and SHMINFO::shmstart.
Referenced by kick_daemon(), and start_sbdaemon().
00182 { /*forget about the daemon */ 00183 #ifdef __MSW32__ 00184 if (shminfo.fds[INFD] != NULL) { 00185 CloseHandle (shminfo.fds[INFD]); 00186 shminfo.fds[INFD] = 0; 00187 } 00188 if (shminfo.fds[OUTFD] != NULL) { 00189 CloseHandle (shminfo.fds[OUTFD]); 00190 shminfo.fds[OUTFD] = 0; 00191 } 00192 if (shminfo.shmstart != NULL) { 00193 UnmapViewOfFile (shminfo.shmstart); 00194 shminfo.shmstart = NULL; 00195 } 00196 if (shminfo.shmid != NULL) { 00197 CloseHandle (shminfo.shmid); 00198 shminfo.shmid = NULL; 00199 } 00200 if (event_sem != NULL) { 00201 CloseHandle(event_sem); 00202 event_sem = NULL; 00203 } 00204 #elif defined(__UNIX__) 00205 if (shminfo.fds[INFD] > 0) { 00206 close (shminfo.fds[INFD]); 00207 shminfo.fds[INFD] = 0; 00208 } 00209 if (shminfo.fds[OUTFD] > 0) { 00210 close (shminfo.fds[OUTFD]); 00211 shminfo.fds[OUTFD] = 0; 00212 } 00213 shminfo.shmstart = NULL; 00214 #endif //defined(__UNIX__) 00215 }
DLLSYM void* getshm | ( | INT32 | size | ) |
Get memory.
Get the next element of the shared memory. If there is no more room in the segment, kick the daemon to get it to empty it out and then restart the buffer once it acknowledges the cleanout.
Definition at line 270 of file grphshm.cpp.
References AWAIT_BUFFER, kick_daemon(), NULL, shminfo, SHMINFO::shmsize, SHMINFO::shmstart, and SHMINFO::usedsize.
Referenced by WINFD::Append_text(), WINFD::Arc(), WINFD::Character_height(), WINFD::Clear_view_surface(), WINFD::create(), def_overlap_picture_ops(), def_show_sub_image(), WINFD::Destroy_window(), WINFD::Draw2d(), WINFD::Ellipse(), WINFD::Fill_color(), WINFD::Fill_color_index(), WINFD::Interior_style(), WINFD::Line_color_index(), WINFD::Line_type(), WINFD::Make_picture_current(), WINFD::Marker_color_index(), WINFD::Marker_size(), WINFD::Marker_type(), WINFD::Move2d(), WINFD::Perimeter_color_index(), WINFD::Polygon2d(), WINFD::Polyline2d(), WINFD::Polymarker2d(), WINFD::Re_compute_colourmap(), WINFD::Rectangle(), WINFD::Set_echo(), WINFD::Synchronize_windows(), WINFD::Text2d(), WINFD::Text_alignment(), WINFD::Text_color_index(), WINFD::Text_font_index(), and WINFD::Vdc_extent().
00272 { 00273 void *segment; /*return segment */ 00274 00275 if (shminfo.shmstart == NULL) 00276 return NULL; //no daemon connection 00277 size = (size + 3) & ~3; 00278 if (size > shminfo.shmsize) 00279 return NULL; 00280 /*too full? */ 00281 if (shminfo.usedsize + size > shminfo.shmsize 00282 || shminfo.usedsize < 0) { /*or read pending */ 00283 kick_daemon(AWAIT_BUFFER); /*get it to read */ 00284 } 00285 /*address of segment */ 00286 segment = (char *) shminfo.shmstart + shminfo.usedsize; 00287 shminfo.usedsize += size; /*sum used sizes */ 00288 return segment; 00289 }
void kick_daemon | ( | INT8 | mode | ) |
Empty queue.
Tell the daemon to read the shared memory and perform all the operations in it. This function blocks until the daemon has emptied the queue.
Function is a NOP on __MAC__
Definition at line 301 of file grphshm.cpp.
References add_event(), AWAIT_BUFFER, cleanup_sbdaemon(), COUNT_READS, ERRCODE::error(), EVENT_HEAD, EVENT_INDEX, EVENTSIZE, EXIT, FALSE, sbdgraphicsevent::fd, SHMINFO::fds, graphicsevent::fildes, FLUSH_IN, INFD, graphicsevent::key, sbdgraphicsevent::key, lock_events(), MAX_PATH, MAX_PENDING, graphicsevent::next, NULL, OUTFD, PIPESIZE, PRIMITIVES, QUEUE_CLEAR, READFAILED, SHMINFO::shmid, shminfo, SHMINFO::shmstart, TRUE, sbdgraphicsevent::type, graphicsevent::type, unlock_events(), SHMINFO::usedsize, WRITEFAILED, graphicsevent::x, sbdgraphicsevent::x, graphicsevent::y, and sbdgraphicsevent::y.
Referenced by def_overlap_picture_ops(), event_reader(), getshm(), and WINFD::Make_picture_current().
00303 { 00304 #ifndef __MAC__ 00305 SBD_GRAPHICS_EVENT event; /*event from daemon */ 00306 GRAPHICS_EVENT real_event; //converted format 00307 #ifdef __MSW32__ 00308 unsigned long nwrite; 00309 unsigned long nread; //bytes read 00310 char pipe_char[2]; //char from pipe 00311 INT32 pipe_index; //index to event queue 00312 #endif //__MSW32__ 00313 static INT16 reads_pending = 0;/*acknowledges pending */ 00314 00315 if (mode == COUNT_READS) { 00316 lock_events(); 00317 reads_pending--; /*got a read */ 00318 unlock_events(); 00319 return; 00320 } 00321 if (shminfo.shmstart == NULL) 00322 return; //no connection 00323 if (shminfo.usedsize > 0) { 00324 #ifdef __UNIX__ 00325 if (write 00326 (shminfo.fds[OUTFD], (const char *) &shminfo.usedsize, 00327 sizeof (INT32)) != sizeof (INT32)) 00328 WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe"); 00329 #else 00330 PRIMITIVES = shminfo.usedsize; 00331 if (WriteFile (shminfo.fds[OUTFD], "xx", 2, &nwrite, NULL) == 0 00332 || nwrite != 2) { 00333 cleanup_sbdaemon(); 00334 return; 00335 } 00336 #endif 00337 #ifdef __UNIX__ 00338 if (shminfo.shmid < 0) { 00339 if (write (shminfo.fds[OUTFD], (const char *) shminfo.shmstart, 00340 shminfo.usedsize) != shminfo.usedsize) 00341 WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe"); 00342 #else //__UNIX__ 00343 if (shminfo.shmid == NULL) { 00344 if (WriteFile (shminfo.fds[OUTFD], (const char *) shminfo.shmstart, 00345 shminfo.usedsize, &nwrite, NULL) == 0 00346 || nwrite != (UINT32) shminfo.usedsize) { 00347 cleanup_sbdaemon(); 00348 return; 00349 } 00350 #endif //__UNIX__ 00351 shminfo.usedsize = 0; /*can use it now */ 00352 } 00353 else 00354 shminfo.usedsize = -1; /*need to wait */ 00355 lock_events(); 00356 reads_pending++; /*acknowledges due */ 00357 unlock_events(); 00358 } 00359 if (mode == FLUSH_IN || reads_pending > MAX_PENDING || mode == AWAIT_BUFFER 00360 #ifdef __UNIX__ 00361 && shminfo.shmid < 0) 00362 #else //__UNIX__ 00363 && shminfo.shmid != NULL) 00364 #endif //__UNIX__ 00365 { 00366 while (reads_pending > 0) { 00367 #ifdef __MSW32__ 00368 if (event_id == GetCurrentThreadId ()) { 00369 if (ReadFile (shminfo.fds[INFD], pipe_char, 2, &nread, NULL) != 0 00370 && nread == 2) { 00371 pipe_index = EVENT_HEAD; 00372 event = EVENT_INDEX (pipe_index); 00373 pipe_index++; 00374 if (pipe_index >= EVENTSIZE) 00375 pipe_index = 0; 00376 EVENT_HEAD = pipe_index; 00377 #endif //__MSW32__ 00378 #ifdef __UNIX__ 00379 if (read 00380 (shminfo.fds[INFD], &event, 00381 sizeof (SBD_GRAPHICS_EVENT)) != 00382 sizeof (SBD_GRAPHICS_EVENT)) 00383 READFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe"); 00384 #endif //__UNIX__ 00385 if (event.type != QUEUE_CLEAR) { 00386 real_event.fildes = event.fd; 00387 real_event.type = event.type; 00388 real_event.key = event.key; 00389 real_event.x = event.x; 00390 real_event.y = event.y; 00391 real_event.next = NULL; 00392 /*add event to queue */ 00393 add_event(&real_event); 00394 } 00395 else 00396 reads_pending--; /*got acknowledge */ 00397 #ifdef __MSW32__ 00398 } 00399 } 00400 else 00401 Sleep (50); // a minute? this isn't 1989 :) 00402 #endif //__MSW32__ 00403 } 00404 if (shminfo.usedsize < 0) //must be reentrant 00405 shminfo.usedsize = 0; /*none used now */ 00406 } 00407 #endif // ! __MAC__ 00408 }
BOOL8 remote_display | ( | char * | name | ) |
Check for remote.
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.
Definition at line 225 of file grphshm.cpp.
References DISP, FALSE, LOCAL1, LOCAL2, MAX_PATH, NULL, and TRUE.
Referenced by start_sbdaemon().
00227 { 00228 #if defined (__UNIX__) || defined(__MSW32__) 00229 char *xenv; /*DISPLAY environ */ 00230 char *nameend; //end of name 00231 #ifdef __UNIX__ 00232 char thishost[MAX_PATH]; //current host 00233 #endif 00234 00235 xenv = getenv (DISP); /*get display variable */ 00236 if (xenv != NULL) { 00237 strcpy(name, xenv); 00238 nameend = strchr (name, ':'); 00239 if (nameend != NULL) 00240 *nameend = '\0'; /*chop display off */ 00241 nameend = strchr (name, '.'); 00242 if (nameend != NULL) 00243 *nameend = '\0'; /*chop resolv off */ 00244 #ifdef __UNIX__ 00245 if (strcmp (name, LOCAL1) && strcmp (name, LOCAL2) 00246 && gethostname (thishost, MAX_PATH) >= 0) { 00247 nameend = strchr (thishost, '.'); 00248 if (nameend != NULL) 00249 *nameend = '\0'; /*chop resolv off */ 00250 if (strcmp (name, thishost)) { 00251 return TRUE; 00252 } 00253 } 00254 #else 00255 return TRUE; 00256 #endif 00257 } 00258 #endif 00259 return FALSE; 00260 }
void start_sbdaemon | ( | ) |
Start the daemon.
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.
Definition at line 61 of file grphshm.cpp.
References cleanup_sbdaemon(), DISP, EVENT_HEAD, event_reader(), event_sem, EVENT_TAIL, EVENTSIZE, SHMINFO::fds, INFD, INT32FORMAT, MAX_PATH, NULL, PIPESIZE, remote_display(), REMSH, SBADDR, SBDAEMON, SBDEFAULT, SHMINFO::shmid, shminfo, SHMOFFSET, SHMSIZE, SHMINFO::shmsize, SHMINFO::shmstart, TRUE, SHMINFO::usedsize, USER_RW, WMSHM, and WMSHMDEFAULT.
Referenced by WINFD::create().
00061 { /*start the daemon */ 00062 #if defined (__UNIX__) || defined(__MSW32__) 00063 char *shmaddr; /*address to attach */ 00064 char *sbenv; /*SB_DISPLAY_ADDR */ 00065 INT32 sbaddr; /*starbase address */ 00066 INT32 wmshm; //windows shared mem 00067 char arg1[MAX_PATH]; /*shmid argument */ 00068 char arg2[MAX_PATH]; /*shmstart argument */ 00069 char arg3[MAX_PATH]; /*shmsize argument */ 00070 const char *argv[5]; /*args of sbdaemon */ 00071 /*for pipe usage */ 00072 static char pipebuffer[PIPESIZE]; 00073 00074 sbenv = getenv (SBADDR); /*get SB_DISPLAY_ADDR */ 00075 if (sbenv == NULL || sscanf (sbenv, INT32FORMAT, &sbaddr) != 1) 00076 sbaddr = SBDEFAULT; 00077 shmaddr = getenv (WMSHM); 00078 if (shmaddr == NULL || sscanf (shmaddr, INT32FORMAT, &wmshm) != 1) 00079 wmshm = WMSHMDEFAULT; 00080 /*default address */ 00081 shmaddr = (char *) sbaddr - (wmshm + SHMSIZE + SHMOFFSET); 00082 00083 if (!remote_display (arg1)) { 00084 shminfo.shmsize = SHMSIZE; /*size of segment */ 00085 #ifdef __UNIX__ 00086 shminfo.shmid = shmget (IPC_PRIVATE, SHMSIZE, USER_RW); 00087 /*get shm segment */ 00088 // if (shminfo.shmid==-1) 00089 // NO_SHM_SEGMENT.error("start_sbdaemon",ABORT,"Errno=%d",errno); 00090 #ifdef hp9000s800 00091 /*attach it */ 00092 shminfo.shmstart = shmat (shminfo.shmid, 0, 0); 00093 if ((int) shminfo.shmstart == -1) 00094 #else //hp9000s800 00095 /*attach it */ 00096 shminfo.shmstart = shmat (shminfo.shmid, shmaddr, 0); 00097 // if (shminfo.shmstart!=shmaddr) 00098 #endif //hp9000s800 00099 // SHM_ATTACH_FAILED.error("start_sbdaemon",ABORT,"Errno=%d",errno); 00100 #else //__UNIX__ 00101 SECURITY_ATTRIBUTES security;//for handles 00102 00103 security.nLength = sizeof (security); 00104 security.lpSecurityDescriptor = NULL; 00105 //make it inheritable 00106 security.bInheritHandle = TRUE; 00107 //anonymous 00108 shminfo.shmid = CreateFileMapping ((HANDLE) 0xffffffff, &security, 00109 PAGE_READWRITE, 0, shminfo.shmsize + 3 * sizeof (INT32) 00110 + EVENTSIZE * sizeof (SBD_GRAPHICS_EVENT), NULL); 00111 if (shminfo.shmid == NULL) { 00112 shminfo.shmstart = NULL; 00113 return; //quietly fail 00114 } 00115 shminfo.shmstart = 00116 MapViewOfFile (shminfo.shmid, FILE_MAP_WRITE, 0, 0, 0); 00117 if (shminfo.shmstart == NULL) 00118 return; 00119 EVENT_TAIL = 0; 00120 EVENT_HEAD = 0; 00121 #endif //__UNIX__ 00122 /*set up args */ 00123 sprintf (arg1, "%d", shminfo.shmid); 00124 sprintf (arg2, "%p", shminfo.shmstart); 00125 sprintf (arg3, INT32FORMAT, shminfo.shmsize); 00126 argv[0] = SBDAEMON; /*set up argv */ 00127 argv[1] = arg1; 00128 argv[2] = arg2; 00129 argv[3] = arg3; 00130 argv[4] = NULL; 00131 } 00132 else { 00133 shmaddr = NULL; //remote 00134 fprintf (stderr, "start_sbdaemon:using %s to connect to machine %s\n", 00135 REMSH, arg1); 00136 #ifdef __UNIX__ 00137 shminfo.shmid = -1; 00138 #else //__UNIX__ 00139 shminfo.shmid = NULL; 00140 #endif //__UNIX__ 00141 /*not using shm */ 00142 shminfo.shmstart = pipebuffer; 00143 shminfo.shmsize = PIPESIZE; /*size of pipe buffer */ 00144 #ifdef __UNIX__ 00145 /*command on host */ 00146 sprintf (arg2, "%s=0x%x; export %s; %s -1 0 " INT32FORMAT " %s", 00147 SBADDR, sbaddr, SBADDR, SBDAEMON, shminfo.shmsize, getenv (DISP)); 00148 #else//__UNIX__ 00149 /*command on host */ 00150 sprintf (arg2, "%s -1 0 %d %s", SBDAEMON, shminfo.shmsize, getenv (DISP)); 00151 #endif //__UNIX__ 00152 argv[0] = REMSH; /*set up argv */ 00153 argv[1] = arg1; /*host to use */ 00154 argv[2] = arg2; 00155 argv[3] = NULL; 00156 } 00157 00158 shminfo.usedsize = 0; /*none used yet */ 00159 00160 #ifdef __UNIX__ 00161 // shminfo.pid=two_way_pipe(argv[0],argv,shminfo.fds); /*start daemon*/ 00162 #else //__UNIX__ 00163 if (two_way_pipe (argv[0], argv, shminfo.fds) != 0) { 00164 cleanup_sbdaemon(); 00165 } 00166 else { 00167 //anonymous 00168 event_sem = CreateSemaphore (NULL, 1, 1, NULL); 00169 //xiaofan 00170 _beginthread (event_reader, 0, &shminfo.fds[INFD]); 00171 } 00172 #endif //__UNIX__ 00173 #endif //defined (__UNIX__) || defined(__MSW32__) 00174 }
Definition at line 47 of file grphshm.cpp.
Referenced by WINFD::Clear_event_queue(), WINFD::create(), def_overlap_picture_ops(), WINFD::Destroy_window(), and search_event_queue().
Definition at line 46 of file grphshm.cpp.
Referenced by add_event(), WINFD::Clear_event_queue(), WINFD::create(), def_overlap_picture_ops(), WINFD::Destroy_window(), search_event_queue(), and search_single_queue().
Definition at line 45 of file grphshm.cpp.
Referenced by cleanup_sbdaemon(), getshm(), kick_daemon(), and start_sbdaemon().