REMOTE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

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