Category : Files from Magazines
Archive   : VOL9N12.ZIP
Filename : THREADS3.C

 
Output of file : THREADS3.C contained in archive : VOL9N12.ZIP
®RHA®PT2¯®LM10¯®RM75¯ENVIRONMENTS o CHARLES PETZOLD p. ®PN¯ of ®FP¯
Vol. 9, No. 12
Filename: ®VA$FI¯


¯®PT2¯®LM20¯®RM50.5¯®LS2¯®TS22¯
®NB¯®PT11¯®LM0¯®RM80¯®AL1¯®TS8,16,24,32,40¯
CODE BOX
THREADS3.C
COMPLETE LISTING



/*---------------------------------------------------------
THREADS3.C -- Demonstrates drawing from a second thread
(c) 1990, Ziff Communications Co.
PC Magazine * Charles Petzold, 2/90
---------------------------------------------------------*/

#define INCL_WIN
#define INCL_GPI
#include
#include
#include

#define CXIMAGE 150
#define CYIMAGE 150
#define SPLINE 100
#define STACKSIZE (4096 * sizeof (int))
#define SEGNAME 1L
#define PI 3.14159

typedef struct
{
HPS hps ;
BOOL fTerminate ;
ULONG semTriggerDraw ;
ULONG semDoingDraw ;
}
THREADPARAMS ;

MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
VOID FAR SecondThread (THREADPARAMS *) ;
VOID ScaleImageToClient (HPS, SIZEL *) ;
VOID DrawImage (HPS) ;
VOID DrawLetters (HPS) ;

HAB hab ;

int main (void)
{
static CHAR szClientClass [] = "Threads3" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION | FCF_TASKLIST ;
HAB hab ;
HMQ hmq ;
HWND hwndFrame, hwndClient ;
QMSG qmsg ;

hab = WinInitialize (0) ;
hmq = WinCreateMsgQueue (hab, 0) ;
WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;

hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, szClientClass, NULL,
0L, NULL, 0, &hwndClient) ;

while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
WinDispatchMsg (hab, &qmsg) ;

WinDestroyWindow (hwndFrame) ;
WinDestroyMsgQueue (hmq) ;
WinTerminate (hab) ;
return 0 ;
}

MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static int aiThreadStack [STACKSIZE / sizeof (int)] ;
static THREADPARAMS tp ;
HDC hdc ;
SIZEL sizlPage, sizlClient ;

switch (msg)
{
case WM_CREATE:
// create a presentation space for the window

hdc = WinOpenWindowDC (hwnd) ;
sizlPage.cx = 0 ;
sizlPage.cy = 0 ;
tp.hps = GpiCreatePS (hab, hdc, &sizlPage,
PU_LOENGLISH | GPIF_DEFAULT |
GPIT_NORMAL | GPIA_ASSOC) ;

// start the thread after initialization

tp.fTerminate = FALSE ;

DosSemSet (&tp.semTriggerDraw) ;
DosSemClear (&tp.semDoingDraw) ;

_beginthread (SecondThread, aiThreadStack, STACKSIZE, &tp) ;

// create the segment

GpiSetDrawingMode (tp.hps, DM_RETAIN) ;

GpiOpenSegment (tp.hps, SEGNAME) ;
DrawImage (tp.hps) ;
GpiCloseSegment (tp.hps) ;
return 0 ;

case WM_SIZE:
// stop the thread from drawing

GpiSetStopDraw (tp.hps, SDW_ON) ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;

// get new size of client window

sizlClient.cx = SHORT1FROMMP (mp2) ;
sizlClient.cy = SHORT2FROMMP (mp2) ;

// set the new default view matrix

GpiConvert (tp.hps, CVTC_DEVICE, CVTC_PAGE, 1L,
(PPOINTL) &sizlClient) ;

ScaleImageToClient (tp.hps, &sizlClient) ;
return 0 ;

case WM_PAINT:
// stop the thread from drawing

GpiSetStopDraw (tp.hps, SDW_ON) ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;

// erase the window

WinBeginPaint (hwnd, tp.hps, NULL) ;
GpiErase (tp.hps) ;
WinEndPaint (tp.hps) ;

// let the thread continue

GpiSetStopDraw (tp.hps, SDW_OFF) ;
DosSemSet (&tp.semDoingDraw) ;
DosSemClear (&tp.semTriggerDraw) ;
return 0 ;

case WM_DESTROY:
// stop the thread

tp.fTerminate = TRUE ;
GpiSetStopDraw (tp.hps, SDW_ON) ;
DosSemWait (&tp.semDoingDraw, SEM_INDEFINITE_WAIT) ;

// clean up

GpiDeleteSegment (tp.hps, SEGNAME) ;
GpiAssociate (tp.hps, NULL) ;
GpiDestroyPS (tp.hps) ;
return 0 ;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
}

VOID _CDECL FAR SecondThread (THREADPARAMS * ptp)
{
HAB hab ;

hab = WinInitialize (0) ;

while (!ptp->fTerminate)
{
// wait for the semaphore to be cleared

DosSemWait (&ptp->semTriggerDraw, SEM_INDEFINITE_WAIT) ;

// draw the image

GpiSavePS (ptp->hps) ;
GpiDrawSegment (ptp->hps, SEGNAME) ;
GpiRestorePS (ptp->hps, -1L) ;

// set and clear the semaphores

DosSemSet (&ptp->semTriggerDraw) ;
DosSemClear (&ptp->semDoingDraw) ;
}

WinTerminate (hab) ;
_endthread () ;
}

VOID ScaleImageToClient (HPS hps, SIZEL *psizlClient)
{
FIXED afxScale[2] ;
MATRIXLF matlf ;
POINTL ptl ;

afxScale[0] = afxScale[1] = min (65536L * psizlClient->cx / CXIMAGE,
65536L * psizlClient->cy / CYIMAGE) ;
ptl.x = 0 ;
ptl.y = 0 ;

GpiScale (hps, &matlf, TRANSFORM_REPLACE, afxScale, &ptl) ;

ptl.x = (psizlClient->cx - afxScale[0] * CXIMAGE / 65536L) / 2 ;
ptl.y = (psizlClient->cy - afxScale[1] * CYIMAGE / 65536L) / 2 ;

GpiTranslate (hps, &matlf, TRANSFORM_ADD, &ptl) ;

GpiSetDefaultViewMatrix (hps, 9L, &matlf, TRANSFORM_REPLACE) ;
}

VOID DrawImage (HPS hps)
{
MATRIXLF matlf ;
POINTL ptl, aptl[4] ;
SHORT iAngle ;

// Draw outline of letters

DrawLetters (hps) ;

// Use letters outline as clipping path

GpiBeginPath (hps, 1L) ;
DrawLetters (hps) ;
GpiEndPath (hps) ;
GpiSetClipPath (hps, 1L, SCP_AND | SCP_ALTERNATE) ;

for (iAngle = 0 ; iAngle < 360 ; iAngle++)
{
// Find matrix for rotation around origin

ptl.x = 0 ;
ptl.y = 0 ;
GpiRotate (hps, &matlf, TRANSFORM_REPLACE,
MAKEFIXED (iAngle, 0), &ptl) ;

// Append matrix for translation to center of image

ptl.x = CXIMAGE / 2 ;
ptl.y = CYIMAGE / 2 ;
GpiTranslate (hps, &matlf, TRANSFORM_ADD, &ptl) ;

// Set model transform using composite matrix

GpiSetModelTransformMatrix (hps, 9L, &matlf, TRANSFORM_REPLACE) ;

// Draw spline curve

aptl[0].x = 0 ;
aptl[0].y = 0 ;

aptl[1].x = SPLINE / 3 ;
aptl[1].y = SPLINE / 2 ;

aptl[2].x = 2 * SPLINE / 3 ;
aptl[2].y = - SPLINE / 2 ;

aptl[3].x = SPLINE ;
aptl[3].y = 0 ;

GpiMove (hps, aptl) ;
GpiPolySpline (hps, 3L, aptl + 1) ;
}
}

VOID DrawLetters (HPS hps)
{
POINTL ptl, aptl[3] ;

// Outside of 'P'

ptl.x = 4 ; ptl.y = 4 ; GpiMove (hps, &ptl) ;
ptl.x = 4 ; ptl.y = 146 ; GpiLine (hps, &ptl) ;
ptl.x = 45 ; ptl.y = 146 ; GpiLine (hps, &ptl) ;
aptl[0].x = 72 ; aptl[0].y = 146 ;
aptl[1].x = 72 ; aptl[1].y = 119 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 72 ; ptl.y = 85 ; GpiLine (hps, &ptl) ;
aptl[0].x = 72 ; aptl[0].y = 58 ;
aptl[1].x = 45 ; aptl[1].y = 58 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 35 ; ptl.y = 58 ; GpiLine (hps, &ptl) ;
ptl.x = 35 ; ptl.y = 4 ; GpiLine (hps, &ptl) ;
ptl.x = 4 ; ptl.y = 4 ; GpiLine (hps, &ptl) ;

// Inside of 'P'

ptl.x = 35 ; ptl.y = 77 ; GpiMove (hps, &ptl) ;
ptl.x = 35 ; ptl.y = 125 ; GpiLine (hps, &ptl) ;
aptl[0].x = 43 ; aptl[0].y = 125 ;
aptl[1].x = 43 ; aptl[1].y = 117 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 43 ; ptl.y = 85 ; GpiLine (hps, &ptl) ;
aptl[0].x = 43 ; aptl[0].y = 77 ;
aptl[1].x = 35 ; aptl[1].y = 77 ; GpiPolyFillet (hps, 2L, aptl) ;

// Outline of 'C'

ptl.x = 116 ; ptl.y = 63 ; GpiMove (hps, &ptl) ;
ptl.x = 145 ; ptl.y = 63 ; GpiLine (hps, &ptl) ;
ptl.x = 145 ; ptl.y = 31 ; GpiLine (hps, &ptl) ;
aptl[0].x = 145 ; aptl[0].y = 4 ;
aptl[1].x = 118 ; aptl[1].y = 4 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 103 ; ptl.y = 4 ; GpiLine (hps, &ptl) ;
aptl[0].x = 76 ; aptl[0].y = 4 ;
aptl[1].x = 76 ; aptl[1].y = 31 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 76 ; ptl.y = 119 ; GpiLine (hps, &ptl) ;
aptl[0].x = 76 ; aptl[0].y = 146 ;
aptl[1].x = 103 ; aptl[1].y = 146 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 118 ; ptl.y = 146 ; GpiLine (hps, &ptl) ;
aptl[0].x = 145 ; aptl[0].y = 146 ;
aptl[1].x = 145 ; aptl[1].y = 119 ; GpiPolyFillet (hps, 2L, aptl) ;
ptl.x = 145 ; ptl.y = 88 ; GpiLine (hps, &ptl) ;
ptl.x = 116 ; ptl.y = 88 ; GpiLine (hps, &ptl) ;
ptl.x = 116 ; ptl.y = 123 ; GpiLine (hps, &ptl) ;
aptl[0].x = 116 ; aptl[0].y = 127 ;
aptl[1].x = 108 ; aptl[1].y = 127 ;
aptl[2].x = 108 ; aptl[2].y = 123 ; GpiPolyFillet (hps, 3L, aptl) ;
ptl.x = 108 ; ptl.y = 30 ; GpiLine (hps, &ptl) ;
aptl[0].x = 108 ; aptl[0].y = 26 ;
aptl[1].x = 116 ; aptl[1].y = 26 ;
aptl[2].x = 116 ; aptl[2].y = 30 ; GpiPolyFillet (hps, 3L, aptl) ;
ptl.x = 116 ; ptl.y = 63 ; GpiLine (hps, &ptl) ;
}



caption:
®BB¯®PT7¯®AL0¯®LM0¯®RM69.6¯®LS2¯®MDBO¯Figure 3:®MDNM¯ The THREADS3.C source code listing contains several new functions that require OS/2 1.2.


  3 Responses to “Category : Files from Magazines
Archive   : VOL9N12.ZIP
Filename : THREADS3.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/