Annotation of os232sdk/toolkt20/c/samples/semaph/sem_pnt.c, revision 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.