home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / THREADS3.ZIP / THREADS3.C next >
Text File  |  1990-03-18  |  11KB  |  335 lines

  1. «RHA«PT2»«LM10»«RM75»ENVIRONMENTS o CHARLES PETZOLD         p.  «PN»  of «FP» 
  2. Vol. 9, No. 12
  3.                       Filename:  «VA$FI»
  4.  
  5.  
  6. »«PT2»«LM20»«RM50.5»«LS2»«TS22»
  7. «NB»«PT11»«LM0»«RM80»«AL1»«TS8,16,24,32,40»
  8. CODE BOX
  9. THREADS3.C
  10. COMPLETE LISTING
  11.  
  12.  
  13.  
  14. /*---------------------------------------------------------
  15.    THREADS3.C -- Demonstrates drawing from a second thread
  16.                  (c) 1990, Ziff Communications Co.
  17.                  PC Magazine * Charles Petzold, 2/90
  18.   ---------------------------------------------------------*/
  19.  
  20. #define INCL_WIN
  21. #define INCL_GPI
  22. #include <os2.h>
  23. #include <mt\process.h>
  24. #include <mt\stdlib.h>
  25.  
  26. #define CXIMAGE     150
  27. #define CYIMAGE     150
  28. #define SPLINE      100
  29. #define STACKSIZE   (4096 * sizeof (int))
  30. #define SEGNAME     1L
  31. #define PI          3.14159
  32.  
  33. typedef struct
  34.      {
  35.      HPS   hps ;
  36.      BOOL  fTerminate ;
  37.      ULONG semTriggerDraw ;
  38.      ULONG semDoingDraw ;
  39.      }
  40.      THREADPARAMS ;
  41.  
  42. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  43. VOID    FAR      SecondThread (THREADPARAMS *) ;
  44. VOID             ScaleImageToClient (HPS, SIZEL *) ;
  45. VOID             DrawImage (HPS) ;
  46. VOID             DrawLetters (HPS) ;
  47.  
  48. HAB  hab ;
  49.  
  50. int main (void)
  51.      {
  52.      static CHAR  szClientClass [] = "Threads3" ;
  53.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU |
  54.                                  FCF_SIZEBORDER    | FCF_MINMAX  |
  55.                                  FCF_SHELLPOSITION | FCF_TASKLIST ;
  56.      HAB          hab ;
  57.      HMQ          hmq ;
  58.      HWND         hwndFrame, hwndClient ;
  59.      QMSG         qmsg ;
  60.  
  61.      hab = WinInitialize (0) ;
  62.      hmq = WinCreateMsgQueue (hab, 0) ;
  63.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  64.  
  65.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  66.                                      &flFrameFlags, szClientClass, NULL,
  67.                                      0L, NULL, 0, &hwndClient) ;
  68.  
  69.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  70.           WinDispatchMsg (hab, &qmsg) ;
  71.  
  72.      WinDestroyWindow (hwndFrame) ;
  73.      WinDestroyMsgQueue (hmq) ;
  74.      WinTerminate (hab) ;
  75.      return 0 ;
  76.      }
  77.  
  78. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  79.      {
  80.      static int          aiThreadStack [STACKSIZE / sizeof (int)] ;
  81.      static THREADPARAMS tp ;
  82.      HDC                 hdc ;
  83.      SIZEL               sizlPage, sizlClient ;
  84.  
  85.      switch (msg)
  86.           {
  87.           case WM_CREATE:
  88.                               // create a presentation space for the window
  89.  
  90.                hdc = WinOpenWindowDC (hwnd) ;
  91.                sizlPage.cx = 0 ;
  92.                sizlPage.cy = 0 ;
  93.                tp.hps = GpiCreatePS (hab, hdc, &sizlPage,
  94.                                      PU_LOENGLISH | GPIF_DEFAULT |
  95.                                      GPIT_NORMAL  | GPIA_ASSOC) ;
  96.  
  97.                               // start the thread after initialization
  98.  
  99.                tp.fTerminate = FALSE ;
  100.  
  101.                DosSemSet (&tp.semTriggerDraw) ;
  102.                DosSemClear (&tp.semDoingDraw) ;
  103.  
  104.                _beginthread (SecondThread, aiThreadStack, STACKSIZE, &tp) ;
  105.  
  106.                               // create the segment
  107.  
  108.                GpiSetDrawingMode (tp.hps, DM_RETAIN) ;
  109.  
  110.                GpiOpenSegment (tp.hps, SEGNAME) ;
  111.                DrawImage (tp.hps) ;
  112.                GpiCloseSegment (tp.hps) ;
  113.                return 0 ;
  114.  
  115.           case WM_SIZE:
  116.                               // stop the thread from drawing
  117.  
  118.                GpiSetStopDraw (tp.hps, SDW_ON) ;
  119.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  120.  
  121.                               // get new size of client window
  122.  
  123.                sizlClient.cx = SHORT1FROMMP (mp2) ;
  124.                sizlClient.cy = SHORT2FROMMP (mp2) ;
  125.  
  126.                               // set the new default view matrix
  127.  
  128.                GpiConvert (tp.hps, CVTC_DEVICE, CVTC_PAGE, 1L,
  129.                                    (PPOINTL) &sizlClient) ;
  130.  
  131.                ScaleImageToClient (tp.hps, &sizlClient) ;
  132.                return 0 ;
  133.  
  134.           case WM_PAINT:
  135.                               // stop the thread from drawing
  136.  
  137.                GpiSetStopDraw (tp.hps, SDW_ON) ;
  138.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  139.  
  140.                               // erase the window
  141.  
  142.                WinBeginPaint (hwnd, tp.hps, NULL) ;
  143.                GpiErase (tp.hps) ;
  144.                WinEndPaint (tp.hps) ;
  145.  
  146.                               // let the thread continue
  147.  
  148.                GpiSetStopDraw (tp.hps, SDW_OFF) ;
  149.                DosSemSet (&tp.semDoingDraw) ;
  150.                DosSemClear (&tp.semTriggerDraw) ;
  151.                return 0 ;
  152.  
  153.           case WM_DESTROY:
  154.                               // stop the thread
  155.  
  156.                tp.fTerminate = TRUE ;
  157.                GpiSetStopDraw (tp.hps, SDW_ON) ;
  158.                DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;
  159.  
  160.                               // clean up
  161.  
  162.                GpiDeleteSegment (tp.hps, SEGNAME) ;
  163.                GpiAssociate (tp.hps, NULL) ;
  164.                GpiDestroyPS (tp.hps) ;
  165.                return 0 ;
  166.           }
  167.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  168.      }
  169.  
  170. VOID _CDECL FAR SecondThread (THREADPARAMS * ptp)
  171.      {
  172.      HAB  hab ;
  173.  
  174.      hab = WinInitialize (0) ;
  175.  
  176.      while (!ptp->fTerminate)
  177.           {
  178.                               // wait for the semaphore to be cleared
  179.  
  180.           DosSemWait (&ptp->semTriggerDraw, SEM_INDEFINITE_WAIT) ;
  181.  
  182.                               // draw the image
  183.  
  184.           GpiSavePS (ptp->hps) ;
  185.           GpiDrawSegment (ptp->hps, SEGNAME) ;
  186.           GpiRestorePS (ptp->hps, -1L) ;
  187.  
  188.                               // set and clear the semaphores
  189.  
  190.           DosSemSet (&ptp->semTriggerDraw) ;
  191.           DosSemClear (&ptp->semDoingDraw) ;
  192.           }
  193.  
  194.      WinTerminate (hab) ;
  195.      _endthread () ;
  196.      }
  197.  
  198. VOID ScaleImageToClient (HPS hps, SIZEL *psizlClient)
  199.      {
  200.      FIXED    afxScale[2] ;
  201.      MATRIXLF matlf ;
  202.      POINTL   ptl ;
  203.  
  204.      afxScale[0] = afxScale[1] = min (65536L * psizlClient->cx / CXIMAGE,
  205.                                       65536L * psizlClient->cy / CYIMAGE) ;
  206.      ptl.x = 0 ;
  207.      ptl.y = 0 ;
  208.  
  209.      GpiScale (hps, &matlf, TRANSFORM_REPLACE, afxScale, &ptl) ;
  210.  
  211.      ptl.x = (psizlClient->cx - afxScale[0] * CXIMAGE / 65536L) / 2 ;
  212.      ptl.y = (psizlClient->cy - afxScale[1] * CYIMAGE / 65536L) / 2 ;
  213.  
  214.      GpiTranslate (hps, &matlf, TRANSFORM_ADD, &ptl) ;
  215.  
  216.      GpiSetDefaultViewMatrix (hps, 9L, &matlf, TRANSFORM_REPLACE) ;
  217.      }
  218.  
  219. VOID DrawImage (HPS hps)
  220.      {
  221.      MATRIXLF matlf ;
  222.      POINTL   ptl, aptl[4] ;
  223.      SHORT    iAngle ;
  224.  
  225.                // Draw outline of letters
  226.  
  227.      DrawLetters (hps) ;
  228.  
  229.                // Use letters outline as clipping path
  230.  
  231.      GpiBeginPath (hps, 1L) ;
  232.      DrawLetters (hps) ;
  233.      GpiEndPath (hps) ;
  234.      GpiSetClipPath (hps, 1L, SCP_AND | SCP_ALTERNATE) ;
  235.  
  236.      for (iAngle = 0 ; iAngle < 360 ; iAngle++)
  237.           {
  238.                     // Find matrix for rotation around origin
  239.  
  240.           ptl.x = 0 ;
  241.           ptl.y = 0 ;
  242.           GpiRotate (hps, &matlf, TRANSFORM_REPLACE,
  243.                      MAKEFIXED (iAngle, 0), &ptl) ;
  244.  
  245.                     // Append matrix for translation to center of image
  246.  
  247.           ptl.x = CXIMAGE / 2 ;
  248.           ptl.y = CYIMAGE / 2 ;
  249.           GpiTranslate (hps, &matlf, TRANSFORM_ADD, &ptl) ;
  250.  
  251.                     // Set model transform using composite matrix
  252.  
  253.           GpiSetModelTransformMatrix (hps, 9L, &matlf, TRANSFORM_REPLACE) ;
  254.  
  255.                     // Draw spline curve
  256.  
  257.           aptl[0].x = 0 ;
  258.           aptl[0].y = 0 ;
  259.  
  260.           aptl[1].x = SPLINE / 3 ;
  261.           aptl[1].y = SPLINE / 2 ;
  262.  
  263.           aptl[2].x = 2 * SPLINE / 3 ;
  264.           aptl[2].y = - SPLINE / 2 ;
  265.  
  266.           aptl[3].x = SPLINE ;
  267.           aptl[3].y = 0 ;
  268.  
  269.           GpiMove (hps, aptl) ;
  270.           GpiPolySpline (hps, 3L, aptl + 1) ;
  271.           }
  272.      }
  273.  
  274. VOID DrawLetters (HPS hps)
  275.      {
  276.      POINTL ptl, aptl[3] ;
  277.  
  278.                     // Outside of 'P'
  279.  
  280.      ptl.x     =   4 ;  ptl.y     =   4 ;  GpiMove (hps, &ptl) ;
  281.      ptl.x     =   4 ;  ptl.y     = 146 ;  GpiLine (hps, &ptl) ;
  282.      ptl.x     =  45 ;  ptl.y     = 146 ;  GpiLine (hps, &ptl) ;
  283.      aptl[0].x =  72 ;  aptl[0].y = 146 ;
  284.      aptl[1].x =  72 ;  aptl[1].y = 119 ;  GpiPolyFillet (hps, 2L, aptl) ;
  285.      ptl.x     =  72 ;  ptl.y     =  85 ;  GpiLine (hps, &ptl) ;
  286.      aptl[0].x =  72 ;  aptl[0].y =  58 ;
  287.      aptl[1].x =  45 ;  aptl[1].y =  58 ;  GpiPolyFillet (hps, 2L, aptl) ;
  288.      ptl.x     =  35 ;  ptl.y     =  58 ;  GpiLine (hps, &ptl) ;
  289.      ptl.x     =  35 ;  ptl.y     =   4 ;  GpiLine (hps, &ptl) ;
  290.      ptl.x     =   4 ;  ptl.y     =   4 ;  GpiLine (hps, &ptl) ;
  291.  
  292.                     // Inside of 'P'
  293.  
  294.      ptl.x     =  35 ;  ptl.y     =  77 ;  GpiMove (hps, &ptl) ;
  295.      ptl.x     =  35 ;  ptl.y     = 125 ;  GpiLine (hps, &ptl) ;
  296.      aptl[0].x =  43 ;  aptl[0].y = 125 ;
  297.      aptl[1].x =  43 ;  aptl[1].y = 117 ;  GpiPolyFillet (hps, 2L, aptl) ;
  298.      ptl.x     =  43 ;  ptl.y     =  85 ;  GpiLine (hps, &ptl) ;
  299.      aptl[0].x =  43 ;  aptl[0].y =  77 ;
  300.      aptl[1].x =  35 ;  aptl[1].y =  77 ;  GpiPolyFillet (hps, 2L, aptl) ;
  301.  
  302.                     // Outline of 'C'
  303.  
  304.      ptl.x     = 116 ;  ptl.y     =  63 ;  GpiMove (hps, &ptl) ;
  305.      ptl.x     = 145 ;  ptl.y     =  63 ;  GpiLine (hps, &ptl) ;
  306.      ptl.x     = 145 ;  ptl.y     =  31 ;  GpiLine (hps, &ptl) ;
  307.      aptl[0].x = 145 ;  aptl[0].y =   4 ;
  308.      aptl[1].x = 118 ;  aptl[1].y =   4 ;  GpiPolyFillet (hps, 2L, aptl) ;
  309.      ptl.x     = 103 ;  ptl.y     =   4 ;  GpiLine (hps, &ptl) ;
  310.      aptl[0].x =  76 ;  aptl[0].y =   4 ;
  311.      aptl[1].x =  76 ;  aptl[1].y =  31 ;  GpiPolyFillet (hps, 2L, aptl) ;
  312.      ptl.x     =  76 ;  ptl.y     = 119 ;  GpiLine (hps, &ptl) ;
  313.      aptl[0].x =  76 ;  aptl[0].y = 146 ;
  314.      aptl[1].x = 103 ;  aptl[1].y = 146 ;  GpiPolyFillet (hps, 2L, aptl) ;
  315.      ptl.x     = 118 ;  ptl.y     = 146 ;  GpiLine (hps, &ptl) ;
  316.      aptl[0].x = 145 ;  aptl[0].y = 146 ;
  317.      aptl[1].x = 145 ;  aptl[1].y = 119 ;  GpiPolyFillet (hps, 2L, aptl) ;
  318.      ptl.x     = 145 ;  ptl.y     =  88 ;  GpiLine (hps, &ptl) ;
  319.      ptl.x     = 116 ;  ptl.y     =  88 ;  GpiLine (hps, &ptl) ;
  320.      ptl.x     = 116 ;  ptl.y     = 123 ;  GpiLine (hps, &ptl) ;
  321.      aptl[0].x = 116 ;  aptl[0].y = 127 ;
  322.      aptl[1].x = 108 ;  aptl[1].y = 127 ;
  323.      aptl[2].x = 108 ;  aptl[2].y = 123 ;  GpiPolyFillet (hps, 3L, aptl) ;
  324.      ptl.x     = 108 ;  ptl.y     =  30 ;  GpiLine (hps, &ptl) ;
  325.      aptl[0].x = 108 ;  aptl[0].y =  26 ;
  326.      aptl[1].x = 116 ;  aptl[1].y =  26 ;
  327.      aptl[2].x = 116 ;  aptl[2].y =  30 ;  GpiPolyFillet (hps, 3L, aptl) ;
  328.      ptl.x     = 116 ;  ptl.y     =  63 ;  GpiLine (hps, &ptl) ;
  329.      }
  330.  
  331.  
  332.  
  333. caption:
  334. «BB»«PT7»«AL0»«LM0»«RM69.6»«LS2»«MDBO»Figure 3:«MDNM»  The THREADS3.C source code listing contains several new functions that require OS/2 1.2.
  335.