Annotation of os232sdk/toolkt20/c/samples/semaph/sem_pnt.c, revision 1.1.1.1

1.1       root        1: /*==============================================================*\
                      2:  *  sem_pnt.c - routines for the painting of the main window    *
                      3:  *      Created 1990, Microsoft, IBM Corp.                      *
                      4:  *--------------------------------------------------------------*
                      5:  *                                                              *
                      6:  *  This module contains the code for the main client window    *
                      7:  *  painting                                                    *
                      8:  *                                                              *
                      9:  *--------------------------------------------------------------*
                     10:  *                                                              *
                     11:  *  This source file contains the following functions:          *
                     12:  *                                                              *
                     13:  *      DrawResource(PRECTL, COLOR) - Draws colored square      *
                     14:  *      DrawStats(USHORT) update the statistics for a thread    *
                     15:  *      ChangeResource(COLOR) - Changes resource color          *
                     16:  *      InitSemaphExample(VOID) - Sets initial colors           *
                     17:  *      SetRectPositions(HWND) - Calculate rectangle locations  *
                     18:  *      MyOffsetRect(PRECTL,SHORT,SHORT) - Offsets consumer     *
                     19:  *                                         rectangles from      *
                     20:  *                                         resource             *
                     21:  *      MainPaint(hwnd) - main WM_PAINT processing routine      *
                     22:  *                                                              *
                     23: \*==============================================================*/
                     24: 
                     25: /*--------------------------------------------------------------*\
                     26:  *  Include files, macros, defined constants, and externs       *
                     27: \*--------------------------------------------------------------*/
                     28: 
                     29: #define  LINT_ARGS
                     30: #define  INCL_PM
                     31: #define  INCL_BASE
                     32: 
                     33: #include <os2.h>
                     34: #include <stdio.h>
                     35: #include <stdlib.h>
                     36: #include <string.h>
                     37: #include "sem_pnt.h"
                     38: #include "sem_main.h"
                     39: #include "sem_xtrn.h"
                     40: #include "semaph.h"
                     41: 
                     42: /*--------------------------------------------------------------*\
                     43:  *  Global variables                                            *
                     44: \*--------------------------------------------------------------*/
                     45: CHAR szWindowText[MAXTEXTLEN]="Sample";
                     46: USHORT  cNumUsers = NUMUSERS;
                     47: SQ aSquares[MAXRESOURCES];
                     48: LONG colors[MAXUSERS]= {
                     49:     CLR_WHITE, CLR_BLACK, CLR_BLUE, CLR_RED, CLR_PINK, CLR_GREEN,
                     50:     CLR_CYAN, CLR_YELLOW, CLR_DARKGRAY, CLR_DARKBLUE, CLR_DARKRED,
                     51:     CLR_DARKPINK, CLR_DARKGREEN, CLR_DARKCYAN, CLR_BROWN, CLR_PALEGRAY};
                     52: 
                     53: LONG clrText[MAXUSERS]= {
                     54:     CLR_BLACK, CLR_WHITE, CLR_YELLOW, CLR_GREEN, CLR_BLACK, CLR_YELLOW,
                     55:     CLR_WHITE, CLR_RED, CLR_WHITE, CLR_BLUE, CLR_RED,
                     56:     CLR_PINK, CLR_GREEN, CLR_CYAN, CLR_WHITE, CLR_DARKGRAY};
                     57: 
                     58: /* static variables - only visible within this file */
                     59: static LONG  yStatsTop, yStatsBtm, xStatsRight, yBoardTop, yDescGlobal;
                     60: static POINTL ptlInfoOne, ptlInfoTwo;
                     61: SHORT   xWidth;
                     62: extern USHORT fSemaphoreStarted, fSemaphoreWasStarted;
                     63: 
                     64: /****************************************************************\
                     65:  * Routine to print informational message      
                     66:  *--------------------------------------------------------------
                     67:  *
                     68:  *  Name:     InfoLine (HPS)
                     69:  *            
                     70:  *  Purpose:  print informational message as space allows
                     71:  *
                     72:  *  Usage:    called from DrawRects on screen repaint
                     73:  *
                     74:  *  Method:   use information stored in global variables to
                     75:  *            calculate the position for 2 lines of informational
                     76:  *            text and lines to bracket them.
                     77:  *
                     78:  *  Returns:  none
                     79:  *
                     80: \****************************************************************/
                     81: VOID
                     82: InfoLine (HPS hps)
                     83: {
                     84:     POINTL  ptl;
                     85:     LONG    yBot;
                     86:     CHAR    acLineOne[MESSAGELEN];
                     87:     CHAR    acLineTwo[MESSAGELEN];
                     88: 
                     89:     /* print dividing line at bottom of stat display */
                     90:     ptl.x = 0;
                     91:     yBot = ptl.y = yStatsBtm - 2;
                     92:     GpiMove (hps, &ptl);
                     93:     ptl.x = xWidth;
                     94:     GpiLine (hps, &ptl);
                     95: 
                     96:     /* ptlInfoOne and ptlInfoTwo are intialized in SetRectPositions
                     97:      * when the window is created or resized.
                     98:      * The y coordinate will be zero if the window is too small
                     99:      * for the informational text.
                    100:      */
                    101:     if (ptlInfoOne.y) {
                    102:         /* load informational text from resource file */
                    103:         memset (acLineOne, 0, MESSAGELEN);
                    104:         if(WinLoadString(hab, NULL, IDS_INFOONE, MESSAGELEN, (PSZ)acLineOne)) {
                    105:             GpiCharStringAt (hps, &ptlInfoOne, MESSAGELEN, acLineOne);
                    106:             yBot = ptlInfoOne.y - yDescGlobal - 1;
                    107:         }
                    108:     }
                    109:     
                    110:     if (ptlInfoTwo.y) {
                    111:         /* load informational text from resource file */
                    112:         memset (acLineTwo, 0, MESSAGELEN);
                    113:         if(WinLoadString(hab, NULL, IDS_INFOTWO, MESSAGELEN, (PSZ)acLineTwo)) {
                    114:             GpiCharStringAt (hps, &ptlInfoTwo, MESSAGELEN, acLineTwo);
                    115:             yBot = ptlInfoTwo.y - yDescGlobal - 1;
                    116:         }
                    117:     }
                    118: 
                    119:     /* if there is informational text, then print another line at the top
                    120:      * of the "game board".
                    121:      */
                    122:     if (yBoardTop != yStatsBtm) {
                    123:         ptl.x = 0;
                    124:         ptl.y = min (yBoardTop + 1, yBot);
                    125:         GpiMove (hps, &ptl);
                    126:         ptl.x = xWidth;
                    127:         GpiLine (hps, &ptl);
                    128:     }
                    129: }
                    130: 
                    131: /****************************************************************\
                    132:  * Routine to draw the resource rectangle.                      *
                    133:  *--------------------------------------------------------------*
                    134:  *                                                              *
                    135:  *  Name:     DrawResource(PRECTL, COLOR)                       *
                    136:  *                                                              *
                    137:  *  Purpose:  Color 1 of the 64 rectangles on the playing board.*
                    138:  *                                                              *
                    139:  *  Usage:    Called from ThreadConsumer in semaph.c when       *
                    140:  *            resource becomes owned by a thread.               *
                    141:  *                                                              *
                    142:  *  Method:   Get the PS from global hwndMain and  WinFillRect. *
                    143:  *            This rountine is included so that no access       *
                    144:  *            to the resouce is made outside of paint.c.        *
                    145:  *            This is to produce code which is more             *
                    146:  *            object orientated.                                *
                    147:  *                                                              *
                    148:  *  Returns:  none                                              *
                    149:  *                                                              *
                    150: \****************************************************************/
                    151: 
                    152: VOID DrawResource(PRECTL prcl, COLOR color)
                    153: {
                    154:     HPS hps;
                    155: 
                    156:     hps = WinGetPS(hwndMain);
                    157:     /* this code is related to the WinFillRect in DrawRects.
                    158:      * they should stay in synch with each other.
                    159:      */
                    160:     WinFillRect(hps,prcl,color);
                    161:     WinReleasePS(hps);
                    162: }
                    163: 
                    164: /****************************************************************\
                    165:  * update the statistics (number of hits) for a thread          *
                    166:  *--------------------------------------------------------------*
                    167:  *                                                              *
                    168:  *  Name:     DrawStats(USHORT)                                 *
                    169:  *                                                              *
                    170:  *  Purpose:  update statistics display for for a thread        *
                    171:  *                                                              *
                    172:  *  Usage:    Called from ThreadConsumer in semaph.c when       *
                    173:  *            resource becomes owned by a thread.               *
                    174:  *                                                              *
                    175:  *                                                              *
                    176:  *  Method:   Get the PS, set colors, print number of hits for  *
                    177:  *            the thread identified by usMyID.                  *
                    178:  *            This rountine is included so that no access       *
                    179:  *            to the resouce is made outside of paint.c.        *
                    180:  *                                                              *
                    181:  *  Returns:                                                    *
                    182:  *                                                              *
                    183: \****************************************************************/
                    184: 
                    185: VOID DrawStats(USHORT usMyID)
                    186: {
                    187:     HPS hps;
                    188:     POINTL  ptl;
                    189:     THRDATA *pThr = &thrConsumers[usMyID];
                    190:     CHAR    szBuf [CNT_SZHITS];
                    191: 
                    192:     ptl.x = pThr->rcl.xLeft;
                    193:     ptl.y = pThr->rcl.yBottom;
                    194:     /* sprintf is non-reentrant, so it is used only when      
                    195:      * have the mutex.
                    196:      */
                    197:     sprintf (szBuf, "%4.4lu", pThr->lHits);
                    198:     hps = WinGetPS(hwndMain);
                    199:     GpiSetBackColor (hps, colors [usMyID]);
                    200:     GpiSetColor (hps, clrText [usMyID]);
                    201:     GpiCharStringPosAt (hps, &ptl, &pThr->rcl, CHS_CLIP | CHS_OPAQUE,
                    202:      strlen (szBuf), szBuf, NULL);
                    203:     WinReleasePS(hps);
                    204: }
                    205: 
                    206: 
                    207: /****************************************************************\
                    208:  *  Routine to paint rectangles in main window.                 *
                    209:  *--------------------------------------------------------------*
                    210:  *                                                              *
                    211:  *  Name:     DrawRects(HPS)                                    *
                    212:  *                                                              *
                    213:  *  Purpose:  Does painting of rectangles.                      *
                    214:  *                                                              *
                    215:  *  Usage:    Called from MainPaint when a paint message        *
                    216:  *            is received after the semaphore sample has        *
                    217:  *            been started.                                     *
                    218:  *                                                              *
                    219:  *  Method:   Uses WinFillRect API to color all owned squares on*
                    220:  *            the square "playing board". Updates stats for     *
                    221:  *            every active consumer thread. Prints the static   *
                    222:  *            informational text.                               *
                    223:  *                                                              *
                    224:  *  Returns:  none.                                             *
                    225:  *                                                              *
                    226: \****************************************************************/
                    227: 
                    228: VOID DrawRects(HPS hps)
                    229: {
                    230:     INT i;
                    231: 
                    232:     /*
                    233:      * Fill all rectangles in consumer array.... as well as rectangle
                    234:      * for resource.
                    235:      */
                    236:     if (fSemaphoreWasStarted) {
                    237:         for ( i = 0; i < MAXRESOURCES; i++ )
                    238:         {
                    239:             if (aSquares[i].usOwner < (USHORT) MAXUSERS &&
                    240:              aSquares[i].usOwner != (USHORT) UNOWNED) {
                    241:                 /* this line is identical to that in DrawResource.
                    242:                 * they should stay in synch with each other.
                    243:                 */
                    244:                 WinFillRect (hps, &aSquares[i].rcl, colors[aSquares[i].usOwner]);
                    245:             }
                    246:         }
                    247:     }
                    248:     InfoLine (hps);
                    249:     /* print statistics for each user */
                    250:     for (i = 0; i < cNumUsers; i++) {
                    251:         DrawStats (i);
                    252:     }
                    253: }
                    254: 
                    255: 
                    256: 
                    257: /********************************************************************\
                    258:  * Routine to size and set the positions of rectangle.          
                    259:  *------------------------------------------------------------------
                    260:  *                                                                  
                    261:  * Name:    SetRectPositions (xClient, yClient, yChar, yDesc)
                    262:  *          SHORT   xClient;    width of client window              
                    263:  *          SHORT   yClient;    height of client window             
                    264:  *          SHORT   yChar;      maximum baseline extender           
                    265:  *          SHORT   yDesc;      maximum char descender              
                    266:  *                                                                  
                    267:  * Purpose: Given above information about the window, calculate     
                    268:  *          the area need for the square game board, the statistics    
                    269:  *          display, and informative text.                          
                    270:  *                                                                  
                    271:  * Usage:   Called from MainWndProc whenever a size message         
                    272:  *          is received.                                            
                    273:  *                                                                  
                    274:  * Method:  Determines space needed for statistics display from the 
                    275:  *          font information given as parameters to this procedure. 
                    276:  *          Then calculates the 18 values which describe a chess    
                    277:  *          by distances from a corner along 2 adjacent sides.
                    278:  *          These are stored in arrays aX and aY. Given these values,
                    279:  *          rectangles are calculated for each square on the grid,
                    280:  *          and stored as part of the information about those squares.
                    281:  *          Then the size of the rectangles used for the stat display
                    282:  *          at the top of the window are calculated, and stored in
                    283:  *          the struct describing the thread. Finally, the position
                    284:  *          of the line of informative text which divides the two regions
                    285:  *          of colored squares is derived.
                    286:  *                                                                  
                    287:  * Returns: none                                                    
                    288:  *                                                                  
                    289: \********************************************************************/
                    290: 
                    291: VOID SetRectPositions(SHORT xClient, SHORT yClient, SHORT yChar, SHORT yDesc)
                    292: {
                    293:     INT     i;
                    294:     INT     dx;
                    295:     LONG aX [CNT_POINTS_EDGE];
                    296:     LONG aY [CNT_POINTS_EDGE];
                    297:     SHORT xScale, yScale;
                    298: 
                    299:     if (!fSemaphoreStarted)
                    300:     {
                    301:         /* insert code here for informative display */
                    302:     }
                    303:     
                    304:     /* top of stat display */
                    305:     yStatsTop = yClient;
                    306:     
                    307:     /* bottom of stat display */
                    308:     yStatsBtm = yClient - yChar - yDesc;
                    309:     
                    310:     /* width of stat display */
                    311:     xStatsRight = xClient;
                    312:     
                    313:     /* dx is the "scaling factor" for the statistics display */
                    314:     dx = xStatsRight / cNumUsers;
                    315:     
                    316:     /* rectangles for the stat display */    
                    317:     for (i = 0; i < cNumUsers; i++) {
                    318:         thrConsumers[i].rcl.yBottom = yStatsBtm;
                    319:         thrConsumers[i].rcl.yTop = yStatsTop;
                    320:         thrConsumers[i].rcl.xLeft = i * dx;
                    321:         thrConsumers[i].rcl.xRight = (i+1) * dx;
                    322:     }
                    323:     /* consume any unused edge */
                    324:     thrConsumers [cNumUsers - 1].rcl.xRight = xClient;
                    325: 
                    326:     /* if there is room for it, print an informational message */
                    327:     if (yStatsBtm > yChar + yDesc) {
                    328:         /* there is room for the first line */
                    329:         ptlInfoOne.x = 0;
                    330:         ptlInfoOne.y = yStatsBtm - yChar;
                    331:     }
                    332:     else
                    333:         ptlInfoOne.y = 0L;
                    334: 
                    335:     if (ptlInfoOne.y && ptlInfoOne.y > (2 * yDesc + yChar)) {
                    336:         /* room for second line */
                    337:         ptlInfoTwo.x = 0;
                    338:         ptlInfoTwo.y = ptlInfoOne.y - yChar - yDesc;
                    339:     }
                    340:     else
                    341:         ptlInfoTwo.y = 0L;
                    342: 
                    343:     /* calculate top of playing board, hence stored in yClient */
                    344:     if (ptlInfoTwo.y) {
                    345:         yClient = ptlInfoTwo.y - yDesc;
                    346:     }
                    347:     else if (ptlInfoOne.y) {
                    348:         yClient = ptlInfoOne.y - yDesc;
                    349:     }
                    350:     else
                    351:         yClient = yStatsBtm - 1;
                    352: 
                    353:     /* discard unusable portion */
                    354:     yClient = yClient - (yClient % CNT_SQUARES_EDGE);
                    355:     /* the scaling factors determine how large each square will be */
                    356:     xScale = xClient / CNT_SQUARES_EDGE;
                    357:     yScale = yClient / CNT_SQUARES_EDGE;
                    358:     
                    359:     /* the entire game board is described by the points that are
                    360:      * calculated here.
                    361:      */
                    362:     for (i = 0; i < CNT_POINTS_EDGE; i++) {
                    363:         aX[i] = i * xScale;
                    364:         aY[i] = i * yScale;
                    365:     }
                    366:     /* consume any unused portion */
                    367:     aX[CNT_SQUARES_EDGE] = aX[CNT_SQUARES_EDGE] + xClient % CNT_SQUARES_EDGE;
                    368:     aY[CNT_SQUARES_EDGE] = aY[CNT_SQUARES_EDGE] + yClient % CNT_SQUARES_EDGE - 1;
                    369: 
                    370:     /* now plug the points just calculated into the
                    371:      * rectangles that make up the board
                    372:      */
                    373:     for (i = 0; i < MAXRESOURCES; i++) {
                    374:         aSquares[i].rcl.xLeft = aX [i % CNT_SQUARES_EDGE];
                    375:         aSquares[i].rcl.xRight = aX [(i % CNT_SQUARES_EDGE) + 1];
                    376:         aSquares[i].rcl.yBottom = aY [i / CNT_SQUARES_EDGE];
                    377:         aSquares[i].rcl.yTop = aY [(i / CNT_SQUARES_EDGE) + 1];
                    378:     }
                    379:     /* store the descender for later */
                    380:     yDescGlobal = yDesc;
                    381:     /* store top of board for later reference */
                    382:     yBoardTop = aY[CNT_SQUARES_EDGE];
                    383:     /* finally, store the width of the client window for later reference */
                    384:     xWidth = xClient;
                    385: }
                    386: 
                    387: 
                    388: 
                    389: /****************************************************************\
                    390:  *   client painting routine                                *
                    391:  *--------------------------------------------------------------*
                    392:  *                                                              *
                    393:  *  Name:   MainPaint(hwnd)                                     *
                    394:  *                                                              *
                    395:  *  Purpose: Paints the main client window.                     *
                    396:  *                                                              *
                    397:  *  Usage:  Routine is called whenver the client window         *
                    398:  *          procedure receives a WM_PAINT message               *
                    399:  *                                                              *
                    400:  *  Method:                                                     *
                    401:  *          - begins painting by calling WinBeginPaint          *
                    402:  *            and retriving the HPS for the window              *
                    403:  *          - performs any painting desired.  Currently the     *
                    404:  *            only painting it does is to draw rectangles on    *
                    405:  *            the screen if semaphore is started.               *
                    406:  *          - ends painting by calling WinEndPaint              *
                    407:  *                                                              *
                    408:  *  Returns:                                                    *
                    409:  *                                                              *
                    410: \****************************************************************/
                    411: 
                    412: VOID MainPaint(hwnd)
                    413: HWND hwnd;     /* handle of the window to be painted */
                    414: {
                    415:     HPS hps;
                    416: 
                    417:     hps = WinBeginPaint(hwnd, NULL, NULL);
                    418:     GpiErase (hps);
                    419:     DrawRects (hps);
                    420:     WinEndPaint(hps);
                    421: 
                    422: }   /* MainPaint() */
                    423: 

unix.superglobalmegacorp.com

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