home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / os2cl016.zip / bg_paint.cpp next >
C/C++ Source or Header  |  1996-05-04  |  11KB  |  395 lines

  1. /* 
  2.  
  3.  
  4.     bg_paint.cpp (emx+gcc) 
  5.  
  6.     1995 Giovanni Iachello
  7.     This is freeware software. You can use or modify it as you wish,
  8.     provided that the part of code that I wrote remains freeware.
  9.     Freeware means that the source code must be available on request 
  10.     to anyone.
  11.     You must also include this notice in all files derived from this
  12.     file.
  13.  
  14.     Parts of this code are:
  15.  
  16. */
  17.  
  18. /*---------------------------------------------------------
  19.    THREADS3.C -- Demonstrates drawing from a second thread
  20.                  (c) 1990, Ziff Communications Co.
  21.                  PC Magazine * Charles Petzold, 2/90
  22.   ---------------------------------------------------------*/
  23.  
  24. /*
  25.  
  26.     This example shows some of the library features:
  27.     
  28.     * using the background paint thread 
  29.     * using semaphores
  30.  
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #define INCL_WIN
  37. #include "pmwin.h"
  38. #include "pmdlg.h"
  39. #include "pmgpi.h"
  40. #include "pmstdres.h"
  41. #include "bg_paint.h"
  42.  
  43. #define CXIMAGE     150
  44. #define CYIMAGE     150
  45. #define SPLINE      100
  46.  
  47. #define min(a,b) ((a)>(b)? (b) : (a))
  48.  
  49.  
  50. PMApp* App;
  51.  
  52. /////////////////////////////////////////////////////////////////////////////
  53. //
  54. // PMPaintThread: paint thread class: allows to dump lenghty paint
  55. // operations on a secondary thread.
  56. //
  57. //
  58. // What to do to use the class: 
  59. // 1. create the class (you'll want to derive another class and redefine
  60. //      the paint function).
  61. // 2. when creating the window that uses the class (in the create() func.)
  62. //      open a DC of the window, get a PS, create the paint thread, and if
  63. //    you want, you may produce a segment on the PS. (openSegment with
  64. //    drawing mode set to DM_RETAIN).
  65. // 3. When WM_PAINT is sent to the window, do default processing (ie erasing
  66. //    the window, then stop drawing in the paint thread, wait for ready flag
  67. //    (readySem posted), and post the triggerSem to trigger drawing.
  68. // 4. When exiting the window, kill the thread, (optionally calling
  69. //    stop and waiting for ready flag).
  70. // 
  71. // note: it is not necessary to wait for the ready flag.
  72. //
  73. class PMPaintThread : public PMWindowThread 
  74. {
  75.  
  76.     PMPresSpace *pps;    
  77.     BOOL stopCalled;
  78.     
  79. public:
  80.     PMEventSemaphore *readySem,*triggerSem;
  81.  
  82.     PMPaintThread(PMPresSpace *p) : PMWindowThread() 
  83.     {
  84.         readySem = new PMEventSemaphore;
  85.         triggerSem = new PMEventSemaphore;
  86.         pps=p;
  87.     }
  88.     void main(void* =NULL) {
  89.         while (TRUE) {
  90.             readySem->post();           // we're ready...
  91.             triggerSem->wait();           // wait for trigger
  92.  
  93.             pps->setStopDraw(SDW_OFF); // default setting, do not stop drawing
  94.             stopCalled=FALSE;
  95.  
  96.             readySem->reset();           // we're not ready...
  97.             triggerSem->reset();       // deactivate trigger...
  98.             paint();
  99.         }
  100.     }
  101.     PMPresSpace *ps() { return pps; }
  102.     void stop()        
  103.     // try stop drawing, by calling GpiSetStopDraw (if drawing from a 
  104.     // segment) or by checking a flag in the paint function.
  105.     {
  106.         stopCalled=TRUE;
  107.         pps->setStopDraw(SDW_ON);
  108.     }
  109. protected:
  110.     void paint() 
  111.     {
  112.         pps->save();
  113.         pps->drawSegment(1L);
  114.         pps->restore(-1L);
  115.         for (int j=0; j<8; j++) {
  116.             for (int i=0; i<200 && !stopCalled; i++) {
  117.                 PMRect rcl(j*100,0,(j+1)*100,i);
  118.                 pps->fillRect(&rcl,CLR_BLUE+j);
  119.             }
  120.         }
  121.     }    
  122.  
  123. };
  124.  
  125. class BG_PaintWin : public PMWin 
  126. {
  127.     PMPaintThread *dthread;
  128.     PMDeviceContext *dc;
  129.     PMPresSpace *ps;
  130.     ULONG prtclass;
  131.     LONG delta;
  132. public:
  133.     BG_PaintWin(HAB ab,ULONG pc,LONG d) : PMWin("bgpaintwin",ab) {
  134.         createArgs->flCreateFlags|=FCF_ICON;
  135.         createArgs->idResources=ID_BGPAINT;
  136.         createArgs->pszTitle="bgpaint";
  137.         delta=d;
  138.         prtclass=pc;
  139.     } ;
  140.     BOOL create(PMEvent &)
  141.     {
  142.         if (!dthread) {
  143.             dc= new PMDeviceContext( hwnd );
  144.             ps = new PMPresSpace(dc, 0, 0, PU_LOENGLISH | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC, ab) ;
  145.             dthread = new PMPaintThread(ps);
  146.  
  147.             dthread->setPriority(PRTYS_THREAD,prtclass,delta);
  148.             // produce a simple segment to show how it is done
  149.             // segments are collections of Gpi commands which are not
  150.             // executed directly but are kept in the PS. When the 
  151.             // drawSegment command is invoked the whole segment is
  152.             // drawn in one pass. It is possible to stop the lenghty 
  153.             // drawing operation with setStopDraw.
  154.             ps->setDrawingMode ( DM_RETAIN) ;
  155.             ps->openSegment (1L) ;
  156.             drawImage () ;
  157.             ps->closeSegment () ;
  158.         }
  159.         return TRUE;
  160.     }
  161.  
  162.     // parts of this code was taken from an example by Charles Petzold, quote:
  163. /*---------------------------------------------------------
  164.    THREADS3.C -- Demonstrates drawing from a second thread
  165.                  (c) 1990, Ziff Communications Co.
  166.                  PC Magazine * Charles Petzold, 2/90
  167.   ---------------------------------------------------------*/
  168.     
  169.     BOOL size(SHORT sx,SHORT sy)
  170.     {
  171.         dthread->stop();
  172.         dthread->readySem->wait();
  173.         SIZEL sizlClient ;
  174.         // get new size of client window
  175.  
  176.         sizlClient.cx = sx ;
  177.         sizlClient.cy = sy ;
  178.  
  179.         // set the new default view matrix
  180.  
  181.         GpiConvert (*ps, CVTC_DEVICE, CVTC_PAGE, 1L, (PPOINTL) &sizlClient);
  182.         FIXED    afxScale[2] ;
  183.         MATRIXLF matlf ;
  184.         POINTL   ptl ;
  185.  
  186.         afxScale[0] = afxScale[1] = min (65536L * sizlClient.cx / CXIMAGE,
  187.                                       65536L * sizlClient.cy / CYIMAGE) ;
  188.         ptl.x = 0 ;
  189.         ptl.y = 0 ;
  190.  
  191.         GpiScale (*ps, &matlf, TRANSFORM_REPLACE, afxScale, &ptl) ;
  192.  
  193.         ptl.x = (sizlClient.cx - afxScale[0] *CXIMAGE / 65536L) / 2 ;
  194.         ptl.y = (sizlClient.cy - afxScale[1] * CYIMAGE / 65536L) / 2 ;
  195.  
  196.         GpiTranslate (*ps, &matlf, TRANSFORM_ADD, &ptl) ;
  197.  
  198.         GpiSetDefaultViewMatrix (*ps, 9L, &matlf, TRANSFORM_REPLACE) ;
  199.         return TRUE;
  200.     }
  201.     BOOL destroy()
  202.     {
  203.         if (dthread) {
  204.             dthread->stop();
  205.             dthread->kill();
  206.             delete dthread;
  207.             delete ps;
  208.         }
  209.         return TRUE;
  210.     }
  211.     BOOL paint()
  212.     {
  213.         PMRect rcl;
  214.         dthread->stop();
  215.         dthread->readySem->wait();
  216.         WinBeginPaint (hwnd, *ps, NULL) ;
  217.         rcl=this;
  218.         GpiErase (*ps) ;
  219.         ps->fillRect(&rcl,CLR_BLUE);
  220.         WinEndPaint (*ps) ;
  221.         dthread->triggerSem->post();
  222.         return TRUE;
  223.     }
  224.     BOOL other(PMEvent &event)
  225.     {
  226.         if (event.msg == WM_ERASEBACKGROUND) {
  227.             event.ret=(MRESULT)TRUE;
  228.             return TRUE;
  229.         }
  230.         return FALSE;
  231.     }
  232.  
  233.     void drawImage() 
  234.     {
  235. //        PMRect rcl;
  236. //        rcl=this;
  237. //          ps->setColor (CLR_DARKCYAN);
  238. //        ps->fillRect(&rcl,CLR_WHITE);
  239. //          ps->drawText (-1, "Background Paint main window ", &rcl, 0, 0, DT_TEXTATTRS | DT_CENTER | DT_VCENTER | DT_ERASERECT);
  240.      MATRIXLF matlf ;
  241.      POINTL   ptl, aptl[4] ;
  242.      SHORT    iAngle ;
  243.  
  244.                // Draw outline of letters
  245.  
  246.      drawLetters () ;
  247.  
  248.                // Use letters outline as clipping path
  249.  
  250.      GpiBeginPath (*ps, 1L) ;
  251.      drawLetters () ;
  252.      GpiEndPath (*ps) ;
  253.      GpiSetClipPath (*ps, 1L, SCP_AND | SCP_ALTERNATE) ;
  254.  
  255.      for (iAngle = 0 ; iAngle < 360 ; iAngle++)
  256.           {
  257.                     // Find matrix for rotation around origin
  258.  
  259.           ptl.x = 0 ;
  260.           ptl.y = 0 ;
  261.           GpiRotate (*ps, &matlf, TRANSFORM_REPLACE,
  262.                      MAKEFIXED (iAngle, 0), &ptl) ;
  263.  
  264.                     // Append matrix for translation to center of image
  265.  
  266.           ptl.x = CXIMAGE / 2 ;
  267.           ptl.y = CYIMAGE / 2 ;
  268.           GpiTranslate (*ps, &matlf, TRANSFORM_ADD, &ptl) ;
  269.  
  270.                     // Set model transform using composite matrix
  271.  
  272.           GpiSetModelTransformMatrix (*ps, 9L, &matlf, TRANSFORM_REPLACE) ;
  273.  
  274.                     // Draw spline curve
  275.  
  276.           aptl[0].x = 0 ;
  277.           aptl[0].y = 0 ;
  278.  
  279.           aptl[1].x = SPLINE / 3 ;
  280.           aptl[1].y = SPLINE / 2 ;
  281.  
  282.           aptl[2].x = 2 * SPLINE / 3 ;
  283.           aptl[2].y = - SPLINE / 2 ;
  284.  
  285.           aptl[3].x = SPLINE ;
  286.           aptl[3].y = 0 ;
  287.  
  288.           GpiMove (*ps, aptl) ;
  289.           GpiPolySpline (*ps, 3L, aptl + 1) ;
  290.           }
  291.     }
  292.     void drawLetters ()
  293.      {
  294.      POINTL ptl, aptl[3] ;
  295.  
  296.                     // Outside of 'P'
  297.  
  298.      ptl.x     =   4 ;  ptl.y     =   4 ;  GpiMove (*ps, &ptl) ;
  299.      ptl.x     =   4 ;  ptl.y     = 146 ;  GpiLine (*ps, &ptl) ;
  300.      ptl.x     =  45 ;  ptl.y     = 146 ;  GpiLine (*ps, &ptl) ;
  301.      aptl[0].x =  72 ;  aptl[0].y = 146 ;
  302.      aptl[1].x =  72 ;  aptl[1].y = 119 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  303.      ptl.x     =  72 ;  ptl.y     =  85 ;  GpiLine (*ps, &ptl) ;
  304.      aptl[0].x =  72 ;  aptl[0].y =  58 ;
  305.      aptl[1].x =  45 ;  aptl[1].y =  58 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  306.      ptl.x     =  35 ;  ptl.y     =  58 ;  GpiLine (*ps, &ptl) ;
  307.      ptl.x     =  35 ;  ptl.y     =   4 ;  GpiLine (*ps, &ptl) ;
  308.      ptl.x     =   4 ;  ptl.y     =   4 ;  GpiLine (*ps, &ptl) ;
  309.  
  310.                     // Inside of 'P'
  311.  
  312.      ptl.x     =  35 ;  ptl.y     =  77 ;  GpiMove (*ps, &ptl) ;
  313.      ptl.x     =  35 ;  ptl.y     = 125 ;  GpiLine (*ps, &ptl) ;
  314.      aptl[0].x =  43 ;  aptl[0].y = 125 ;
  315.      aptl[1].x =  43 ;  aptl[1].y = 117 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  316.      ptl.x     =  43 ;  ptl.y     =  85 ;  GpiLine (*ps, &ptl) ;
  317.      aptl[0].x =  43 ;  aptl[0].y =  77 ;
  318.      aptl[1].x =  35 ;  aptl[1].y =  77 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  319.  
  320.                     // Outline of 'C'
  321.  
  322.      ptl.x     = 116 ;  ptl.y     =  63 ;  GpiMove (*ps, &ptl) ;
  323.      ptl.x     = 145 ;  ptl.y     =  63 ;  GpiLine (*ps, &ptl) ;
  324.      ptl.x     = 145 ;  ptl.y     =  31 ;  GpiLine (*ps, &ptl) ;
  325.      aptl[0].x = 145 ;  aptl[0].y =   4 ;
  326.      aptl[1].x = 118 ;  aptl[1].y =   4 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  327.      ptl.x     = 103 ;  ptl.y     =   4 ;  GpiLine (*ps, &ptl) ;
  328.      aptl[0].x =  76 ;  aptl[0].y =   4 ;
  329.      aptl[1].x =  76 ;  aptl[1].y =  31 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  330.      ptl.x     =  76 ;  ptl.y     = 119 ;  GpiLine (*ps, &ptl) ;
  331.      aptl[0].x =  76 ;  aptl[0].y = 146 ;
  332.      aptl[1].x = 103 ;  aptl[1].y = 146 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  333.      ptl.x     = 118 ;  ptl.y     = 146 ;  GpiLine (*ps, &ptl) ;
  334.      aptl[0].x = 145 ;  aptl[0].y = 146 ;
  335.      aptl[1].x = 145 ;  aptl[1].y = 119 ;  GpiPolyFillet (*ps, 2L, aptl) ;
  336.      ptl.x     = 145 ;  ptl.y     =  88 ;  GpiLine (*ps, &ptl) ;
  337.      ptl.x     = 116 ;  ptl.y     =  88 ;  GpiLine (*ps, &ptl) ;
  338.      ptl.x     = 116 ;  ptl.y     = 123 ;  GpiLine (*ps, &ptl) ;
  339.      aptl[0].x = 116 ;  aptl[0].y = 127 ;
  340.      aptl[1].x = 108 ;  aptl[1].y = 127 ;
  341.      aptl[2].x = 108 ;  aptl[2].y = 123 ;  GpiPolyFillet (*ps, 3L, aptl) ;
  342.      ptl.x     = 108 ;  ptl.y     =  30 ;  GpiLine (*ps, &ptl) ;
  343.      aptl[0].x = 108 ;  aptl[0].y =  26 ;
  344.      aptl[1].x = 116 ;  aptl[1].y =  26 ;
  345.      aptl[2].x = 116 ;  aptl[2].y =  30 ;  GpiPolyFillet (*ps, 3L, aptl) ;
  346.      ptl.x     = 116 ;  ptl.y     =  63 ;  GpiLine (*ps, &ptl) ;
  347.      }
  348. };
  349.  
  350.  
  351. int main (int argc,char* argv[])
  352. {
  353.     ULONG pc;
  354.     LONG d;
  355.  
  356.     if (argc>1) {
  357.         if (argc!=3 || strcmp(argv[1],"-?")==0) {
  358.             fprintf(stderr,"bg_paint <priority class 1..4> <delta level -31..31>\n");
  359.             exit(0);
  360.         } else {
  361.             pc=atol(argv[1]);
  362.             d=atol(argv[2]);
  363.         }                
  364.     } else {
  365.         pc=1;
  366.         d=16;
  367.     }
  368.  
  369.     PMAnchorBlock ab;
  370.     PMMessageQueue mq;
  371.     ab.init();
  372.     mq.create(ab);
  373.  
  374.  
  375.     App=new PMApp(ab,mq,argc,argv);
  376.  
  377.     BG_PaintWin * bgpw=new BG_PaintWin(ab,pc,d);
  378.     bgpw->createWin();
  379.  
  380.     App->run();
  381.  
  382.     bgpw->destroyWin();
  383.  
  384.     mq.destroy();
  385.     ab.uninit();
  386.  
  387.     return (0);
  388. }
  389.  
  390. /*
  391.  * Local variables:
  392.  * compile-command: "dmake bg_paint.exe"
  393.  * end:
  394.  */
  395.