Annotation of mstools/samples/rpc/mandel/remote.c, revision 1.1.1.4

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.