home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional Developers Kit 1992 November / Disc01 / Disc01.mdf / samples / wps / palette / palette.c next >
Encoding:
Text File  |  1992-07-28  |  35.3 KB  |  932 lines

  1. /*+--------------------------------------------------------------------------+*/
  2. /*|                                                                          |*/
  3. /*| PROGRAM NAME: PALETTE                                                    |*/
  4. /*| -------------                                                            |*/
  5. /*|  A PM program demonstrating vector fonts, palette manager api's, and IPF |*/
  6. /*|  help.                                                                   |*/
  7. /*|                                                                          |*/
  8. /*| COPYRIGHT:                                                               |*/
  9. /*| ----------                                                               |*/
  10. /*|  Copyright (C) International Business Machines Corp., 1992               |*/
  11. /*|                                                                          |*/
  12. /*| DISCLAIMER OF WARRANTIES:                                                |*/
  13. /*| -------------------------                                                |*/
  14. /*|  The following [enclosed] code is sample code created by IBM Corporation.|*/
  15. /*|  This sample code is not part of any standard IBM product and is provided|*/
  16. /*|  to you solely for the purpose of assisting you in the development of    |*/
  17. /*|  your applications.  The code is provided "AS IS", without warranty of   |*/
  18. /*|  any kind.  IBM shall not be liable for any damages arising out of your  |*/
  19. /*|  use of the sample code, even if they have been advised of the           |*/
  20. /*|  possibility of such damages.                                            |*/
  21. /*|                                                                          |*/
  22. /*| REVISION LEVEL: 1.0                                                      |*/
  23. /*| ---------------                                                          |*/
  24. /*|                                                                          |*/
  25. /*| WHAT THIS PROGRAM DOES:                                                  |*/
  26. /*| -----------------------                                                  |*/
  27. /*|  This program displays a standard window and then draws the IBM logo     |*/
  28. /*|  in the window.  The logo is done using a vector font.  Then a palette   |*/
  29. /*|  is created and rotated in another thread.                               |*/
  30. /*|                                                                          |*/
  31. /*| WHAT THIS PROGRAM DEMONSTRATES:                                          |*/
  32. /*| -------------------------------                                          |*/
  33. /*|  This program demonstrates how to create and display a standard window,  |*/
  34. /*|  use switched menus, use a second thread for drawing, modify a palette   |*/
  35. /*|  using some basic GPI calls, and display vectored fonts.                 |*/
  36. /*|                                                                          |*/
  37. /*| WHAT YOU NEED TO COMPILE THIS PROGRAM:                                   |*/
  38. /*| --------------------------------------                                   |*/
  39. /*|                                                                          |*/
  40. /*|  REQUIRED FILES:                                                         |*/
  41. /*|  ---------------                                                         |*/
  42. /*|                                                                          |*/
  43. /*|    PALETTE.C      - Source code                                          |*/
  44. /*|    PALETTE.MAK    - Make file for this program                           |*/
  45. /*|    PALETTE.DEP    - Dependency file for this program                     |*/
  46. /*|    PALETTE.DEF    - Module definition file                               |*/
  47. /*|    PALETTE.H      - Application header file                              |*/
  48. /*|    PALETTE.ICO    - Icon file                                            |*/
  49. /*|    PALETTE.RC     - Resource file                                        |*/
  50. /*|    PALETTE.IPF    - Documentation file for this program                  |*/
  51. /*|    PALETTE.DLG    - Dialog file                                          |*/
  52. /*|                                                                          |*/
  53. /*|    OS2.H          - Presentation Manager include file                    |*/
  54. /*|    STDLIB.H       - Standard library function declarations               |*/
  55. /*|    ...                                                                   |*/
  56. /*|                                                                          |*/
  57. /*|  REQUIRED LIBRARIES:                                                     |*/
  58. /*|  -------------------                                                     |*/
  59. /*|                                                                          |*/
  60. /*|    OS2386.LIB     - OS/2 API Library                                     |*/
  61. /*|                                                                          |*/
  62. /*|  REQUIRED PROGRAMS:                                                      |*/
  63. /*|  ------------------                                                      |*/
  64. /*|                                                                          |*/
  65. /*|    IBM C Set/2 Compiler (icc.exe    )                                    |*/
  66. /*|    IBM Linker           (link386.exe)                                    |*/
  67. /*|    Resource Compiler    (rc.exe     )                                    |*/
  68. /*|    Help Compiler        (ipfc.exe   )                                    |*/
  69. /*|                                                                          |*/
  70. /*|                                                                          |*/
  71. /*+--------------------------------------------------------------------------+*/
  72.  
  73. /*+--------------------------------------------------------------------------+*/
  74. /*| System and library header files.                                         |*/
  75. /*+--------------------------------------------------------------------------+*/
  76.  
  77. #define INCL_PM             // INCLUDE EVERYTHING - THIS IS ONLY SHOWN FOR
  78. #define INCL_DOSPROCESS     // SAMPLE PURPOSES, ONE SHOULD INCL_ ONLY
  79. #include <os2.h>            // THE NECESSARY HEADERS FOR COMPILE SPEED
  80.  
  81. #include <string.h>
  82. #include <stdlib.h>
  83. #include <stdio.h> 
  84. #include <stdarg.h> 
  85. #include "palette.h"
  86.  
  87.  
  88. /* 
  89.  * Globals
  90.  */
  91.  
  92. HAB     hab;
  93. HPAL    hPal=0L;
  94. HRGN    hrgn=0L;
  95. HDC     hdc = 0L;
  96. HMQ     hmqPalette;
  97. HWND    hwndPalette;
  98. HWND    hwndPaletteFrame;
  99. CHAR    szClassName[]   = "Palette";
  100. CHAR    szMessage[]     = "Palette Manager Sample";
  101.  
  102.  
  103. /*
  104.  * Status Flags For the options menu
  105.  */
  106.  
  107. #define SLOW_VALUE    100L
  108. #define MEDIUM_VALUE  10L                   /* Set speed constants            */
  109. #define FAST_VALUE     0L
  110.  
  111. BOOL  speedSlow      = FALSE;
  112. BOOL  speedMedium    = TRUE;                /* Initial Speed                  */
  113. BOOL  speedFast      = FALSE;
  114. ULONG animationSpeed = MEDIUM_VALUE;
  115.  
  116. BOOL  logoIBM        = FALSE;               /* Initial Text                   */
  117. BOOL  logoOS2        = TRUE;
  118.  
  119.  
  120. /*
  121.  * Palette Drawing Thread Globals
  122.  */
  123.  
  124. static SHORT   cxClient, cyClient;          /* client window X and Y size     */
  125. static USHORT  threadRun = FALSE;           /* non-zero means draw lines      */
  126. static HMTX    hmtxPS = 0L;                 /* PS access semaphore            */
  127. static HPS     hpsBuffer = 0L;     /* Presentation space for memory buffer    */
  128.  
  129. #define PAL_COUNT 128L       /* For the purposes of this example we will be   */
  130. ULONG alTable[PAL_COUNT];    /*        using 128 palette entries.             */
  131.  
  132. #define MSG_BOX_ID     256                  /* error message box id           */
  133.  
  134.  
  135. /*
  136.  * Required IPF Structure Declarations
  137.  */
  138.  
  139. HELPINIT hmiHelpData;                       /* Help initialization structure  */
  140. HWND     hwndHelpInstance;                  /* Handle to Help window          */
  141.  
  142.  
  143.  
  144.  
  145. /*
  146.  * Main routine...initializes window and message queue
  147.  */
  148. int main( ) 
  149. {
  150.    QMSG qmsg;
  151.    ULONG ctldata;
  152.  
  153.    /*
  154.     * Create your hab, hmq, and register a class. 
  155.     */
  156.  
  157.    hab = WinInitialize(0);
  158.  
  159.    hmqPalette = WinCreateMsgQueue(hab, 0);
  160.  
  161.    WinRegisterClass( hab,
  162.                      (PCH)szClassName,
  163.                      (PFNWP)PaletteWndProc,
  164.                      CS_SIZEREDRAW,
  165.                      0);
  166.  
  167.    /*+-----------------------------------------+*/
  168.    /*| IPF Initialization Structure            |*/
  169.    /*+-----------------------------------------+*/
  170.  
  171.    hmiHelpData.cb                       = sizeof(HELPINIT);
  172.    hmiHelpData.ulReturnCode             = 0;
  173.    hmiHelpData.pszTutorialName          = NULL;
  174.    hmiHelpData.phtHelpTable             = (PVOID)(0xffff0000 | MAIN_HELPTABLE);
  175.    hmiHelpData.hmodAccelActionBarModule = 0;
  176.    hmiHelpData.idAccelTable             = 0;
  177.    hmiHelpData.idActionBar              = 0;
  178.    hmiHelpData.pszHelpWindowTitle       = "Palette Help";
  179.    hmiHelpData.hmodHelpTableModule      = 0;
  180.    hmiHelpData.fShowPanelId             = 0;
  181.    hmiHelpData.pszHelpLibraryName       = "PALETTE.HLP";
  182.  
  183.  
  184.    /*+------------------------------------------+*/
  185.    /*| Create Instance of IPF                   |*/
  186.    /*|                                          |*/
  187.    /*| pass Anchor Block handle and address of  |*/
  188.    /*| IPF initialization structure, and check  |*/
  189.    /*| that creation was successful.            |*/
  190.    /*+------------------------------------------+*/
  191.  
  192.    if((hwndHelpInstance = WinCreateHelpInstance(hab, &hmiHelpData))==0L)
  193.       mprintf("Help Creation Error");
  194.  
  195.    else if (hmiHelpData.ulReturnCode)
  196.    {
  197.       mprintf("Help Terminated Due to Error %d",
  198.                hmiHelpData.ulReturnCode);
  199.  
  200.       WinDestroyHelpInstance(hwndHelpInstance);
  201.    }
  202.  
  203.  
  204.    /*
  205.     * Create a standard pm window and check  
  206.     * that creation was successful.
  207.     */
  208.  
  209.    ctldata = FCF_STANDARD;
  210.  
  211.    hwndPaletteFrame = WinCreateStdWindow( HWND_DESKTOP, 
  212.                                           WS_VISIBLE, 
  213.                                           &ctldata,
  214.                                           szClassName, 
  215.                                           szMessage,
  216.                                           0L, 
  217.                                           0L, 
  218.                                           ID_WINDOW,
  219.                                           &hwndPalette );
  220.    if (hwndPaletteFrame == 0L)
  221.    {
  222.       mprintf("WinCreateStdWindow error: 0x%04x",WinGetLastError(hab));
  223.       return 0;
  224.    }
  225.    WinShowWindow( hwndPaletteFrame, TRUE );
  226.  
  227.  
  228.    /*+-----------------------------------------+*/
  229.    /*| Associate Instance of IPF               |*/
  230.    /*|                                         |*/
  231.    /*| pass handle to Help Window and handle   |*/
  232.    /*| to frame window with which Help is      |*/
  233.    /*| to be associated.                       |*/
  234.    /*+-----------------------------------------+*/
  235.  
  236.    if (hwndHelpInstance)
  237.       WinAssociateHelpInstance(hwndHelpInstance, hwndPaletteFrame);
  238.  
  239.  
  240.    /*
  241.     * Poll messages from event queue 
  242.     */
  243.  
  244.    while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
  245.       WinDispatchMsg( hab, (PQMSG)&qmsg );
  246.  
  247.  
  248.    /*
  249.     * Clean up  
  250.     */
  251.  
  252.    if(hpsBuffer)        WinReleasePS( hpsBuffer );
  253.    if(hwndHelpInstance) WinDestroyHelpInstance( hwndHelpInstance );
  254.    if(hwndPaletteFrame) WinDestroyWindow( hwndPaletteFrame );
  255.    if(hmqPalette)       WinDestroyMsgQueue( hmqPalette );
  256.    WinTerminate( hab );
  257. }
  258.  
  259.  
  260. /*
  261.  * This routine processes WM_COMMAND, WM_PAINT.  It passes
  262.  * everything else to the Default Window Procedure.
  263.  */
  264. MRESULT PaletteWndProc(
  265.    HWND   hwnd,
  266.    ULONG  msg,
  267.    MPARAM mp1,
  268.    MPARAM mp2 )
  269. {
  270.    static RECTL  rctlClient,rctlSize;         /* client rectl's               */
  271.    TID    tidDrawing;                         /* drawing thread identifier    */
  272.    ULONG   cclr;
  273.    HPS     hps;
  274.    POINTL  aptl[4];
  275.    HWND    hwndMenu;                          /* Handle for the Menu bar      */
  276.  
  277.  
  278.    switch (msg) 
  279.    {
  280.  
  281.       /*+-----------------------------------------------------------------+*/
  282.       /*| In this example, the WinRealizePalette call is issued in        |*/
  283.       /*| response to a WM_REALIZEPALETTE. This ensures that the palette  |*/
  284.       /*| is appropriately realized for all drawing operations.           |*/
  285.       /*+-----------------------------------------------------------------+*/
  286.  
  287.    case WM_REALIZEPALETTE:
  288.          DosRequestMutexSem( hmtxPS, SEM_INDEFINITE_WAIT );
  289.          WinRealizePalette(hwnd, hpsBuffer, &cclr);
  290.          DosReleaseMutexSem( hmtxPS );
  291.       break;
  292.    
  293.  
  294.    case WM_CREATE:
  295.  
  296.    {
  297.       SIZEL sizl = { 0, 0 };
  298.  
  299.       /*+-----------------------------------------------------------------+*/
  300.       /*| The client window is being created.  Create the semaphore to    |*/
  301.       /*| control access to the presentation space.  Then create the      |*/
  302.       /*| thread that will draw the lines.                                |*/
  303.       /*+-----------------------------------------------------------------+*/
  304.  
  305.       DosCreateMutexSem( NULL, &hmtxPS, 0UL, FALSE );
  306.  
  307.       hdc = WinOpenWindowDC(hwnd);
  308.  
  309.  
  310.       /*+-----------------------------------------------------------------+*/
  311.       /*| Create a non-cached presentation space.  *We will not release   |*/
  312.       /*| this PS as we will be Selecting a Palette to this PS and then   |*/
  313.       /*| animating the palette.  Upon releasing a PS the palette is no   |*/
  314.       /*| longer selected for obvious reasons.                            |*/
  315.       /*+-----------------------------------------------------------------+*/
  316.  
  317.       hpsBuffer = GpiCreatePS( hab,
  318.                                hdc,
  319.                                &sizl,
  320.                                PU_PELS | GPIF_DEFAULT |
  321.                                GPIT_MICRO | GPIA_ASSOC );
  322.  
  323.       if(PaletteInit()) break;
  324.  
  325.       threadRun = TRUE;
  326.  
  327.       DosCreateThread( &tidDrawing,
  328.                        (PFNTHREAD) DrawingThread,
  329.                        0UL,
  330.                        0UL,
  331.                        8192UL );
  332.       
  333.       break;
  334.    }
  335.  
  336.    case WM_SIZE:
  337.       /*+-----------------------------------------------------------------+*/
  338.       /*| Window is being resized so get new client window size and       |*/
  339.       /*| recompute the end points for the lines.                         |*/
  340.       /*+-----------------------------------------------------------------+*/
  341.  
  342.       WinQueryWindowRect(hwnd,&rctlSize);
  343.  
  344.       cxClient = SHORT1FROMMP( mp2 );       /* Get new client window size     */
  345.       cyClient = SHORT2FROMMP( mp2 );
  346.       break;
  347.  
  348.    case WM_INITMENU:
  349.       switch (LOUSHORT(mp1)) 
  350.       {
  351.          case IDM_SPEED:
  352.             SetPulldownState(hwndPaletteFrame,IDM_SPEEDSLOW  ,speedSlow);
  353.             SetPulldownState(hwndPaletteFrame,IDM_SPEEDMEDIUM,speedMedium);
  354.             SetPulldownState(hwndPaletteFrame,IDM_SPEEDFAST  ,speedFast);
  355.             break;
  356.          case IDM_LOGO:
  357.             SetPulldownState(hwndPaletteFrame,IDM_LOGOIBM    ,logoIBM);
  358.             SetPulldownState(hwndPaletteFrame,IDM_LOGOOS2    ,logoOS2);
  359.             break;
  360.       }
  361.       break;
  362.  
  363.  
  364.    case WM_COMMAND:
  365.       switch (LOUSHORT(mp1)) 
  366.       {
  367.          case IDM_EXIT:
  368.             WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
  369.             break;
  370.  
  371.          case IDM_STARTSTOP:
  372.             hwndMenu = WinWindowFromID( hwndPaletteFrame, /* Get Menu Handle  */
  373.                                         FID_MENU );
  374.  
  375.             if ( speedSlow || speedMedium || speedFast  ) /* If running->stop */
  376.             {                                                      
  377.                speedSlow   = FALSE;                                 
  378.                speedMedium = FALSE;                       /* Set no speed     */
  379.                speedFast   = FALSE;                               
  380.                                                                   
  381.                WinSetMenuItemText( hwndMenu,              /* Change Menu Text */
  382.                                    IDM_STARTSTOP,         /* ID# for old text */
  383.                                    "Start" );             /* 'Change To' text */
  384.             }
  385.             else                                     /* If stopped then start */
  386.             {                                                     
  387.                if ( animationSpeed == SLOW_VALUE )
  388.                     speedSlow   = TRUE;                        
  389.                if ( animationSpeed == MEDIUM_VALUE )      /* Reset proper flag */
  390.                     speedMedium = TRUE;                      
  391.                if ( animationSpeed == FAST_VALUE )
  392.                     speedFast   = TRUE;
  393.  
  394.                WinSetMenuItemText( hwndMenu,              /* Change Menu Text */
  395.                                    IDM_STARTSTOP,         /* ID# for old text */
  396.                                    "Stop" );              /* 'Change To' text */
  397.             }                                                          
  398.             break;
  399.  
  400.                                                       
  401.  
  402.          case IDM_SPEEDSLOW:
  403.             speedSlow   = TRUE;
  404.             speedMedium = FALSE;
  405.             speedFast   = FALSE;
  406.             animationSpeed = SLOW_VALUE;
  407.             break;
  408.  
  409.          case IDM_SPEEDMEDIUM:
  410.             speedSlow   = FALSE;
  411.             speedMedium = TRUE;
  412.             speedFast   = FALSE;
  413.             animationSpeed = MEDIUM_VALUE;
  414.             break;
  415.  
  416.          case IDM_SPEEDFAST:
  417.             speedSlow   = FALSE;
  418.             speedMedium = FALSE;
  419.             speedFast   = TRUE;
  420.             animationSpeed = FAST_VALUE;
  421.             break;
  422.  
  423.          case IDM_LOGOIBM:
  424.             logoIBM = TRUE;
  425.             logoOS2 = FALSE;
  426.             WinInvalidateRect(hwnd, &rctlSize, FALSE);
  427.             break;
  428.  
  429.          case IDM_LOGOOS2:
  430.             logoIBM = FALSE;
  431.             logoOS2 = TRUE;
  432.             WinInvalidateRect(hwnd, &rctlSize, FALSE);
  433.             break;
  434.  
  435.          case IDM_HELPABOUT:               /* DISPLAY HELP ABOUT DIALOG       */
  436.             WinDlgBox(HWND_DESKTOP,        /* MAKE THE DESKTOP THE PARENT     */
  437.                       hwnd,                /* OWNED BY THE CLIENT WINDOW      */
  438.                       (PFNWP) AboutDlgProc,/* ADDRESS OF THE DIALOG PROCEDURE */
  439.                       0UL,                 /* MODULE HANDLE                   */
  440.                       IDD_ABOUT,           /* DIALOG IDENTIFIER IN RESOURCE   */
  441.                       NULL);               /* INITIALIZATION DATA             */
  442.  
  443.             WinInvalidateRect(hwnd, &rctlSize, FALSE);      /* Refresh Window */
  444.             break;
  445.  
  446.          case IDM_HELPFORHELP:
  447.             if (hwndHelpInstance) 
  448.             {
  449.                WinSendMsg( hwndHelpInstance, HM_DISPLAY_HELP, 0L, 0L);
  450.             }
  451.            break;
  452.  
  453.          case IDM_HELP_INDEX:
  454.             if (hwndHelpInstance) 
  455.             {
  456.                WinSendMsg(hwndHelpInstance, HM_HELP_CONTENTS, NULL, NULL);
  457.             }
  458.             break;
  459.  
  460.          case IDM_EXTENDED_HELP:
  461.             if (hwndHelpInstance) 
  462.             {
  463.                WinSendMsg(hwndHelpInstance, HM_DISPLAY_HELP,
  464.                MPFROMSHORT(IDM_EXTENDED_HELP), HM_RESOURCEID);
  465.             }
  466.             break;
  467.  
  468.          case IDM_KEYS_HELP:
  469.             if (hwndHelpInstance) 
  470.             {
  471.                WinSendMsg( hwndHelpInstance, 
  472.                            HM_DISPLAY_HELP,
  473.                            MPFROMLONG(MAKELONG(IDM_KEYS_HELP, NULL)),
  474.                            MPFROMSHORT(HM_RESOURCEID));
  475.             }
  476.             break;
  477.  
  478.          default: 
  479.             break;
  480.  
  481.       } /* end of switch within case WM_COMMAND */
  482.       break;
  483.  
  484.    case WM_PAINT: 
  485.  
  486.       /*+------------------------------------------------------+*/
  487.       /*| Since there will be two threads painting on the same |*/
  488.       /*| frame we will use a semaphore to resolve contention. |*/
  489.       /*+------------------------------------------------------+*/
  490.       
  491.       DosRequestMutexSem( hmtxPS, SEM_INDEFINITE_WAIT );
  492.  
  493.       /*
  494.        * Get a cached micro presentation space.
  495.        */
  496.       hps = WinBeginPaint( hwnd, 0L, &rctlClient );
  497.  
  498.       /*
  499.        * Fill the rectangle with the backgound color.
  500.        */
  501.       WinFillRect( hps, &rctlClient, CLR_BLACK );
  502.  
  503.       /*+-------------------------------------------------+*/
  504.       /*| The following code segment loads a vector font  |*/
  505.       /*| scales it to fit in the window and draws it     |*/
  506.       /*| vertically and horizontally centered.           |*/
  507.       /*+-------------------------------------------------+*/
  508.       {
  509.          POINTL       ptl;
  510.          SIZEF        sizfx;
  511.          FATTRS       fattrs;
  512.          CHARBUNDLE   cbnd;
  513.          ULONG        min;
  514.          LONG         cFonts, lTemp = 0L;
  515.          PFONTMETRICS pfm;
  516.          LONG         lcid = 1;
  517.          CHAR         fontName[25],outText[25];
  518.          USHORT       codePage;
  519.  
  520.  
  521.          min = (cxClient<cyClient) ? cxClient:cyClient;
  522.          min /=3;
  523.  
  524.          if(logoIBM)
  525.          {
  526.             strcpy(fontName,"Symbol Set");
  527.             codePage = 65400;
  528.             strcpy(outText,"Ä");
  529.          }
  530.          else
  531.          {
  532.             /*+-------------------------------------------+*/
  533.             /*| Define "Helvetica Bold" vector font,      |*/
  534.             /*| "Courier Bold" and "Times New Roman Bold" |*/
  535.             /*| are examples of other vector fonts.       |*/
  536.             /*+-------------------------------------------+*/
  537.             strcpy(fontName,"Helvetica Bold");
  538.             codePage = 850;
  539.             strcpy(outText,"OS/2");
  540.          }
  541.  
  542.          cFonts = GpiQueryFonts(hpsBuffer, QF_PUBLIC, fontName, &lTemp,
  543.              (LONG) sizeof(FONTMETRICS), NULL);
  544.  
  545.          pfm = malloc(sizeof(FONTMETRICS) * cFonts);
  546.  
  547.          GpiQueryFonts(hpsBuffer, QF_PUBLIC, fontName, &cFonts,
  548.              (LONG) sizeof(FONTMETRICS), pfm);
  549.        
  550.          fattrs.usRecordLength  = sizeof(FATTRS);
  551.          fattrs.fsSelection     = FATTR_SEL_OUTLINE;
  552.          fattrs.lMatch          = pfm[0].lMatch;
  553.          fattrs.idRegistry      = 0;
  554.          fattrs.usCodePage      = codePage;
  555.          fattrs.lMaxBaselineExt = 0;
  556.          fattrs.lAveCharWidth   = 0;
  557.          fattrs.fsType          = 0;
  558.          fattrs.fsFontUse       = FATTR_FONTUSE_OUTLINE;
  559.          strcpy(fattrs.szFacename,pfm[0].szFacename);
  560.  
  561.          GpiCreateLogFont(hpsBuffer, (PSTR8) NULL, lcid, &fattrs);
  562.          GpiSetCharSet(hpsBuffer, lcid);
  563.  
  564.          sizfx.cx = MAKEFIXED(min, 0);
  565.          sizfx.cy = MAKEFIXED(min, 0);
  566.          GpiSetCharBox(hpsBuffer, &sizfx);
  567.  
  568.          /*+------------------------------------------------+*/
  569.          /*| CALCULATE THE POINT TO START THE CENTERED TEXT |*/
  570.          /*+------------------------------------------------+*/
  571.          {
  572.             POINTL aptl[TXTBOX_COUNT];
  573.  
  574.             GpiQueryTextBox(hpsBuffer,
  575.                             strlen(outText),
  576.                             outText,
  577.                             TXTBOX_COUNT,      /* return maximum information  */
  578.                             aptl);             /* array of coordinates points */
  579.                                                /* in world coordinates.       */
  580.  
  581.  
  582.             ptl.x = (cxClient - aptl[TXTBOX_TOPRIGHT].x) / 2;
  583.             ptl.y = (cyClient - aptl[TXTBOX_TOPRIGHT].y) / 2;
  584.  
  585.          }
  586.  
  587.  
  588.  
  589.          /*+-------------------------------------------+*/
  590.          /*| Now that we have our vector font and      |*/
  591.          /*| location to place on the screen, lets     |*/
  592.          /*| create a Path using the outline font.     |*/
  593.          /*+-------------------------------------------+*/
  594.  
  595.          GpiBeginPath(hpsBuffer,1L);
  596.  
  597.          GpiMove(hpsBuffer,&ptl);
  598.          GpiCharString(hpsBuffer,strlen(outText),outText);
  599.  
  600.          GpiEndPath(hpsBuffer);
  601.  
  602.          /*+-----------------------------------------+*/
  603.          /*| Next lets erase the current clip path   |*/
  604.          /*| and assign the above outline font path  |*/
  605.          /*| as a clip path to the current hps.      |*/
  606.          /*+-----------------------------------------+*/
  607.  
  608.          GpiSetClipPath(hpsBuffer,
  609.                 0L,
  610.                 FPATH_ALTERNATE);
  611.  
  612.          GpiSetClipPath(hpsBuffer,
  613.                 1L,
  614.                 FPATH_ALTERNATE | SCP_AND);
  615.   
  616.  
  617.          /*+-------------------------------------------+*/
  618.          /*| Lastly draw a series of lines which will  |*/
  619.          /*| be clipped to attached clip path.         |*/
  620.          /*| *Draw on the Char Box                     |*/
  621.          /*+-------------------------------------------+*/
  622.  
  623.          DrawPaletteLines(rctlSize,
  624.                           PAL_COUNT,
  625.                           hpsBuffer);
  626.  
  627.          free(pfm);
  628.  
  629.       }
  630.  
  631.  
  632.       /*
  633.        * Release the cached micro presentation space.
  634.        */
  635.       WinEndPaint( hps );
  636.  
  637.       /*+------------------------------------------------------+*/
  638.       /*| Release the semaphore, thereby allowing the other    |*/
  639.       /*| thread to paint                                      |*/
  640.       /*+------------------------------------------------------+*/
  641.  
  642.       DosReleaseMutexSem( hmtxPS );
  643.  
  644.       break;
  645.  
  646.    default:
  647.       return WinDefWindowProc(hwnd, msg, mp1, mp2); 
  648.  
  649.    }
  650.    return 0L;
  651. }
  652.  
  653.  
  654.  
  655. /*+--------------------------------------------------------------------------+*/
  656. /*| AboutDlgProc - Help About Dialog Procedure                               |*/
  657. /*+--------------------------------------------------------------------------+*/
  658.  
  659. MRESULT AboutDlgProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
  660. {
  661. switch( msg )
  662.    {
  663.    case WM_COMMAND: /* DISMISS DIALOG */
  664.       WinDismissDlg( hwndDlg, TRUE );
  665.       break;
  666.  
  667.    default:
  668.       return (WinDefDlgProc( hwndDlg, msg, mp1, mp2 ));
  669.       break;
  670.    }
  671. return 0L;
  672. }
  673.  
  674.  
  675.  
  676. /*+--------------------------------------------------------------------------+*/
  677. /*| PaletteInit - Initializes the palette in the client window.              |*/
  678. /*+--------------------------------------------------------------------------+*/
  679. LONG PaletteInit()
  680. {
  681.    LONG    i;
  682.    LONG    ret = 0L;
  683.    ULONG   cclr;
  684.    
  685.    DosRequestMutexSem( hmtxPS, SEM_INDEFINITE_WAIT );
  686.  
  687.    /*+-----------------------------------+*/
  688.    /*| Create entry with shades of blue  |*/
  689.    /*+-----------------------------------+*/
  690.  
  691.    for(i=0;(ULONG) i < PAL_COUNT;i++)
  692.    {
  693.       LONG index;
  694.  
  695.       /*+----------------------------------------------------+*/
  696.       /*| INDEX = 128 POINTS EVENLY SPACED BETWEEN 1 AND 255 |*/
  697.       /*+----------------------------------------------------+*/
  698.       index = ((float) (i + 1) * 255.0) / (float) PAL_COUNT;
  699.  
  700.       alTable[i] = PC_RESERVED * 16777216 + LONGFromRGB(0,0,index); // BLUE
  701.  
  702.       //alTable[i] = PC_RESERVED * 16777216 + (index * 65536) + (0 * 256) + 0;//RED
  703.       //alTable[i] = PC_RESERVED * 16777216 + (0 * 65536) + (index * 256) + 0;//GREEN
  704.       //alTable[i] = PC_RESERVED * 16777216 + (0 * 65536) + (0 * 256) + index;//BLUE
  705.    }
  706.  
  707.    hPal = GpiCreatePalette( hab, 
  708.                             (ULONG) LCOL_PURECOLOR,
  709.                             (ULONG) LCOLF_CONSECRGB,
  710.                             PAL_COUNT,
  711.                             alTable );
  712.  
  713.    if( hPal == 0L || hPal == GPI_ERROR)
  714.    {
  715.       DosReleaseMutexSem( hmtxPS );
  716.       mprintf("GpiCreatePalette Error 0x%04x",ret = WinGetLastError(hab));
  717.    }
  718.  
  719.    else if(GpiSelectPalette(hpsBuffer, hPal ) == PAL_ERROR)
  720.    {
  721.       DosReleaseMutexSem( hmtxPS );
  722.       mprintf("GpiSelectPalette Error 0x%04x",ret = WinGetLastError(hab));
  723.    }
  724.  
  725.    else if( WinRealizePalette(hwndPalette,hpsBuffer,&cclr) == PAL_ERROR)
  726.    {
  727.       DosReleaseMutexSem( hmtxPS );
  728.       mprintf("WinRealizePalette Error 0x%04x",ret = WinGetLastError(hab));
  729.    }
  730.  
  731.    else
  732.    {
  733.       DosReleaseMutexSem( hmtxPS );
  734.    }
  735.  
  736.    return ret;
  737. }
  738.  
  739.  
  740. /*+--------------------------------------------------------------------------+*/
  741. /*| DrawPaletteLines - Procedure that draws the lines in the passed box.     |*/
  742. /*+--------------------------------------------------------------------------+*/
  743. VOID DrawPaletteLines(RECTL  rctl,
  744.                       ULONG ulPalCount, 
  745.                       HPS hps)
  746. {
  747.    LONG  color = 0L;                 /* foreground (line) color      */
  748.    POINTL ptl1,ptl2;
  749.    
  750.    ptl1.x = rctl.xLeft;
  751.    ptl1.y = rctl.yTop;
  752.    ptl2.x = rctl.xLeft;
  753.    ptl2.y = rctl.yBottom;
  754.  
  755.    while(ptl1.x <= rctl.xRight)
  756.    {
  757.       if ( (ULONG) color >= ulPalCount )
  758.           color = 0L;
  759.       else
  760.           color++;                   /* Increment foreground color   */
  761.  
  762.       ptl1.x ++;
  763.       ptl2.x ++;
  764.  
  765.       GpiSetColor( hps, color );
  766.       GpiMove( hps, &ptl1 );         /* Move to start point          */
  767.       GpiLine( hps, &ptl2 );         /* Draw new line                */
  768.     }
  769. }
  770.  
  771.  
  772.  
  773. /*+--------------------------------------------------------------------------+*/
  774. /*| DrawingThread - Procedure that animates the palette in the client window.|*/
  775. /*+--------------------------------------------------------------------------+*/
  776. static void DrawingThread( ULONG ulThreadArg )
  777. {
  778.    HAB   habThread2;               /* Anchor block handle for thread */
  779.    HMQ   hmqThread2;               /* Queue handle for thread        */
  780.    int   i;
  781.  
  782.    habThread2 = WinInitialize( 0 );
  783.    hmqThread2 = WinCreateMsgQueue( habThread2, 0 );
  784.  
  785.    while ( threadRun )
  786.    {
  787.       LONG temp;
  788.  
  789.  
  790. /*+--------------------------------------------------------------------------+*/
  791. /*|     The following if clause puts this thread to sleep as long as there   |*/
  792. /*| is no speed flag set, i.e. the animation is 'Stop'ed.                    |*/
  793. /*|     The else clause continues rotating the palette.                      |*/
  794. /*+--------------------------------------------------------------------------+*/
  795.       if (!speedSlow && !speedMedium && !speedFast ) 
  796.       {
  797.          DosSleep(500L);
  798.       }
  799.       else
  800.       {
  801.          /*+-----------------------------------------------------------+*/
  802.          /*| Request PS semaphore so that main thread does NOT use it. |*/
  803.          /*+-----------------------------------------------------------+*/
  804.  
  805.          DosRequestMutexSem( hmtxPS, SEM_INDEFINITE_WAIT );
  806.  
  807.          temp = alTable[ 0 ];
  808.          for(i = 0; (ULONG) i < PAL_COUNT - 1; i++)
  809.          {
  810.             alTable[ i ] = alTable[ i + 1 ];
  811.          }
  812.          alTable[ PAL_COUNT - 1 ] = temp;
  813.  
  814.          GpiAnimatePalette( hPal,
  815.                             LCOLF_CONSECRGB,
  816.                             0L,
  817.                             PAL_COUNT,
  818.                             alTable);
  819.  
  820.          /*+-----------------------+*/
  821.          /*| Release PS semaphore. |*/
  822.          /*+-----------------------+*/
  823.  
  824.          DosReleaseMutexSem( hmtxPS );
  825.  
  826.          /*+---------------------------------------------+*/
  827.          /* Surrender rest of timeslice to other threads. */                        
  828.          /* Never do a DosSleep(0) as this will not give  */
  829.          /* lower priority threads a time slice           */
  830.          /*+---------------------------------------------+*/
  831.  
  832.          if(animationSpeed) DosSleep( animationSpeed );
  833.       }
  834.    }
  835.  
  836.  
  837.    /*+----------------------------------------+*/
  838.    /*| Clean up and terminate drawing thread. |*/
  839.    /*+----------------------------------------+*/
  840.  
  841.    if(hPal) GpiDeletePalette( hPal );
  842.    WinTerminate( habThread2 );
  843.    DosExit( EXIT_THREAD, 0 );
  844. }
  845.  
  846.  
  847.  
  848. /*+--------------------------------------------------------------------------+*/
  849. /*|                                                                          |*/
  850. /*| FUNCTION NAME: mprintf                                                   |*/
  851. /*| --------------                                                           |*/
  852. /*|  A PM function for displaying a message box with a printf type format.   |*/
  853. /*|                                                                          |*/
  854. /*| EXPECTED INPUT:                                                          |*/
  855. /*| ---------------                                                          |*/
  856. /*|  See the definition of printf.                                           |*/
  857. /*|                                                                          |*/
  858. /*| EXPECTED OUTPUT:                                                         |*/
  859. /*| ----------------                                                         |*/
  860. /*|  Message Box                                                             |*/
  861. /*|                                                                          |*/
  862. /*| NOTES                                                                    |*/
  863. /*| ----------------                                                         |*/
  864. /*|  One must be carefull not to call this within a paint routine.  Because  |*/
  865. /*|  the closing of the message box will generate another paint message.     |*/
  866. /*|                                                                          |*/
  867. /*+--------------------------------------------------------------------------+*/
  868. LONG mprintf(PSZ format, ...)
  869. {
  870.    va_list pArg;
  871.    PSZ     buffer;
  872.    LONG    lCount;
  873.  
  874.    WinAlarm( HWND_DESKTOP, WA_ERROR );
  875.  
  876.    if(!(buffer = malloc(513))) return 0L;
  877.  
  878.    va_start(pArg, format);
  879.  
  880.    lCount = vsprintf(buffer, format, pArg);
  881.  
  882.    WinMessageBox( HWND_DESKTOP,       /* parent window handle    */
  883.                   HWND_DESKTOP,       /* owner window handle     */
  884.                   buffer,             /* pointer to message text */
  885.                   szClassName,        /* pointer to title text   */
  886.                   MSG_BOX_ID,         /* message box identifier  */
  887.                   MB_OK | MB_ERROR ); /* message box style       */
  888.  
  889.    return lCount;
  890. }
  891.  
  892.  
  893.  
  894. /*+--------------------------------------------------------------------------+*/
  895. /*|                                                                          |*/
  896. /*| FUNCTION NAME: SetPulldownState                                          |*/
  897. /*| --------------                                                           |*/
  898. /*|  A PM function for setting the check mark status of a menu item.         |*/
  899. /*|                                                                          |*/
  900. /*| EXPECTED INPUT:                                                          |*/
  901. /*| ---------------                                                          |*/
  902. /*|  Handle to the window containing the menu.                               |*/
  903. /*|  Item id within the menu to check.                                       |*/
  904. /*|  Bool indicating State to set TRUE=CHECKED FALSE=UNCHECKED               |*/
  905. /*|                                                                          |*/
  906. /*| EXPECTED OUTPUT:                                                         |*/
  907. /*| ----------------                                                         |*/
  908. /*|  None                                                                    |*/
  909. /*+--------------------------------------------------------------------------+*/
  910. void SetPulldownState( HWND   hwnd,
  911.                        USHORT item,
  912.                        BOOL   state)
  913. {
  914.    if (state)
  915.    {
  916.       WinSendMsg(WinWindowFromID(hwnd, FID_MENU), 
  917.                  MM_SETITEMATTR,
  918.                  MPFROM2SHORT(item, TRUE),
  919.                  MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  920.    }
  921.    else
  922.    {
  923.       WinSendMsg(WinWindowFromID(hwnd, FID_MENU), 
  924.                  MM_SETITEMATTR,
  925.                  MPFROM2SHORT(item, TRUE),
  926.                  MPFROM2SHORT(MIA_CHECKED, 0));
  927.    }
  928. }
  929.  
  930.  
  931.  
  932.