|
|
1.1.1.4 ! root 1: /**************************************************************************** ! 2: Microsoft RPC Version 1.0 ! 3: Copyright Microsoft Corp. 1992 ! 4: mandel Example ! 5: ! 6: FILE: remote.c ! 7: ! 8: PURPOSE: Client side of the RPC distributed application Mandel ! 9: ! 10: COMMENTS: Code to do the remote calculations for the Windows ! 11: Mandelbrot Set distributed drawing program. ! 12: ! 13: Information coming into this module (via API calls) is ! 14: based on upper-left being (0,0) (the Windows standard). ! 15: We translate that to lower-left is (0,0) before we ship ! 16: it out onto the net, and we do reverse translations ! 17: accordingly. ! 18: ! 19: The iteration data is passed back to the main window ! 20: procedure (by means of a WM_PAINTLINE message) which ! 21: draws the picture. ! 22: ! 23: A word about the shared buffer: multiple buffers could ! 24: be used, but a single one is used. The buffer is requested ! 25: in this code, and then released after the data has been ! 26: drawn (in PaintLine() in mandel.c). So long as the painting ! 27: is done quickly, this is efficient. ! 28: ! 29: ****************************************************************************/ 1.1 root 30: 1.1.1.4 ! root 31: #include <stdlib.h> 1.1 root 32: #include <stdio.h> 1.1.1.4 ! root 33: #include <string.h> 1.1 root 34: #include <windows.h> 35: 36: #ifdef RPC 37: #include "mdlrpc.h" 38: #endif 39: #include "mandel.h" 1.1.1.2 root 40: 1.1 root 41: 42: /* 1.1.1.4 ! root 43: * External variables 1.1 root 44: */ 1.1.1.4 ! root 45: extern int fBound; ! 46: extern svr_table SvrTable; // the server table ! 47: extern int iLines; ! 48: extern double dPrec; ! 49: extern int fContinueZoom; ! 50: extern int fZoomIn; ! 51: extern int iHistMaxI; ! 52: extern int iHistMaxJ; ! 53: extern RECT rcZoom; ! 54: extern BOOL fRectDefined; 1.1 root 55: 56: 57: /* 1.1.1.4 ! root 58: * Picture information 1.1 root 59: */ 1.1.1.4 ! root 60: int cPictureID = 0; // picture id, in case we reset in the middle ! 61: static CPOINT cptLL; // upper-left ! 62: static double dPrecision; // precision of draw ! 63: static LONGRECT rclPicture; // rectangle defining client window ! 64: static DWORD dwCurrentLine; // next line to be drawn ! 65: static DWORD dwThreshold; // threshold for iterations 1.1 root 66: 67: /* 1.1.1.4 ! root 68: * Function prototypes for local procs 1.1 root 69: */ 1.1.1.4 ! root 70: DWORD CalcThreshold(double); 1.1 root 71: 72: 73: /* 74: * InitRemote -- 75: * 76: * This function initializes everything for our remote connections. 77: * It gets the local wksta name (making sure the wksta is started) 78: * and it creates the mailslot with which to collect replies to our poll. 79: * 80: * RETURNS 1.1.1.4 ! root 81: * TRUE - initialization succeeded ! 82: * FALSE - initialization failed, can't go on 1.1 root 83: */ 84: 1.1.1.4 ! root 85: BOOL InitRemote(HWND hWnd) 1.1 root 86: { 1.1.1.2 root 87: 1.1 root 88: #ifndef RPC 89: UNREFERENCED_PARAMETER(hWnd); 90: #endif 91: 92: // set up our local entry 1.1.1.4 ! root 93: strcpy(SvrTable.name, "Local machine"); ! 94: SvrTable.iStatus = SS_LOCAL; 1.1 root 95: 96: // good, we succeeded 1.1.1.4 ! root 97: return(TRUE); 1.1 root 98: } 99: 100: 101: /* 102: * CheckDrawStatus -- 103: * 104: * This function does a check of all buffers being drawn. 105: * 106: * If it finds an idle pipe, and there is work to be done, it assigns 107: * a line, and writes out the request. 108: * If it finds a read-pending pipe, it checks if the read has completed. 109: * If it has, it is read and a message is sent so the read data can 110: * be processed. 111: * 112: * RETURNS 1.1.1.4 ! root 113: * TRUE - we did a piece of work ! 114: * FALSE - we could not find any work to do. 1.1 root 115: */ 116: 1.1.1.4 ! root 117: BOOL CheckDrawStatus(HWND hwnd) 1.1 root 118: { 119: CALCBUF cb; 1.1.1.4 ! root 120: LPVOID pbBuf; 1.1 root 121: 1.1.1.4 ! root 122: while(TRUE) { 1.1 root 123: 124: // Check the status 1.1.1.4 ! root 125: switch(SvrTable.iStatus) { 1.1 root 126: 127: case SS_PAINTING: 128: break; 129: 130: case SS_IDLE: 1.1.1.4 ! root 131: break; 1.1 root 132: 133: case SS_LOCAL: 1.1.1.4 ! root 134: // Do a chunk of work locally ! 135: 1.1.1.3 root 136: #ifdef RPC 1.1.1.4 ! root 137: if (fBound == FALSE) ! 138: break; 1.1.1.3 root 139: #endif 1.1 root 140: 1.1.1.4 ! root 141: if ((long) dwCurrentLine > rclPicture.xRight) { 1.1 root 142: if (fContinueZoom == TRUE) { 1.1.1.4 ! root 143: if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC)) 1.1 root 144: fZoomIn = FALSE; // start zooming out 1.1.1.4 ! root 145: if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC)) 1.1 root 146: fZoomIn = TRUE; 1.1.1.4 ! root 147: if (fZoomIn) { ! 148: CountHistogram(); ! 149: rcZoom.top = iHistMaxJ * (WIDTH/4); ! 150: rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1; ! 151: rcZoom.left = iHistMaxI * (HEIGHT/4); ! 152: rcZoom.right = rcZoom.left + (HEIGHT/4) - 1; ! 153: fRectDefined = TRUE; ! 154: PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L); ! 155: } ! 156: else ! 157: PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L); 1.1 root 158: } 159: break; 160: } 161: 1.1.1.4 ! root 162: if (TakeDrawBuffer() == FALSE) 1.1 root 163: break; 164: 1.1.1.4 ! root 165: pbBuf = LockDrawBuffer(); ! 166: 1.1 root 167: cb.rclDraw.xLeft = dwCurrentLine; 1.1.1.4 ! root 168: cb.rclDraw.xRight = dwCurrentLine + iLines - 1; 1.1 root 169: cb.rclDraw.yTop = rclPicture.yTop; 170: cb.rclDraw.yBottom = rclPicture.yBottom; 171: 1.1.1.4 ! root 172: RpcTryExcept { ! 173: MandelCalc(&cptLL, ! 174: &(cb.rclDraw), ! 175: dPrecision, ! 176: dwThreshold, ! 177: (LINEBUF *) pbBuf); ! 178: } ! 179: RpcExcept(1) { ! 180: PostMessage(hwnd, WM_EXCEPTION, 0, 0L); ! 181: return(FALSE); ! 182: } ! 183: RpcEndExcept ! 184: ! 185: UnlockDrawBuffer(); 1.1 root 186: 1.1.1.4 ! root 187: SvrTable.cPicture = cPictureID; ! 188: SvrTable.dwLine = dwCurrentLine; ! 189: SvrTable.cLines = iLines; ! 190: ! 191: PostMessage(hwnd, WM_PAINTLINE, 0, 0L); 1.1 root 192: dwCurrentLine += iLines; 193: 1.1.1.4 ! root 194: return(TRUE); 1.1 root 195: } 196: 1.1.1.4 ! root 197: return(FALSE); 1.1 root 198: } 199: } 200: 201: 202: /* 203: * SetNewCalc -- 204: * 205: * This sets up new information for a drawing and 206: * updates the drawing ID so any calculations in progress will not 207: * be mixed in. 208: */ 209: 1.1.1.4 ! root 210: void SetNewCalc(CPOINT cptUL, double dPrec, RECT rc) 1.1 root 211: { 1.1.1.4 ! root 212: // First, translate from upper left to lower left 1.1 root 213: cptLL.real = cptUL.real; 214: cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top)); 215: 216: // Now the precision 217: dPrecision = dPrec; 218: 219: // The rectangle. Once again, translate. 220: rclPicture.xLeft = (long) rc.left; 221: rclPicture.xRight = (long) rc.right; 222: rclPicture.yBottom = (long) rc.top; 223: rclPicture.yTop = (long) rc.bottom; 224: 225: // Current line, start of drawing 226: dwCurrentLine = rclPicture.xLeft; 227: 228: dwThreshold = CalcThreshold(dPrecision); 229: } 230: 1.1.1.4 ! root 231: 1.1 root 232: void IncPictureID(void) 233: { 234: cPictureID++; 235: } 236: 1.1.1.4 ! root 237: ! 238: void ResetPictureID(void) ! 239: { ! 240: cPictureID = 0; ! 241: } ! 242: ! 243: 1.1 root 244: /* 245: * CheckDrawing -- 246: * 247: * Just a sanity check here -- a function to check to make sure that we're 248: * on the right drawing 249: */ 250: 1.1.1.4 ! root 251: BOOL CheckDrawingID(int id) 1.1 root 252: { 1.1.1.4 ! root 253: return((id == cPictureID) ? TRUE : FALSE); 1.1 root 254: } 255: 256: 257: /* 258: * TakeDrawBuffer ensures only one pipe read at a time. 1.1.1.4 ! root 259: * LockDrawBuffer locks the handle and returns a pointer. ! 260: * UnlockDrawBuffer unlocks the handle. ! 261: * ReturnDrawBuffer lets another pipe read go. ! 262: * FreeDrawBuffer ensures the allocated buffer is freed upon exit. 1.1 root 263: */ 264: 265: static BOOL fBufferTaken = FALSE; 1.1.1.4 ! root 266: static HANDLE hSharedBuf = (HANDLE) NULL; 1.1 root 267: 268: 1.1.1.4 ! root 269: BOOL TakeDrawBuffer(void) 1.1 root 270: { 1.1.1.4 ! root 271: if (fBufferTaken) { ! 272: return(FALSE); 1.1 root 273: } 274: 1.1.1.4 ! root 275: if (hSharedBuf == (HANDLE) NULL) { ! 276: hSharedBuf = LocalAlloc(LMEM_MOVEABLE, MAX_BUFSIZE); ! 277: if (hSharedBuf == (HANDLE) NULL) ! 278: return(FALSE); 1.1 root 279: } 1.1.1.4 ! root 280: 1.1 root 281: fBufferTaken = TRUE; 1.1.1.4 ! root 282: return(TRUE); 1.1 root 283: } 284: 285: 1.1.1.4 ! root 286: LPVOID LockDrawBuffer(void) 1.1 root 287: { 1.1.1.4 ! root 288: if (hSharedBuf == (HANDLE) NULL) ! 289: return(NULL); 1.1 root 290: 1.1.1.4 ! root 291: return(LocalLock(hSharedBuf)); 1.1 root 292: } 293: 294: 1.1.1.4 ! root 295: void UnlockDrawBuffer(void) 1.1 root 296: { 1.1.1.4 ! root 297: LocalUnlock(hSharedBuf); 1.1 root 298: } 299: 300: 1.1.1.4 ! root 301: void ReturnDrawBuffer(void) 1.1 root 302: { 303: fBufferTaken = FALSE; 304: } 305: 306: 1.1.1.4 ! root 307: void FreeDrawBuffer(void) ! 308: { ! 309: if (hSharedBuf != (HANDLE) NULL) ! 310: LocalFree(hSharedBuf); ! 311: } ! 312: 1.1 root 313: 314: /* 315: * CalcThreshold -- 316: * 317: * We need an iteration threshold beyond which we give up. We want it to 318: * increase the farther we zoom in. This code generates a threshold value 319: * based on the precision of drawing. 320: * 321: * RETURNS 322: * threshold calculated based on precision 323: */ 324: 1.1.1.4 ! root 325: DWORD CalcThreshold(double precision) 1.1 root 326: { 327: DWORD thres = 25; 1.1.1.2 root 328: double multiplier = (double) 100.0; 1.1 root 329: 330: /* for every 100, multiply by 2 */ 1.1.1.4 ! root 331: while ((precision *= multiplier) < (double)1.0) 1.1 root 332: thres *= 2; 333: 1.1.1.4 ! root 334: return(thres); 1.1 root 335: } 336: 337: 338: /* 339: * QueryThreshold -- 340: * 341: * Callback for finding out what the current drawing's threshold is. 342: */ 343: 1.1.1.4 ! root 344: DWORD QueryThreshold(void) 1.1 root 345: { 1.1.1.4 ! root 346: return(dwThreshold); 1.1 root 347: } 348:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.