[BACK]Return to gclient.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / os2

Annotation of OpenXM_contrib/gnuplot/os2/gclient.c, Revision 1.1.1.2

1.1       maekawa     1: #ifdef INCRCSDATA
1.1.1.2 ! maekawa     2: static char RCSid[]="$Id: gclient.c,v 1.7 1998/12/17 22:10:28 lhecking Exp $" ;
1.1       maekawa     3: #endif
                      4:
                      5: /****************************************************************************
                      6:
                      7:     PROGRAM: Gnupmdrv
                      8:
                      9:     MODULE:  gclient.c
                     10:
                     11:     This file contains the client window procedures for Gnupmdrv
                     12:
                     13: ****************************************************************************/
                     14:
                     15: /* PM driver for GNUPLOT */
                     16:
                     17: /*[
                     18:  * Copyright 1992, 1993, 1998   Roger Fearick
                     19:  *
                     20:  * Permission to use, copy, and distribute this software and its
                     21:  * documentation for any purpose with or without fee is hereby granted,
                     22:  * provided that the above copyright notice appear in all copies and
                     23:  * that both that copyright notice and this permission notice appear
                     24:  * in supporting documentation.
                     25:  *
                     26:  * Permission to modify the software is granted, but not the right to
                     27:  * distribute the complete modified source code.  Modifications are to
                     28:  * be distributed as patches to the released version.  Permission to
                     29:  * distribute binaries produced by compiling modified sources is granted,
                     30:  * provided you
                     31:  *   1. distribute the corresponding source modifications from the
                     32:  *    released version in the form of a patch file along with the binaries,
                     33:  *   2. add special version identification to distinguish your version
                     34:  *    in addition to the base release version number,
                     35:  *   3. provide your name and address as the primary contact for the
                     36:  *    support of your modified version, and
                     37:  *   4. retain our contact information in regard to use of the base
                     38:  *    software.
                     39:  * Permission to distribute the released version of the source code along
                     40:  * with corresponding source modifications in the form of a patch file is
                     41:  * granted with same provisions 2 through 4 for binary distributions.
                     42:  *
                     43:  * This software is provided "as is" without express or implied warranty
                     44:  * to the extent permitted by applicable law.
                     45: ]*/
                     46:
                     47: /*
                     48:  * AUTHOR
                     49:  *
                     50:  *   Gnuplot driver for OS/2:  Roger Fearick
                     51:  *
                     52:  * Send your comments or suggestions to
                     53:  *  info-gnuplot@dartmouth.edu.
                     54:  * This is a mailing list; to join it send a note to
                     55:  *  majordomo@dartmouth.edu.
                     56:  * Send bug reports to
                     57:  *  bug-gnuplot@dartmouth.edu.
                     58: **/
                     59:
                     60: #define INCL_PM
                     61: #define INCL_WIN
                     62: #define INCL_SPL
                     63: #define INCL_SPLDOSPRINT
                     64: #define INCL_WINSTDFONT
                     65: #define INCL_DOSMEMMGR
                     66: #define INCL_DOSPROCESS
                     67: #define INCL_DOSERRORS
                     68: #define INCL_DOSFILEMGR
                     69: #define INCL_DOSNMPIPES
                     70: #define INCL_DOSSESMGR
                     71: #define INCL_DOSSEMAPHORES
                     72: #define INCL_DOSMISC
                     73: #define INCL_DOSQUEUES
                     74: #define INCL_WINSWITCHLIST
                     75: #include <os2.h>
                     76: #include <string.h>
                     77: #include <stdio.h>
                     78: #include <io.h>
                     79: #include <fcntl.h>
                     80: #include <math.h>
                     81: #include <stdlib.h>
                     82: #include <unistd.h>
                     83: #include <process.h>
                     84: #include <signal.h>
                     85: #include "gnupmdrv.h"
                     86:
                     87: /*==== g l o b a l    d a t a ================================================*/
                     88:
                     89: extern char szIPCName[] ;       /* name used in IPC with gnuplot */
                     90: extern char szIniFile[256] ;    /* full path of ini file */
                     91: extern int  bServer ;
                     92: extern int  bPersist ;
                     93: extern int  bEnhanced ;
                     94:
                     95: /*==== l o c a l    d a t a ==================================================*/
                     96:
                     97: static long lLineTypes[7] = { LINETYPE_SOLID,
                     98:                               LINETYPE_SHORTDASH,
                     99:                               LINETYPE_DOT,
                    100:                               LINETYPE_DASHDOT,
                    101:                               LINETYPE_LONGDASH,
                    102:                               LINETYPE_DOUBLEDOT,
                    103:                               LINETYPE_DASHDOUBLEDOT } ;
                    104: static long lCols[16] =     { CLR_BLACK,
                    105:                               CLR_DARKGRAY,
                    106:                               CLR_BLUE,
                    107:                               CLR_RED,
                    108:                               CLR_GREEN,
                    109:                               CLR_CYAN,
                    110:                               CLR_PINK,
                    111:                               CLR_YELLOW,
                    112:                               CLR_DARKBLUE,
                    113:                               CLR_DARKRED,
                    114:                               CLR_DARKGREEN,
                    115:                               CLR_DARKCYAN,
                    116:                               CLR_DARKPINK,
                    117:                               CLR_BROWN,
                    118:                               CLR_PALEGRAY,
                    119:                               CLR_WHITE } ;
                    120:
                    121: static LONG alColourTable[ 16 ] ;
                    122:
                    123: #define   GNUBUF    1024        /* buffer for gnuplot commands */
                    124: #define   PIPEBUF   4096        /* size of pipe buffers */
                    125: #define   CMDALLOC  4096        /* command buffer allocation increment (ints) */
                    126: #define   ENVSIZE   2048        /* size of environment */
                    127:
                    128: #define   PAUSE_DLG 1           /* pause handled in dialog box */
                    129: #define   PAUSE_BTN 2           /* pause handled by menu item */
                    130: #define   PAUSE_GNU 3           /* pause handled by Gnuplot */
                    131:
                    132: #define   DEFLW     50
                    133:
                    134: static ULONG    ppidGnu=0L ;      /* gnuplot pid */
                    135: static HPS      hpsScreen ;     /* screen pres. space */
                    136: static int      iSeg = 1 ;
                    137:
                    138: static HSWITCH hSwitch = 0 ;    /* switching between windows */
                    139: static SWCNTRL swGnu ;
                    140:
                    141: static BOOL     bLineTypes = FALSE ;    // true if use dashed linetypes
                    142: BOOL     bWideLines ;
                    143: static BOOL     bColours = TRUE ;
                    144: static BOOL     bShellPos = FALSE ;
                    145: static BOOL     bPlotPos = FALSE ;
                    146: static BOOL     bPopFront = TRUE ;
                    147: static BOOL     bNewFont = FALSE ;
                    148: static BOOL     bHorz = TRUE ;
                    149:
                    150: static ULONG    ulPlotPos[4] ;
                    151: static ULONG    ulShellPos[4] ;
                    152: static PAUSEDATA pausedata = {sizeof(PAUSEDATA), NULL, NULL} ;
                    153: static char     szFontNameSize[FONTBUF] ;
                    154: static PRQINFO3 infPrinter = { "" } ;
                    155: static QPRINT   qPrintData = { sizeof(QPRINT), 0.0, 0.0, 1.0, 1.0, 0,
                    156:                                "", "", &infPrinter, 0, NULL } ;
                    157: //static HEV      semStartSeq ;   /* semaphore to start things in right sequence */
                    158: static HEV      semPause ;
                    159: static HMTX     semHpsAccess ;
                    160: static ULONG    ulPauseReply = 1 ;
                    161: static ULONG    ulPauseMode  = PAUSE_DLG ;
                    162:
                    163: static HWND     hSysMenu ;
                    164:             /* stuff for screen-draw thread control */
                    165:
                    166: static BOOL     bExist ;
                    167: //static HEV      semDrawDone ;
                    168:
                    169:             /* thread control */
                    170:
                    171: static TID     tidDraw, tidSpawn ;
                    172:
                    173:             /* font data */
                    174:
                    175: static int lSupOffset = 0 ;
                    176: static int lSubOffset = 0 ;
                    177: static int lBaseSupOffset = 0 ;
                    178: static int lBaseSubOffset = 0 ;
                    179: static int lCharWidth = 217 ;
                    180: static int lCharHeight = 465 ;
                    181:
                    182:
                    183: /*==== f u n c t i o n s =====================================================*/
                    184:
                    185: int             DoPrint( HWND ) ;
                    186: HBITMAP         CopyToBitmap( HPS ) ;
                    187: HMF             CopyToMetaFile( HPS ) ;
                    188: MRESULT         WmClientCmdProc( HWND , ULONG, MPARAM, MPARAM ) ;
                    189: void            ChangeCheck( HWND, USHORT, USHORT ) ;
                    190: BOOL            QueryIni( HAB ) ;
                    191: static void     SaveIni( HWND ) ;
                    192: static void     ThreadDraw( void* ) ;
                    193: static void     DoPaint( HWND, HPS ) ;
                    194: static void     Display( HPS ) ;
                    195: void            SelectFont( HPS, char * );
                    196: void            SwapFont( HPS, char * );
                    197: static void     CopyToClipBrd( HWND ) ;
                    198: static void     ReadGnu( void* ) ;
                    199: static void     EditLineTypes( HWND, HPS, BOOL ) ;
                    200: static void     EditCharCell( HPS, SIZEF* ) ;
                    201: static HPS      InitScreenPS( void ) ;
                    202: static int      BufRead( HFILE, void*, int, PULONG ) ;
                    203: int             GetNewFont( HWND, HPS ) ;
                    204: void            SigHandler( int ) ;
                    205: void            FontExpand( char * ) ;
                    206: static char    *ParseText(HPS, char *, BOOL, char *,
                    207:                        int, int, BOOL, BOOL ) ;
                    208: static void     CharStringAt(HPS, int, int, int, char *) ;
                    209: static int      QueryTextBox( HPS, int, char * ) ;
                    210: static void      LMove( HPS hps, POINTL *p ) ;
                    211: static void      LLine( HPS hps, POINTL *p ) ;
                    212: static void      LType( int iType ) ;
                    213:
                    214: /*==== c o d e ===============================================================*/
                    215:
                    216: MRESULT EXPENTRY DisplayClientWndProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
                    217: /*
                    218: **  Window proc for main window
                    219: **  -- passes most stuff to active child window via WmClientCmdProc
                    220: **  -- passes DDE messages to DDEProc
                    221: */
                    222: {
                    223:     static BOOL    bSw = FALSE ;
                    224:     static BOOL    bFirst = TRUE ;
                    225:     static RECTL   rectlPaint = { 0, 0, 0, 0 } ;
                    226:     static int     iPaintCount = 0 ;
                    227:     static int     firstcall = 1 ;
                    228:
                    229:     switch (message) {
                    230:
                    231:         case WM_CREATE:
                    232:             {
                    233:             HDC     hdcScreen ;
                    234:             SIZEL   sizlPage ;
                    235:                 // set initial values
                    236:             ChangeCheck( hWnd, IDM_LINES_THICK, bWideLines?IDM_LINES_THICK:0 ) ;
                    237:             ChangeCheck( hWnd, IDM_LINES_SOLID, bLineTypes?0:IDM_LINES_SOLID ) ;
                    238:             ChangeCheck( hWnd, IDM_COLOURS, bColours?IDM_COLOURS:0 ) ;
                    239:             ChangeCheck( hWnd, IDM_FRONT, bPopFront?IDM_FRONT:0 ) ;
                    240:                 // disable close from system menu (close only from gnuplot)
                    241:             hApp = WinQueryWindow( hWnd, QW_PARENT ) ; /* temporary assignment.. */
                    242:             hSysMenu = WinWindowFromID( hApp, FID_SYSMENU ) ;
                    243:                 // setup semaphores
                    244: //            DosCreateEventSem( NULL, &semDrawDone, 0L, 0L ) ;
                    245: //            DosCreateEventSem( NULL, &semStartSeq, 0L, 0L ) ;
                    246:             DosCreateEventSem( NULL, &semPause, 0L, 0L ) ;
                    247:             DosCreateMutexSem( NULL, &semHpsAccess, 0L, 1L ) ;
                    248:             bExist = TRUE ;
                    249:                 // create a dc and hps to draw on the screen
                    250:             hdcScreen = WinOpenWindowDC( hWnd ) ;
                    251:             sizlPage.cx = 0 ; sizlPage.cy = 0 ;
                    252:             sizlPage.cx = 19500 ; sizlPage.cy = 12500 ;
                    253:             hpsScreen = GpiCreatePS( hab, hdcScreen, &sizlPage,
                    254:                            PU_HIMETRIC|GPIT_NORMAL|GPIA_ASSOC) ;
                    255:                 // spawn server for GNUPLOT ...
                    256:             tidSpawn = _beginthread( ReadGnu, NULL, 32768, NULL ) ;
                    257:             }
                    258:             break ;
                    259:
                    260:         case WM_GPSTART:
                    261:
                    262:                 // get details of command-line window
                    263:             hSwitch = WinQuerySwitchHandle( 0, ppidGnu ) ;
                    264:             WinQuerySwitchEntry( hSwitch, &swGnu ) ;
                    265:             if( firstcall ) {
                    266:                 // set size of this window
                    267:             WinSetWindowPos( WinQueryWindow( hWnd, QW_PARENT ),
                    268:                              bPopFront?HWND_TOP:swGnu.hwnd,
                    269:                              ulShellPos[0],
                    270:                              ulShellPos[1],
                    271:                              ulShellPos[2],
                    272:                              ulShellPos[3],
                    273:                              bShellPos?(bPopFront?SWP_SIZE|SWP_MOVE|SWP_SHOW|SWP_ACTIVATE
                    274:                                                  :SWP_SIZE|SWP_MOVE|SWP_SHOW|SWP_ZORDER)
                    275:                                       :(bPopFront?SWP_SHOW|SWP_ACTIVATE:SWP_SHOW|SWP_ZORDER) ) ;
                    276:             signal( SIGTERM, SigHandler ) ;
                    277:                 firstcall = 0 ;
                    278:                 }
                    279:             if( !bPopFront ) WinSwitchToProgram( hSwitch ) ;
                    280: //            DosPostEventSem( semDrawDone ) ;
                    281:             DosReleaseMutexSem( semHpsAccess ) ;
                    282:             return 0 ;
                    283:
                    284:         case WM_COMMAND:
                    285:
                    286:             return WmClientCmdProc( hWnd , message , mp1 , mp2 ) ;
                    287:
                    288:         case WM_CHAR:
                    289:                     /* If the user types a command in the driver window,
                    290:                        we route it to the gnuplot window and switch that
                    291:                        to the front. Doesn't work for full-screen
                    292:                        sessions, though (but does switch).  */
                    293:             {
                    294:             USHORT  usFlag ;
                    295:             usFlag = SHORT1FROMMP( mp1 ) ;
                    296:             if(  !(usFlag & (KC_KEYUP|KC_ALT|KC_CTRL)) ) {
                    297:                 USHORT uc = SHORT1FROMMP( mp2 ) ;
                    298:                     HWND hw = WinQueryWindow( swGnu.hwnd, QW_BOTTOM ) ;
                    299:                     WinSetFocus( HWND_DESKTOP, hw ) ;
                    300:                 WinSendMsg( hw, message,
                    301:                             MPFROM2SHORT((USHORT)(KC_SCANCODE), 1),
                    302:                             MPFROMSHORT(uc) ) ;
                    303:                     WinSwitchToProgram( hSwitch ) ;
                    304:                     }
                    305:             }
                    306:             break ;
                    307:
                    308:         case WM_DESTROY:
                    309:
                    310:             if( WinSendMsg( hWnd, WM_USER_PRINT_QBUSY, 0L, 0L ) != 0L ) {
                    311:                 WinMessageBox( HWND_DESKTOP,
                    312:                                hWnd,
                    313:                                "Still printing - not closed",
                    314:                                APP_NAME,
                    315:                                0,
                    316:                                MB_OK | MB_ICONEXCLAMATION ) ;
                    317:                 return 0L ;
                    318:                 }
                    319:            return (WinDefWindowProc(hWnd, message, mp1, mp2));
                    320:
                    321:         case WM_PAINT:
                    322:             {
                    323:             ULONG ulCount ;
                    324:             PID pid; TID tid;
                    325:             HPS hps_tmp;
                    326:             RECTL rectl_tmp;
                    327:               DosQueryMutexSem( semHpsAccess, &pid, &tid, &ulCount ) ;
                    328:             if (( ulCount > 0 ) && (tid != tidDraw)) {
                    329:                 /* simple repaint while building plot or metafile */
                    330:                 /* use temporary PS                   */
                    331:               hps_tmp = WinBeginPaint(hWnd,0,&rectl_tmp );
                    332:               WinFillRect(hps_tmp,&rectl_tmp,CLR_BACKGROUND);
                    333:               WinEndPaint(hps_tmp);
                    334:                 /* add dirty rectangle to saved rectangle     */
                    335:                 /* to be repainted when PS is available again */
                    336:               WinUnionRect(hab,&rectlPaint,&rectl_tmp,&rectlPaint);
                    337:                 iPaintCount ++ ;
                    338:                 break ;
                    339:                 }
                    340:             WinInvalidateRect( hWnd, &rectlPaint, TRUE ) ;
                    341:             DoPaint( hWnd, hpsScreen ) ;
                    342:             WinSetRectEmpty( hab, &rectlPaint ) ;
                    343:             }
                    344:             break ;
                    345:
                    346:         case WM_SIZE :
                    347:
                    348:             {
                    349:             WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    350:             }
                    351:             break ;
                    352:
                    353:         case WM_PRESPARAMCHANGED:
                    354:             {
                    355:             char *pp ;
                    356:             ULONG ulID ;
                    357:             pp = malloc(FONTBUF) ;
                    358:             if( WinQueryPresParam( hWnd,
                    359:                                    PP_FONTNAMESIZE,
                    360:                                    0,
                    361:                                    &ulID,
                    362:                                    FONTBUF,
                    363:                                    pp,
                    364:                                    QPF_NOINHERIT ) != 0L ) {
                    365:                 strcpy( szFontNameSize, pp ) ;
                    366:                 bNewFont = TRUE ;
                    367:                 WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    368:                 }
                    369:             free(pp) ;
                    370:             }
                    371:             break ;
                    372:
                    373:         case WM_USER_PRINT_BEGIN:
                    374:         case WM_USER_PRINT_OK :
                    375:         case WM_USER_DEV_ERROR :
                    376:         case WM_USER_PRINT_ERROR :
                    377:         case WM_USER_PRINT_QBUSY :
                    378:
                    379:             return( PrintCmdProc( hWnd, message, mp1, mp2 ) ) ;
                    380:
                    381:         case WM_GNUPLOT:
                    382:                 // display the plot
                    383:             if( bPopFront )
                    384:                 WinSetWindowPos( hwndFrame, HWND_TOP, 0,0,0,0, SWP_ACTIVATE|SWP_ZORDER ) ;
                    385:             if( iPaintCount > 0 ) { /* if outstanding paint messages, repaint */
                    386:                 WinInvalidateRect( hWnd, &rectlPaint, TRUE ) ;
                    387:                 iPaintCount = 0 ;
                    388:                 }
                    389:             return 0L ;
                    390:
                    391:         case WM_PAUSEPLOT:
                    392:                 /* put pause message on screen, or enable 'continue' button */
                    393:             if( ulPauseMode == PAUSE_DLG ) {
                    394:                 pausedata.pszMessage = (char*)mp1 ;
                    395:                 WinLoadDlg( HWND_DESKTOP,
                    396:                             hWnd,
                    397:                             (PFNWP)PauseMsgDlgProc,
                    398:                             0L,
                    399:                             IDD_PAUSEBOX,
                    400:                             &pausedata ) ;
                    401:                 }
                    402:             else {
                    403:                 WinEnableMenuItem( WinWindowFromID(
                    404:                                    WinQueryWindow( hWnd, QW_PARENT ), FID_MENU ),
                    405:                                    IDM_CONTINUE,
                    406:                                    TRUE ) ;
                    407:                 }
                    408:             return 0L ;
                    409:
                    410:         case WM_PAUSEEND:
                    411:             /* resume plotting */
                    412:             ulPauseReply = (ULONG) mp1 ;
                    413:             DosPostEventSem( semPause ) ;
                    414:             return 0L ;
                    415:
                    416:        default:         /* Passes it on if unproccessed    */
                    417:            return (WinDefWindowProc(hWnd, message, mp1, mp2));
                    418:     }
                    419:     return (NULL);
                    420: }
                    421:
                    422: MRESULT WmClientCmdProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
                    423: /*
                    424: **   Handle client window command (menu) messages
                    425: */
                    426:     {
                    427:     extern HWND hApp ;
                    428:     static ulPauseItem = IDM_PAUSEDLG ;
                    429:
                    430:     switch( (USHORT) SHORT1FROMMP( mp1 ) ) {
                    431:
                    432:         case IDM_ABOUT :    /* show the 'About' box */
                    433:
                    434:             WinDlgBox( HWND_DESKTOP,
                    435:                        hWnd ,
                    436:                        (PFNWP)About ,
                    437:                        0L,
                    438:                        ID_ABOUT,
                    439:                        NULL ) ;
                    440:             break ;
                    441:
                    442:
                    443:         case IDM_GPLOTINF:  /* view gnuplot.inf */
                    444:             {
                    445:             char path[256] ;
                    446:             char *p ;
                    447:             strcpy( path, "start view " ) ;
                    448:             if( (p=getenv("GNUPLOT")) != NULL ) {
                    449:                 strcat( path, p ) ;
                    450:                 strcat( path, "/" ) ;
                    451:                 }
                    452:             strcat( path, "gnuplot" ) ;
                    453:             system( path ) ;
                    454:             }
                    455:             break ;
                    456:
                    457:         case IDM_PRINT :    /* print plot */
                    458:
                    459:             if( SetupPrinter( hWnd, &qPrintData ) ) {
                    460:                             WinPostMsg( hWnd,
                    461:                             WM_USER_PRINT_BEGIN,
                    462:                             (MPARAM) &qPrintData,
                    463:                             (MPARAM) hpsScreen ) ;
                    464:                             }
                    465:             break ;
                    466:
                    467:         case IDM_PRINTSETUP :    /* select printer */
                    468:
                    469:             WinDlgBox( HWND_DESKTOP,
                    470:                        hWnd ,
                    471:                        (PFNWP)QPrintersDlgProc,
                    472:                        0L,
                    473:                        IDD_QUERYPRINT,
                    474:                        qPrintData.szPrinterName ) ;
                    475:             break ;
                    476:
                    477:         case IDM_LINES_THICK:
                    478:                 // change line setting
                    479:             bWideLines = !bWideLines ;
                    480:             ChangeCheck( hWnd, IDM_LINES_THICK, bWideLines?IDM_LINES_THICK:0 ) ;
                    481:             WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    482:             break ;
                    483:
                    484:         case IDM_LINES_SOLID:
                    485:                 // change line setting
                    486:             bLineTypes = !bLineTypes ;
                    487:             ChangeCheck( hWnd, IDM_LINES_SOLID, bLineTypes?0:IDM_LINES_SOLID ) ;
                    488:             EditLineTypes( hWnd, hpsScreen, bLineTypes ) ;
                    489:             WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    490:             break ;
                    491:
                    492:         case IDM_COLOURS:
                    493:                 // change colour setting
                    494:             bColours = !bColours ;
                    495:             ChangeCheck( hWnd, IDM_COLOURS, bColours?IDM_COLOURS:0 ) ;
                    496:             WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    497:             break ;
                    498:
                    499:         case IDM_FRONT:
                    500:                 /* toggle z-order forcing */
                    501:             bPopFront = !bPopFront ;
                    502:             ChangeCheck( hWnd, IDM_FRONT, bPopFront?IDM_FRONT:0 ) ;
                    503:             break ;
                    504:
                    505:         case IDM_FONTS:
                    506:
                    507:             if( GetNewFont( hWnd, hpsScreen ) ) {
                    508:                 bNewFont = TRUE ;
                    509:                 WinInvalidateRect( hWnd, NULL, TRUE ) ;
                    510:                 }
                    511:             break ;
                    512:
                    513:         case IDM_SAVE :
                    514:             SaveIni( hWnd ) ;
                    515:             break ;
                    516:
                    517:         case IDM_COPY :         /* copy to clipboard */
                    518:             if( WinOpenClipbrd( hab ) ) {
                    519:                 CopyToClipBrd( hWnd ) ;
                    520:                 }
                    521:             else {
                    522:                 WinMessageBox( HWND_DESKTOP,
                    523:                                hWnd,
                    524:                                "Can't open clipboard",
                    525:                                APP_NAME,
                    526:                                0,
                    527:                                MB_OK | MB_ICONEXCLAMATION ) ;
                    528:                 }
                    529:             break ;
                    530:
                    531:         case IDM_CLEARCLIP :         /* clear clipboard */
                    532:             if( WinOpenClipbrd( hab ) ) {
                    533:                 WinEmptyClipbrd( hab ) ;
                    534:                 WinCloseClipbrd( hab ) ;
                    535:                 }
                    536:             else {
                    537:                 WinMessageBox( HWND_DESKTOP,
                    538:                                hWnd,
                    539:                                "Can't open clipboard",
                    540:                                APP_NAME,
                    541:                                0,
                    542:                                MB_OK | MB_ICONEXCLAMATION ) ;
                    543:                 }
                    544:             break ;
                    545:
                    546:         case IDM_COMMAND:       /* go back to GNUPLOT command window */
                    547:             WinSwitchToProgram( hSwitch ) ;
                    548:             break ;
                    549:
                    550:         case IDM_CONTINUE:
                    551:             WinPostMsg( hWnd, WM_PAUSEEND, (MPARAM)1L, (MPARAM)0L ) ;
                    552:             WinEnableMenuItem( WinWindowFromID(
                    553:                                WinQueryWindow( hWnd, QW_PARENT ), FID_MENU ),
                    554:                                IDM_CONTINUE,
                    555:                                FALSE ) ;
                    556:             break ;
                    557:
                    558:         case IDM_PAUSEGNU:  /* gnuplot handles pause */
                    559:             ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEGNU ) ;
                    560:             ulPauseItem = IDM_PAUSEGNU ;
                    561:             ulPauseMode = PAUSE_GNU ;
                    562:             break ;
                    563:
                    564:         case IDM_PAUSEDLG:  /* pause message in dlg box */
                    565:             ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEDLG ) ;
                    566:             ulPauseItem = IDM_PAUSEDLG ;
                    567:             ulPauseMode = PAUSE_DLG ;
                    568:             break ;
                    569:
                    570:         case IDM_PAUSEBTN:  /* pause uses menu button, no message */
                    571:             ChangeCheck( hWnd, ulPauseItem, IDM_PAUSEBTN ) ;
                    572:             ulPauseItem = IDM_PAUSEBTN ;
                    573:             ulPauseMode = PAUSE_BTN ;
                    574:             break ;
                    575:
                    576:         case IDM_HELPFORHELP:
                    577:             WinSendMsg(WinQueryHelpInstance(hWnd),
                    578:                        HM_DISPLAY_HELP, 0L, 0L ) ;
                    579:             return 0L ;
                    580:
                    581:         case IDM_EXTENDEDHELP:
                    582:             WinSendMsg(WinQueryHelpInstance(hWnd),
                    583:                         HM_EXT_HELP, 0L, 0L);
                    584:             return 0L ;
                    585:
                    586:         case IDM_KEYSHELP:
                    587:             WinSendMsg(WinQueryHelpInstance(hWnd),
                    588:                        HM_KEYS_HELP, 0L, 0L);
                    589:             return 0L ;
                    590:
                    591:         case IDM_HELPINDEX:
                    592:             WinSendMsg(WinQueryHelpInstance(hWnd),
                    593:                        HM_HELP_INDEX, 0L, 0L);
                    594:             return 0L ;
                    595:
                    596:         default :
                    597:
                    598:             return WinDefWindowProc( hWnd, message, mp1, mp2 ) ;
                    599:
                    600:         }
                    601:     return( NULL ) ;
                    602:     }
                    603:
                    604: void ChangeCheck( HWND hWnd , USHORT wItem1 , USHORT wItem2 )
                    605: /*
                    606: **  Utility function:
                    607: **
                    608: **  move check mark from menu item 1 to item 2
                    609: */
                    610:     {
                    611:     HWND hMenu ;
                    612:
                    613:     hMenu = WinWindowFromID( WinQueryWindow( hWnd, QW_PARENT ),
                    614:                              FID_MENU ) ;
                    615:     if( wItem1 != 0 )
                    616:         WinSendMsg( hMenu,
                    617:                     MM_SETITEMATTR,
                    618:                     MPFROM2SHORT( wItem1, TRUE ),
                    619:                     MPFROM2SHORT( MIA_CHECKED, 0 ) ) ;
                    620:     if( wItem2 != 0 )
                    621:         WinSendMsg( hMenu,
                    622:                     MM_SETITEMATTR,
                    623:                     MPFROM2SHORT( wItem2, TRUE ),
                    624:                     MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED ) ) ;
                    625:     }
                    626:
                    627: static void CopyToClipBrd( HWND hWnd )
                    628: /*
                    629: **  Copy window to clipboard as bitmap.
                    630: */
                    631:     {
                    632:     HAB hab ;
                    633:     HBITMAP hbm ;
                    634:     HMF     hmf ;
                    635:
                    636:     hab = WinQueryAnchorBlock( hWnd ) ;
                    637:     WinEmptyClipbrd( hab ) ;
                    638:     hbm = CopyToBitmap( hpsScreen ) ;
                    639:     WinSetClipbrdData( hab, (ULONG) hbm, CF_BITMAP, CFI_HANDLE) ;
                    640:     hmf = CopyToMetaFile( hpsScreen ) ;
                    641:     WinSetClipbrdData( hab, (ULONG) hmf, CF_METAFILE, CFI_HANDLE) ;
                    642:     WinCloseClipbrd( hab ) ;
                    643:     }
                    644:
                    645: HBITMAP CopyToBitmap( HPS hps )
                    646: /*
                    647: **  Copy ps to a bitmap.
                    648: */
                    649:     {
                    650:     HPS     hpsMem ;
                    651:     HWND    hwnd ;
                    652:     HAB     hab ;
                    653:     PSZ     psz[4] = {NULL,"Display",NULL,NULL} ;
                    654:     HDC     hdcMem, hdcScr ;
                    655:     SIZEL   sizel ;
                    656:     BITMAPINFOHEADER2 bmp ;
                    657:     PBITMAPINFO2 pbmi ;
                    658:     HBITMAP hbm ;
                    659:     BYTE    abBmp[80] ;
                    660:     LONG    alData[2] ;
                    661:     RECTL   rectl ;
                    662:     POINTL  aptl[6] ;
                    663:     HMF     hmf ;
                    664:
                    665:     hdcScr = GpiQueryDevice( hps ) ;
                    666:     hwnd = WinWindowFromDC( hdcScr ) ;
                    667:     hab = WinQueryAnchorBlock( hwnd ) ;
                    668:     hdcMem = DevOpenDC( hab,
                    669:                         OD_MEMORY,
                    670:                         "*",
                    671:                         4L,
                    672:                         (PDEVOPENDATA) psz,
                    673:                         hdcScr ) ;
                    674:     sizel.cx = 0/*GNUPAGE*/ ; sizel.cy = 0/*GNUPAGE*/ ;
                    675:     hpsMem = GpiCreatePS( hab, hdcMem, &sizel, PU_PELS|GPIA_ASSOC|GPIT_MICRO ) ;
                    676:     GpiQueryDeviceBitmapFormats( hpsMem, 2L, alData ) ;
                    677:     WinQueryWindowRect( hwnd, &rectl ) ;
                    678:     memset( &bmp, 0, sizeof(bmp) ) ;
                    679:     bmp.cbFix = (ULONG) sizeof( bmp ) ;
                    680:     bmp.cx = (SHORT) (rectl.xRight-rectl.xLeft) ;
                    681:     bmp.cy = (SHORT) (rectl.yTop-rectl.yBottom) ;
                    682:     bmp.cPlanes = alData[0] ;
                    683:     bmp.cBitCount = alData[1] ;
                    684:     hbm = GpiCreateBitmap( hpsMem, &bmp, 0, NULL, NULL ) ;
                    685:     GpiSetBitmap( hpsMem, hbm ) ;
                    686:     aptl[0].x = 0 ; aptl[0].y = 0 ;
                    687:     aptl[1].x = (LONG)bmp.cx ; aptl[1].y = (LONG)bmp.cy ;
                    688:     aptl[2].x = 0 ; aptl[2].y = 0 ;
                    689:     GpiBitBlt( hpsMem, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE ) ;
                    690:     GpiDestroyPS( hpsMem ) ;
                    691:     DevCloseDC( hdcMem ) ;
                    692:     return hbm ;
                    693:     }
                    694:
                    695: HMF CopyToMetaFile( HPS hps )
                    696: /*
                    697: **  Copy ps to a mteafile.
                    698: */
                    699:     {
                    700:     HDC hdcMF, hdcOld ;
                    701:     HAB hab ;
                    702:     HWND hwnd ;
                    703:     PSZ psz[4] = {NULL,"Display",NULL,NULL} ;
                    704:     HMF hmf ;
                    705:     hdcOld = GpiQueryDevice( hps ) ;
                    706:     hwnd = WinWindowFromDC( hdcOld ) ;
                    707:     hab = WinQueryAnchorBlock( hwnd ) ;
                    708:     hdcMF = DevOpenDC( hab, OD_METAFILE, "*", 4L, psz, hdcOld ) ;
                    709:     DosRequestMutexSem( semHpsAccess, (ULONG) SEM_INDEFINITE_WAIT ) ;
                    710:     GpiSetDrawingMode( hps, DM_DRAW ) ;
                    711:     GpiAssociate( hps, 0 ) ;
                    712:     GpiAssociate( hps, hdcMF ) ;
                    713:     ScalePS( hps ) ;
                    714:     GpiDrawChain( hps ) ;
                    715:     GpiAssociate( hps, 0 ) ;
                    716:     GpiAssociate( hps, hdcOld ) ;
                    717:     DosReleaseMutexSem( semHpsAccess ) ;
                    718:     hmf = DevCloseDC( hdcMF ) ;
                    719:     return hmf ;
                    720:     }
                    721:
                    722: BOOL QueryIni( HAB hab )
                    723: /*
                    724: ** Query INI file
                    725: */
                    726:     {
                    727:     BOOL         bPos, bData, bSwp  ;
                    728:     ULONG        ulOpts[5] ;
                    729:     HINI         hini ;
                    730:     ULONG        ulCB ;
                    731:     char         *p ;
                    732:     static SWP   pauseswp ;
                    733:
                    734:             // read gnuplot ini file
                    735:
                    736:     hini = PrfOpenProfile( hab, szIniFile ) ;
                    737:     ulCB = sizeof( ulShellPos ) ;
                    738:     bPos = PrfQueryProfileData( hini, APP_NAME, INISHELLPOS, &ulShellPos, &ulCB ) ;
                    739:     ulCB = sizeof( SWP ) ;
                    740:     bSwp = PrfQueryProfileData( hini, APP_NAME, INIPAUSEPOS, &pauseswp, &ulCB ) ;
                    741:     if( bSwp ) pausedata.pswp = &pauseswp ;
                    742:     ulCB = sizeof( ulOpts ) ;
                    743:     bData = PrfQueryProfileData( hini, APP_NAME, INIOPTS, &ulOpts, &ulCB ) ;
                    744:     if( bData ) {
                    745:         bLineTypes = (BOOL)ulOpts[0] ;
                    746:         bWideLines = (BOOL)ulOpts[1] ;
                    747:         bColours = (BOOL)ulOpts[2] ;
                    748:         ulPauseMode = ulOpts[3] ;
                    749:         bPopFront = (BOOL)ulOpts[4] ;
                    750:         }
                    751:     else {
                    752:         bLineTypes = FALSE ;  /* default values */
                    753:      /*   bWideLines = FALSE ; */
                    754:         bColours = TRUE ;
                    755:         bPopFront = TRUE ;
                    756:         ulPauseMode = 1 ;
                    757:         }
                    758:     ulCB = 4*sizeof(float) ;
                    759:     PrfQueryProfileData( hini, APP_NAME, INIFRAC, &qPrintData.xsize, &ulCB ) ;
                    760:     if( PrfQueryProfileSize( hini, APP_NAME, INIPRDRIV, &ulCB ) ) {
                    761:         PDRIVDATA pdriv = (PDRIVDATA) malloc( ulCB ) ;
                    762:         if( pdriv != NULL ) {
                    763:             PrfQueryProfileData( hini, APP_NAME, INIPRDRIV, pdriv, &ulCB ) ;
                    764:             qPrintData.pdriv = pdriv ;
                    765:             qPrintData.cbpdriv = ulCB ;
                    766:             }
                    767:         }
                    768:     PrfQueryProfileString( hini, APP_NAME, INIPRPR, "",
                    769:                            qPrintData.szPrinterName,
                    770:                            (long) sizeof qPrintData.szPrinterName ) ;
                    771:     PrfQueryProfileString( hini, APP_NAME, INIFONT, INITIAL_FONT,
                    772:                              szFontNameSize, FONTBUF ) ;
                    773:     ulCB = sizeof( ulOpts ) ;
                    774:     bData = PrfQueryProfileData( hini, APP_NAME, INICHAR, &ulOpts, &ulCB ) ;
                    775:     if( bData ) {
                    776:         lCharWidth = ulOpts[0] ;
                    777:         lCharHeight = ulOpts[1] ;
                    778:         }
                    779:     else {
                    780:         lCharWidth = 217 ;
                    781:         lCharHeight = 465 ;
                    782:         }
                    783:     PrfCloseProfile( hini ) ;
                    784:
                    785:     if( qPrintData.szPrinterName[0] == '\0' ) {
                    786:             // get default printer name
                    787:         PrfQueryProfileString( HINI_PROFILE,
                    788:                                "PM_SPOOLER",
                    789:                                "PRINTER",
                    790:                                ";",
                    791:                                qPrintData.szPrinterName,
                    792:                                (long) sizeof qPrintData.szPrinterName ) ;
                    793:         if( (p=strchr( qPrintData.szPrinterName, ';' )) != NULL ) *p = '\0' ;
                    794:         }
                    795:     bShellPos = bPos ;
                    796:     return bPos ;
                    797:     }
                    798:
                    799: static void SaveIni( HWND hWnd )
                    800: /*
                    801: ** save data in ini file
                    802: */
                    803:     {
                    804:     SWP     swp ;
                    805:     HINI    hini ;
                    806:     ULONG   ulOpts[5] ;
                    807:     HFILE   hfile ;
                    808:     ULONG   ulAct ;
                    809:     ERRORID errid ;
                    810:     char    achErr[64] ;
                    811:     HAB     hab ;
                    812:
                    813:     hab = WinQueryAnchorBlock( hWnd ) ;
                    814:     hini = PrfOpenProfile( hab, szIniFile ) ;
                    815:     if( hini != NULLHANDLE ) {
                    816:         WinQueryWindowPos( hwndFrame, &swp ) ;
                    817:         ulPlotPos[0] = swp.x ;
                    818:         ulPlotPos[1] = swp.y ;
                    819:         ulPlotPos[2] = swp.cx ;
                    820:         ulPlotPos[3] = swp.cy ;
                    821:         PrfWriteProfileData( hini, APP_NAME, INISHELLPOS, &ulPlotPos, sizeof(ulPlotPos) ) ;
                    822:         if( pausedata.pswp != NULL )
                    823:             PrfWriteProfileData( hini, APP_NAME, INIPAUSEPOS,
                    824:                                  pausedata.pswp, sizeof(SWP) ) ;
                    825:         ulOpts[0] = (ULONG)bLineTypes ;
                    826:         ulOpts[1] = (ULONG)bWideLines ;
                    827:         ulOpts[2] = (ULONG)bColours ;
                    828:         ulOpts[3] = ulPauseMode ;
                    829:         ulOpts[4] = (ULONG)bPopFront ;
                    830:         PrfWriteProfileData( hini, APP_NAME, INIOPTS, &ulOpts, sizeof(ulOpts) ) ;
                    831:         PrfWriteProfileData( hini, APP_NAME, INIFRAC, &qPrintData.xsize, 4*sizeof(float) ) ;
                    832:         if( qPrintData.pdriv != NULL )
                    833:             PrfWriteProfileData( hini, APP_NAME, INIPRDRIV, qPrintData.pdriv,
                    834:                                  qPrintData.cbpdriv ) ;
                    835:         PrfWriteProfileString( hini, APP_NAME, INIPRPR,
                    836:                                qPrintData.szPrinterName[0] == '\0'? NULL:
                    837:                                qPrintData.szPrinterName ) ;
                    838:         PrfWriteProfileString( hini, APP_NAME, INIFONT, szFontNameSize ) ;
                    839:         ulOpts[0] = (ULONG)lCharWidth ;
                    840:         ulOpts[1] = (ULONG)lCharHeight ;
                    841:         PrfWriteProfileData( hini, APP_NAME, INICHAR, &ulOpts, sizeof(ulOpts) ) ;
                    842:         PrfCloseProfile( hini ) ;
                    843:         }
                    844:     else {
                    845:         WinMessageBox( HWND_DESKTOP,
                    846:                        HWND_DESKTOP,
                    847:                        "Can't write ini file",
                    848:                        APP_NAME,
                    849:                        0,
                    850:                        MB_OK | MB_ICONEXCLAMATION ) ;
                    851:         }
                    852:     }
                    853:
                    854: static void DoPaint( HWND hWnd, HPS hps  )
                    855: /*
                    856: **  Paint the screen with current data
                    857: */
                    858:     {
                    859:     ULONG ulCount ;
                    860:
                    861:     static RECTL rectl ;
                    862:     if( tidDraw != 0 ) {
                    863:             /* already drawing - stop it; include the rectl now
                    864:                being drawn in, in the update region; and return
                    865:                without calling beginpaint so that the paint
                    866:                message is resent */
                    867:         GpiSetStopDraw( hpsScreen, SDW_ON ) ;
                    868:         DosSleep(1) ;
                    869:         WinInvalidateRect( hWnd, &rectl, TRUE ) ;
                    870:         return ;
                    871:         }
                    872:             /* winbeginpaint here, so paint message is
                    873:                not resent when we return, then spawn a
                    874:                thread to do the drawing */
                    875:     WinBeginPaint( hWnd, hps, &rectl ) ;                 //rl
                    876:     tidDraw = _beginthread( ThreadDraw, NULL, 32768, NULL ) ;
                    877:     }
                    878:
                    879: static void ThreadDraw( void* arg )
                    880: /*
                    881: **  Thread to draw plot on screen
                    882: */
                    883:     {
                    884:     HAB     hab ;
                    885:
                    886:     hab = WinInitialize( 0 ) ;
                    887:
                    888:     InitScreenPS() ;
                    889:
                    890:     DosRequestMutexSem( semHpsAccess, (ULONG) SEM_INDEFINITE_WAIT ) ;
                    891:     ScalePS( hpsScreen ) ;
                    892:     GpiSetStopDraw( hpsScreen, SDW_OFF ) ;
                    893:     GpiSetDrawingMode( hpsScreen, DM_DRAW ) ;
                    894:     GpiDrawChain( hpsScreen ) ;
                    895:     WinEndPaint( hpsScreen ) ;
                    896:     DosReleaseMutexSem( semHpsAccess ) ;
                    897:     WinTerminate( hab ) ;
                    898:     tidDraw = 0 ;
                    899:     }
                    900:
                    901: HPS InitScreenPS()
                    902: /*
                    903: ** Initialise the screen ps for drawing
                    904: */
                    905:     {
                    906:     RECTL   rectClient ;
                    907:     int     nColour = 0 ;
                    908:
                    909:     GpiResetPS( hpsScreen, GRES_ATTRS ) ;
                    910:     GpiErase(hpsScreen);
                    911:
                    912:     WinQueryWindowRect( hApp, (PRECTL)&rectClient ) ;
                    913:     {
                    914:     double ratio = 1.560 ;
                    915:     double xs = rectClient.xRight - rectClient.xLeft ;
                    916:     double ys = rectClient.yTop - rectClient.yBottom ;
                    917:     if( ys > xs/ratio ) { /* reduce ys to fit */
                    918:         rectClient.yTop = rectClient.yBottom + (int)(xs/ratio) ;
                    919:         }
                    920:     else if( ys < xs/ratio ) { /* reduce xs to fit */
                    921:         rectClient.xRight = rectClient.xLeft + (int)(ys*ratio) ;
                    922:         }
                    923:     }
                    924:
                    925:     GpiSetPageViewport( hpsScreen, &rectClient ) ;
                    926:     if( !bColours ) {
                    927:         int i ;
                    928:         for( i=0; i<8; i++ ) alColourTable[i] = 0 ;
                    929:         for( i=8; i<16; i++ ) alColourTable[i] = 0 ;
                    930:         alColourTable[0] = 0xFFFFFF ;
                    931:         nColour = 16 ;
                    932:         }
                    933:     GpiCreateLogColorTable( hpsScreen,
                    934:                             LCOL_RESET,
                    935:                             LCOLF_CONSECRGB,
                    936:                             0, nColour, alColourTable ) ;
                    937:     return hpsScreen ;
                    938:     }
                    939:
                    940: enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
                    941:
                    942:
                    943: short ScalePS( HPS hps )
                    944: /*
                    945: **  Get a font to use
                    946: **  Scale the plot area to world coords for subsequent plotting
                    947: */
                    948:     {
                    949:     RECTL rectView ;
                    950:
                    951:     SelectFont( hps, szFontNameSize ) ;
                    952:     return 0 ;
                    953:     }
                    954:
                    955: static SIZEF sizBaseSubSup ;
                    956: static SIZEF sizCurSubSup ;
                    957: static SIZEF sizCurFont ;
                    958: static long lVOffset = 0 ;
                    959: static SIZEF sizBaseFont ;
                    960: static struct _ft {
                    961:     char *name ;
                    962:     LONG  lcid ;
                    963:     } tabFont[256] = {{NULL,0L}, {NULL}};
                    964:
                    965: void SelectFont( HPS hps, char *szFontNameSize )
                    966: /*
                    967: **  Select a named and sized outline (adobe) font
                    968: */
                    969:     {
                    970:      HDC    hdc ;
                    971:      FATTRS  fat ;
                    972:      LONG   xDeviceRes, yDeviceRes ;
                    973:      POINTL ptlFont ;
                    974:      SIZEF  sizfx ;
                    975:      static LONG lcid = 0L ;
                    976:      static char *szFontName ;
                    977:      static short shPointSize ;
                    978:
                    979:      sscanf( szFontNameSize, "%hd", &shPointSize ) ;
                    980:      szFontName = strchr( szFontNameSize, '.' ) + 1 ;
                    981:
                    982:      fat.usRecordLength  = sizeof fat ;
                    983:      fat.fsSelection     = 0 ;
                    984:      fat.lMatch          = 0 ;
                    985:      fat.idRegistry      = 0 ;
                    986:      fat.usCodePage      = 0 ; //GpiQueryCp (hps) ;
                    987:      fat.lMaxBaselineExt = 0 ;
                    988:      fat.lAveCharWidth   = 0 ;
                    989:      fat.fsType          = 0 ;
                    990:      fat.fsFontUse       = FATTR_FONTUSE_OUTLINE |
                    991:                            FATTR_FONTUSE_TRANSFORMABLE ;
                    992:
                    993:      strcpy (fat.szFacename, szFontName) ;
                    994:
                    995:      if(tabFont[0].name !=NULL) free( tabFont[0].name ) ;
                    996:      tabFont[0].name = strdup( szFontName ) ;
                    997:      tabFont[0].lcid = 10L ;
                    998:
                    999:      lcid = GpiQueryCharSet( hps ) ;
                   1000:      if( lcid != 10L ) lcid = 10L ;
                   1001:      else {
                   1002:         GpiSetCharSet( hps, 0L) ;
                   1003:         GpiDeleteSetId( hps, lcid ) ;
                   1004:         }
                   1005:      GpiCreateLogFont (hps, NULL, lcid, &fat) ;
                   1006:      GpiSetCharSet( hps, lcid ) ;
                   1007:
                   1008:      hdc = GpiQueryDevice (hps) ;
                   1009:
                   1010:      DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &xDeviceRes) ;
                   1011:      DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,   1L, &yDeviceRes) ;
                   1012:
                   1013:                          // Find desired font size in pixels
                   1014:
                   1015:      ptlFont.x = 2540L * (long)shPointSize / 72L ;
                   1016:      ptlFont.y = 2540L * (long)shPointSize / 72L ;
                   1017:
                   1018:                          // Set the character box
                   1019:
                   1020:      sizfx.cx = MAKEFIXED (ptlFont.x, 0) ;
                   1021:      sizfx.cy = MAKEFIXED (ptlFont.y, 0) ;
                   1022:      lVOffset = ptlFont.y ;
                   1023:
                   1024:      sizBaseFont = sizfx ;
                   1025:      GpiSetCharBox (hps, &sizfx) ;
                   1026:
                   1027:                         // set up some useful globals
                   1028:      {
                   1029:      FONTMETRICS fm ;
                   1030:      GpiQueryFontMetrics( hps, sizeof(FONTMETRICS), &fm ) ;
                   1031:      lBaseSubOffset = -fm.lSubscriptYOffset ;
                   1032:      lBaseSupOffset = fm.lSuperscriptYOffset ;
                   1033:      lSubOffset = lBaseSubOffset ;
                   1034:      lSupOffset = lBaseSupOffset ;
                   1035:      lCharHeight = fm.lMaxAscender*1.2 ;
                   1036:      lCharWidth  = fm.lAveCharWidth ;
                   1037:      sizBaseSubSup.cx = MAKEFIXED( ptlFont.x*0.7, 0 ) ;
                   1038:      sizBaseSubSup.cy = MAKEFIXED( ptlFont.y*0.7, 0 ) ;
                   1039:      }
                   1040:      sizCurFont = sizBaseFont ;
                   1041:      sizCurSubSup = sizBaseSubSup ;
                   1042:     if( bNewFont ) {
                   1043: //        EditCharCell( hps, &sizfx ) ;
                   1044:         bNewFont = FALSE ;
                   1045:         }
                   1046:     }
                   1047:
                   1048: void SwapFont( HPS hps, char *szFNS )
                   1049: /*
                   1050: **  Select a named and sized outline (adobe) font
                   1051: */
                   1052:     {
                   1053:      HDC    hdc ;
                   1054:      FATTRS  fat ;
                   1055:      LONG   xDeviceRes, yDeviceRes ;
                   1056:      POINTL ptlFont ;
                   1057:      SIZEF  sizfx ;
                   1058:      static LONG lcid = 0L ;
                   1059:      static int itab = 1 ;
                   1060:      static char *szFontName ;
                   1061:      static short shPointSize ;
                   1062:
                   1063:      if( szFNS == NULL ) {    /* restore base font */
                   1064:          sizCurFont = sizBaseFont ;
                   1065:          sizCurSubSup = sizBaseSubSup ;
                   1066:          lSubOffset = lBaseSubOffset ;
                   1067:          lSupOffset = lBaseSupOffset ;
                   1068:          GpiSetCharSet( hps, 10 ) ;
                   1069:          GpiSetCharBox (hps, &sizBaseFont) ;
                   1070:         }
                   1071:      else {
                   1072:         sscanf( szFNS, "%hd", &shPointSize ) ;
                   1073:         szFontName = strchr( szFNS, '.' ) + 1 ;
                   1074:
                   1075:         {
                   1076:             int i ;
                   1077:             lcid = 0 ;
                   1078:             for(i=0;i<itab;i++) {
                   1079:                 if( strcmp( szFontName, tabFont[i].name ) == 0 ) {
                   1080:                     lcid = tabFont[i].lcid ;
                   1081:                     break ;
                   1082:                     }
                   1083:                 }
                   1084:         }
                   1085:         if( lcid == 0 ) {
                   1086:
                   1087:         fat.usRecordLength  = sizeof fat ;
                   1088:         fat.fsSelection     = 0 ;
                   1089:         fat.lMatch          = 0 ;
                   1090:         fat.idRegistry      = 0 ;
                   1091:         fat.usCodePage      = 0 ; //GpiQueryCp (hps) ;
                   1092:         fat.lMaxBaselineExt = 0 ;
                   1093:         fat.lAveCharWidth   = 0 ;
                   1094:         fat.fsType          = 0 ;
                   1095:         fat.fsFontUse       = FATTR_FONTUSE_OUTLINE |
                   1096:                                FATTR_FONTUSE_TRANSFORMABLE ;
                   1097:
                   1098:         strcpy (fat.szFacename, szFontName) ;
                   1099:
                   1100:
                   1101:         tabFont[itab].name = strdup( szFontName ) ;
                   1102:         lcid = itab+10 ;
                   1103:         tabFont[itab].lcid = lcid ;
                   1104:         ++itab ;
                   1105:
                   1106: //        lcid = 11L ;
                   1107:         GpiSetCharSet( hps, 0L) ;
                   1108:         GpiDeleteSetId( hps, lcid ) ;
                   1109:         GpiCreateLogFont (hps, NULL, lcid, &fat) ;
                   1110:         }
                   1111:         GpiSetCharSet( hps, lcid ) ;
                   1112:      hdc = GpiQueryDevice (hps) ;
                   1113:
                   1114:      DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &xDeviceRes) ;
                   1115:      DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,   1L, &yDeviceRes) ;
                   1116:
                   1117:                          // Find desired font size in pixels
                   1118:
                   1119:      ptlFont.x = 2540L * (long)shPointSize / 72L ;
                   1120:      ptlFont.y = 2540L * (long)shPointSize / 72L ;
                   1121:
                   1122:                          // Set the character box
                   1123:
                   1124:      sizCurFont.cx = MAKEFIXED (ptlFont.x, 0) ;
                   1125:      sizCurFont.cy = MAKEFIXED (ptlFont.y, 0) ;
                   1126: //     lVOffset = ptlFont.y ;
                   1127:
                   1128:      GpiSetCharBox (hps, &sizCurFont) ;
                   1129:      sizCurSubSup.cx = MAKEFIXED( ptlFont.x*0.7, 0 ) ;
                   1130:      sizCurSubSup.cy = MAKEFIXED( ptlFont.y*0.7, 0 ) ;
                   1131:
                   1132:                         // set up some useful globals
                   1133:      {
                   1134:      FONTMETRICS fm ;
                   1135:      GpiQueryFontMetrics( hps, sizeof(FONTMETRICS), &fm ) ;
                   1136:      lSubOffset = -fm.lSubscriptYOffset ;
                   1137:      lSupOffset = fm.lSuperscriptYOffset ;
                   1138:      }
                   1139:         }
                   1140:
                   1141:      }
                   1142:
                   1143: static void ReadGnu( void* arg )
                   1144: /*
                   1145: ** Thread to read plot commands from  GNUPLOT pm driver.
                   1146: ** Opens named pipe, then clears semaphore to allow GNUPLOT driver to proceed.
                   1147: ** Reads commands and builds a command list.
                   1148: */
                   1149:     {
                   1150:     HPIPE    hRead = 0L ;
                   1151:     POINTL ptl ;
                   1152:     POINTL aptl[4] ;
                   1153:     long lCurCol ;
                   1154:     long lOldLine = 0 ;
                   1155:     BOOL bBW = FALSE ; /* passed frpm print.c ?? */
                   1156:     BOOL bPath = FALSE ;
                   1157:     BOOL bDots = FALSE ;
                   1158:     char *szEnv ;
                   1159:     char *szFileBuf ;
                   1160:     ULONG rc;
                   1161:     USHORT usErr ;
                   1162:     ULONG cbR ;
                   1163:     USHORT i ;
                   1164:     PID ppid ;
                   1165:     unsigned char buff[2] ;
                   1166:     HEV hev ;
                   1167:     static char *szPauseText = NULL ;
                   1168:     ULONG ulPause ;
                   1169:     char *pszPipeName, *pszSemName ;
                   1170:     LONG  commands[4] ;
                   1171:     HPS hps ;
                   1172:     HAB hab ;
                   1173:     int linewidth = DEFLW ;
                   1174:
                   1175:     hab = WinInitialize( 0 ) ;
                   1176:     DosEnterCritSec() ;
                   1177:     pszPipeName = malloc( 256 ) ;
                   1178:     pszSemName  = malloc( 256 ) ;
                   1179:     DosExitCritSec() ;
                   1180:     strcpy( pszPipeName, "\\pipe\\" ) ;
                   1181:     strcpy( pszSemName, "\\sem32\\" ) ;
                   1182:     strcat( pszPipeName, szIPCName ) ;
                   1183:     strcat( pszSemName, szIPCName ) ;
                   1184:
                   1185:             /* open a named pipe for communication with gnuplot */
                   1186:
                   1187:     rc = DosCreateNPipe( pszPipeName,
                   1188:                          &hRead,
                   1189:                          NP_ACCESS_DUPLEX|NP_NOINHERIT|NP_NOWRITEBEHIND ,
                   1190:                          1|NP_WAIT|NP_READMODE_MESSAGE|NP_TYPE_MESSAGE,
                   1191:                          PIPEBUF,
                   1192:                          PIPEBUF,
                   1193:                          0xFFFFFFFF) ;
                   1194:     hev = 0 ;       /* OK, gnuplot can try to open npipe ... */
                   1195:     DosOpenEventSem( pszSemName, &hev ) ;
                   1196:     DosPostEventSem( hev ) ;
                   1197:
                   1198:
                   1199:
                   1200:         /* attach to gnuplot */
                   1201:
                   1202: server:
                   1203:
                   1204:     if( DosConnectNPipe( hRead ) == 0L ) {
                   1205:
                   1206:         WinPostMsg( hSysMenu,
                   1207:                     MM_SETITEMATTR,
                   1208:                     MPFROM2SHORT(SC_CLOSE, TRUE ),
                   1209:                     MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED) ) ;
                   1210:
                   1211:         /* store graphics commands */
                   1212:         /* use semaphore to prevent problems with drawing while reallocating
                   1213:            the command buffers */
                   1214:
                   1215:         DosRead( hRead, &ppidGnu, 4, &cbR ) ;
                   1216: //        DosPostEventSem( semStartSeq ) ;         /* once we've got pidGnu */
                   1217:         WinPostMsg( hApp, WM_GPSTART, 0, 0 ) ;
                   1218:
                   1219:
                   1220:         hps = hpsScreen ;
                   1221:    InitScreenPS() ;
                   1222:         while (1) {
                   1223:
                   1224:             usErr=BufRead(hRead,buff, 1, &cbR) ;
                   1225:             if( usErr != 0 ) break ;
                   1226:
                   1227:             switch( *buff ) {
                   1228:                 case 'G' :    /* enter graphics mode */
                   1229:                     {
                   1230:                     ULONG ulCount ;
                   1231:
                   1232:                     if( tidDraw != 0 ) {
                   1233:                       /* already drawing - stop it */
                   1234:                         GpiSetStopDraw( hpsScreen, SDW_ON ) ;
                   1235:                         while(tidDraw != 0) DosSleep(1) ;
                   1236:                         }
                   1237:                    /* wait for access to command list and lock it */
                   1238: //                    DosWaitEventSem( semDrawDone, SEM_INDEFINITE_WAIT ) ;
                   1239: //                    DosEnterCritSec() ;
                   1240:                     DosRequestMutexSem( semHpsAccess, (ULONG) SEM_INDEFINITE_WAIT ) ;
                   1241:                     InitScreenPS() ;
                   1242:                     ScalePS( hps ) ;
                   1243: //                    DosResetEventSem( semDrawDone, &ulCount ) ;
                   1244:                     GpiSetDrawingMode( hps, DM_DRAWANDRETAIN ) ;
                   1245:                     for(i=1;i<=iSeg;i++)
                   1246:                         GpiDeleteSegment( hps, i ) ;
                   1247:                     iSeg = 1 ;
                   1248:                     GpiOpenSegment( hps, iSeg ) ;
                   1249: //                    DosExitCritSec() ;
                   1250:                     GpiSetLineEnd( hps, LINEEND_ROUND ) ;
                   1251:                     GpiSetLineWidthGeom( hps, linewidth ) ;
                   1252:                     GpiSetCharBox (hps, &sizBaseFont) ;
                   1253:                     }
                   1254:                     break ;
                   1255:
                   1256:                 case 'Q' :     /* query terminal info */
                   1257:                     DosWrite( hRead, &lCharWidth, sizeof(int), &cbR ) ;
                   1258:                     DosWrite( hRead, &lCharHeight, sizeof(int), &cbR ) ;
                   1259:                     break ;
                   1260:
                   1261:                 case 'E' :     /* leave graphics mode (graph completed) */
                   1262:                     if( bPath ) {
                   1263:                         GpiEndPath( hps ) ;
                   1264:                         GpiStrokePath( hps, 1, 0 ) ;
                   1265:                         bPath = FALSE ;
                   1266:                         }
                   1267:                     GpiCloseSegment( hps ) ;
                   1268: //                    DosPostEventSem( semDrawDone ) ;
                   1269:                     DosReleaseMutexSem( semHpsAccess ) ;
                   1270:                     WinPostMsg( hApp, WM_GNUPLOT, 0L, 0L ) ;
                   1271:                     break ;
                   1272:
                   1273:                 case 'R' :
                   1274:                     /* gnuplot has reset drivers, allow user to kill this */
                   1275:                     WinPostMsg( hSysMenu,
                   1276:                                 MM_SETITEMATTR,
                   1277:                                 MPFROM2SHORT(SC_CLOSE, TRUE ),
                   1278:                                 MPFROM2SHORT(MIA_DISABLED, (USHORT)0 ) ) ;
                   1279:                     /* if we are keeping us on the screen, wait for new connection */
                   1280:                     if( bServer||bPersist ) {
                   1281:                         DosDisConnectNPipe( hRead ) ;
                   1282:                         goto server ;
                   1283:                         }
                   1284:                     break ;
                   1285:
                   1286:                 case 'r' :
                   1287:                     /* resume after multiplot */
                   1288:                     {
                   1289:                     ULONG ulCount ;
                   1290:                     DosRequestMutexSem( semHpsAccess, (ULONG) SEM_INDEFINITE_WAIT ) ;
                   1291: //                    DosWaitEventSem( semDrawDone, SEM_INDEFINITE_WAIT ) ;
                   1292:                     iSeg++ ;
                   1293: //                    DosResetEventSem( semDrawDone, &ulCount ) ;
                   1294:                     GpiSetDrawingMode( hps, DM_DRAWANDRETAIN ) ;
                   1295:                     GpiOpenSegment( hps, iSeg ) ;
                   1296:                     }
                   1297:                     break ;
                   1298:
                   1299:                 case 's' :
                   1300:                     /* suspend after multiplot */
                   1301:                     break ;
                   1302:
                   1303:                 case 'M' :   /* move */
                   1304:                 case 'V' :   /* draw vector */
                   1305:                     if( *buff=='M' ) {
                   1306:                         if( bPath ) {
                   1307:                             GpiEndPath( hps ) ;
                   1308:                             GpiStrokePath( hps, 1, 0 ) ;
                   1309:                             bPath = FALSE ;
                   1310:                             }
                   1311:                         }
                   1312:                     else {
                   1313:                         if( bWideLines/*bWideLines*/ && !bPath ) {
                   1314:                             GpiBeginPath( hps, 1 ) ;
                   1315:                             bPath = TRUE ;
                   1316:                             }
                   1317:                         }
                   1318:                     BufRead(hRead,&ptl.x, 2*sizeof(int), &cbR) ;
                   1319:                     if( (*buff=='V') && bDots ) ptl.x += 5 ;
                   1320:                     else if( (*buff=='M') && bDots ) ptl.x -= 5 ;
                   1321:                     if( *buff == 'M' ) LMove( hps, &ptl ) ;
                   1322:                     else LLine( hps, &ptl ) ;
                   1323:                     break ;
                   1324:
                   1325:                 case 'P' :   /* pause */
                   1326:                     {
                   1327:                     int len ;
                   1328:                     BufRead(hRead,&len, sizeof(int), &cbR) ;
                   1329:                     len = (len+sizeof(int)-1)/sizeof(int) ;
                   1330:                     if( len > 0 ){  /* get pause text */
                   1331:                         DosEnterCritSec() ;
                   1332:                         szPauseText = malloc( len*sizeof(int) ) ;
                   1333:                         DosExitCritSec() ;
                   1334:                         BufRead(hRead,szPauseText, len*sizeof(int), &cbR) ;
                   1335:                         }
                   1336:                     if( ulPauseMode != PAUSE_GNU ) {
                   1337:                              /* pause and wait for semaphore to be cleared */
                   1338:                         DosResetEventSem( semPause, &ulPause ) ;
                   1339:                         WinPostMsg( hApp, WM_PAUSEPLOT, (MPARAM) szPauseText, 0L ) ;
                   1340:                         DosWaitEventSem( semPause, SEM_INDEFINITE_WAIT ) ;
                   1341:                         }
                   1342:                     else { /* gnuplot handles pause */
                   1343:                         ulPauseReply = 2 ;
                   1344:                         }
                   1345:                     DosEnterCritSec() ;
                   1346:                     if( szPauseText != NULL ) free( szPauseText ) ;
                   1347:                     szPauseText = NULL ;
                   1348:                     DosExitCritSec() ;
                   1349:                              /* reply to gnuplot so it can continue */
                   1350:                     DosWrite( hRead, &ulPauseReply, sizeof(int), &cbR ) ;
                   1351:                     }
                   1352:                     break ;
                   1353:
                   1354:                 case 'T' :   /* write text */
                   1355:                         /* read x, y, len */
                   1356:                     if( bPath ) {
                   1357:                         GpiEndPath( hps ) ;
                   1358:                         GpiStrokePath( hps, 1, 0 ) ;
                   1359:                         bPath = FALSE ;
                   1360:                         }
                   1361:                     {
                   1362:                     int x, y, len, sw ;
                   1363:                     char *str ;
                   1364:                     BufRead(hRead,&x, sizeof(int), &cbR) ;
                   1365:                     BufRead(hRead,&y, sizeof(int), &cbR) ;
                   1366:                     BufRead(hRead,&len, sizeof(int), &cbR) ;
                   1367:
                   1368:                     DosEnterCritSec() ;
                   1369:                     len = (len+sizeof(int)-1)/sizeof(int) ;
                   1370:                     if( len == 0 ) len = 1 ; //?? how about read
                   1371:                     str = malloc( len*sizeof(int) ) ;
                   1372:                     *str = '\0' ;
                   1373:                     DosExitCritSec() ;
                   1374:                     BufRead(hRead, str, len*sizeof(int), &cbR) ;
                   1375:                     lCurCol = GpiQueryColor( hps ) ;
                   1376:                     GpiSetColor( hps, CLR_BLACK ) ;
                   1377:                     sw = QueryTextBox( hps, strlen(str), str ) ;
                   1378:                     switch(jmode) {
                   1379:                        case LEFT:   sw = 0;     break;
                   1380:                        case CENTRE: sw = -sw/2; break;
                   1381:                        case RIGHT:  sw = -sw;   break;
                   1382:                         }
                   1383:                     if( bHorz ) {
                   1384:                         ptl.x = (LONG)(x+sw) ; ptl.y = (LONG)(y-lVOffset/4) ;
                   1385:                         }
                   1386:                     else {
                   1387:                         ptl.x = (LONG)x ; ptl.y = (LONG)(y+sw) ;
                   1388:                         }
                   1389:                     if(bEnhanced)
                   1390:                         CharStringAt( hps, ptl.x, ptl.y, strlen( str ) , str ) ;
                   1391:                     else
                   1392:                         GpiCharStringAt( hps, &ptl, strlen( str ), str ) ;
                   1393:                     GpiSetColor( hps, lCurCol ) ;
                   1394:                     DosEnterCritSec() ;
                   1395:                     free(str) ;
                   1396:                     DosExitCritSec() ;
                   1397:                     }
                   1398:                     break ;
                   1399:
                   1400:                 case 'J' :   /* justify */
                   1401:                     BufRead(hRead,&jmode, sizeof(int), &cbR) ;
                   1402:                     break ;
                   1403:
                   1404:                 case 'A' :   /* text angle */
                   1405:                     {
                   1406:                     int ta ;
                   1407:                     GRADIENTL grdl ;
                   1408:                     SIZEF sizHor, sizVer ;
                   1409:                     if( bPath ) {
                   1410:                         GpiEndPath( hps ) ;
                   1411:                         GpiStrokePath( hps, 1, 0 ) ;
                   1412:                         bPath = FALSE ;
                   1413:                         }
                   1414:                     BufRead(hRead,&ta, sizeof(int), &cbR) ;
                   1415:                     if( ta == 0 ) {
                   1416:                         grdl.x = 0L ; grdl.y = 0L ;
                   1417:                         GpiSetCharAngle( hps, &grdl ) ;
                   1418:                         if( !bHorz ) {
                   1419:                             bHorz = TRUE ;
                   1420:                             }
                   1421:                         }
                   1422:                     else if( ta == 1 ) {
                   1423:                         grdl.x = 0L ; grdl.y = 1L ;
                   1424:                         GpiSetCharAngle( hps, &grdl ) ;
                   1425:                         if( bHorz ) {
                   1426:                             bHorz = FALSE ;
                   1427:                             }
                   1428:                         }
                   1429:                     }
                   1430:                     break ;
                   1431:
                   1432:                 case 'L' :   /* line type */
                   1433:                     {
                   1434:                     int lt, col ;
                   1435:                     if( bPath ) {
                   1436:                         GpiEndPath( hps ) ;
                   1437:                         GpiStrokePath( hps, 1, 0 ) ;
                   1438:                         bPath = FALSE ;
                   1439:                         }
                   1440:                     BufRead(hRead,&lt, sizeof(int), &cbR) ;
                   1441:                    /* linetype = -2 axes, -1 border, 0 arrows, all to 0 */
                   1442:                    col = lt ;
                   1443:                     if( lt == -2 )     GpiSetLineWidthGeom( hps, DEFLW*0.85 ) ;
                   1444:                     else if( lt == -1 ) GpiSetLineWidthGeom( hps, DEFLW*0.6 ) ;
                   1445:                     else GpiSetLineWidthGeom( hps, linewidth ) ;
                   1446:                     if( lt < 0 ) lt = 0 ;
                   1447:                    lt = (lt%8);
                   1448:                    col = (col+2)%16 ;
                   1449:                     GpiLabel( hps, lLineTypes[lt] ) ;
                   1450: lOldLine=lt ;
                   1451:                     LType( (bLineTypes||bBW)?lt:0 ) ;
                   1452: //                    GpiSetLineType( hps, (bLineTypes||bBW)?lLineTypes[lt]:lLineTypes[0] ) ;
                   1453:                     if( !bBW ) { /* maintain some flexibility here in case we don't want
                   1454:                            the model T option */
                   1455:                         if( bColours ) GpiSetColor( hps, lCols[col] ) ;
                   1456:                         else GpiSetColor( hps, CLR_BLACK ) ;
                   1457:                         }
                   1458:                     }
                   1459:                     break ;
                   1460:
                   1461:                 case 'W' :   /* line width */
                   1462:                     {
                   1463:                     int lw ;
                   1464:                     if( bPath ) {
                   1465:                         GpiEndPath( hps ) ;
                   1466:                         GpiStrokePath( hps, 1, 0 ) ;
                   1467:                         bPath = FALSE ;
                   1468:                         }
                   1469:                     BufRead(hRead,&lw, sizeof(int), &cbR) ;
                   1470:                     GpiSetLineWidthGeom( hps, DEFLW*lw/100 ) ;
                   1471:                     linewidth = DEFLW*lw/100 ;
                   1472:                     }
                   1473:                     break ;
                   1474:
                   1475:                  case 'D' :   /* points mode */
                   1476:                     {
                   1477:                     int lt ;
                   1478:                     BufRead(hRead,&lt, sizeof(int), &cbR) ;
                   1479:                      /* 1: enter point mode, 0: exit */
                   1480:                     if( bLineTypes || bBW ) {
                   1481:                         if( lt==1) LType(0) ;
                   1482:                         else LType( lOldLine ) ;
                   1483: //                        if( lt == 1 ) lOldLine = GpiSetLineType( hps, lLineTypes[0] ) ;
                   1484: //                        else GpiSetLineType( hps, lOldLine ) ;
                   1485:                         }
                   1486: //                    if( lt == 1 ) GpiSetLineWidthGeom( hps, 20 ) ;
                   1487: //                    else GpiSetLineWidthGeom( hps, 50 ) ;
                   1488:                     bDots = lt ;
                   1489:                     }
                   1490:                     break ;
                   1491:
                   1492:                 case 'F' :   /* set font */
                   1493:
                   1494:                     {
                   1495:                     int len ;
                   1496:                     char *str ;
                   1497:                     char font[FONTBUF] ;
                   1498:                     BufRead(hRead,&len, sizeof(int), &cbR) ;
                   1499:                     len = (len+sizeof(int)-1)/sizeof(int) ;
                   1500:                     if( len == 0 ) {
                   1501:                         SwapFont( hps, NULL ) ;
                   1502:                         }
                   1503:                     else {
                   1504:                         char *p ;
                   1505:                         str = malloc( len*sizeof(int) ) ;
                   1506:                         BufRead(hRead, str, len*sizeof(int), &cbR) ;
                   1507:                         p = strchr(str, ',') ;
                   1508:                         if( p==NULL ) strcpy( font, "14" ) ;
                   1509:                         else {
                   1510:                             *p = '\0' ;
                   1511:                             strcpy( font, p+1 ) ;
                   1512:                             }
                   1513:                         strcat( font,"." ) ;
                   1514:                         strcat( font, str ) ;
                   1515:                         free( str ) ;
                   1516:                         SwapFont( hps, font ) ;
                   1517:                         }
                   1518:                     }
                   1519:                     break ;
                   1520:
                   1521:                 case 'O' :   /* set options */
                   1522:
                   1523:                     {
                   1524:                     int len ;
                   1525:                     char *str ;
                   1526:                     BufRead(hRead,&len, sizeof(int), &cbR) ;
                   1527:                     len = (len+sizeof(int)-1)/sizeof(int) ;
                   1528:                     bWideLines = FALSE ; /* reset options */
                   1529:                     bEnhanced = FALSE ;
                   1530:
                   1531:                     if( len > 0 ) {
                   1532:                         char *p ;
                   1533:                         p = str = malloc( len*sizeof(int) ) ;
                   1534:                         BufRead(hRead, str, len*sizeof(int), &cbR) ;
                   1535:                         while( (p=strchr(p,'-')) != NULL ) {
                   1536:                             ++p ;
                   1537:                             if( *p == 'w' ) bWideLines = TRUE ;
                   1538:                             if( *p == 'e' ) bEnhanced = TRUE ;
                   1539:                             ++p ;
                   1540:                             }
                   1541:                         free( str ) ;
                   1542:                         }
                   1543:                     }
                   1544:                     break ;
                   1545:
                   1546:
                   1547:                  default :  /* should handle error */
                   1548:                     break ;
                   1549:                  }
                   1550:              }
                   1551:         }
                   1552: exitserver:
                   1553:     DosDisConnectNPipe( hRead ) ;
                   1554:     WinPostMsg( hApp, WM_CLOSE, 0L, 0L ) ;
                   1555:     }
                   1556:
                   1557: static void EditLineTypes( HWND hwnd, HPS hps, BOOL bDashed )
                   1558: /*
                   1559: */
                   1560:     {
                   1561:     int i, rc ;
                   1562:     char buf[64] ;
                   1563:     GpiSetDrawingMode( hps, DM_RETAIN ) ;
                   1564:     GpiOpenSegment( hps, iSeg ) ;
                   1565:     GpiSetEditMode( hps, SEGEM_REPLACE ) ;
                   1566:     for( i=0; i<7; i++ ) {
                   1567:         while( GpiSetElementPointerAtLabel( hps, lLineTypes[i] ) ) {
                   1568:             GpiOffsetElementPointer( hps, 1 ) ;
                   1569:             GpiSetLineType( hps, bDashed?lLineTypes[i]:lLineTypes[0] ) ;
                   1570:             }
                   1571:         GpiSetElementPointer( hps, 0 ) ;
                   1572:         }
                   1573:     GpiSetEditMode( hps, SEGEM_INSERT ) ;
                   1574:     GpiCloseSegment( hps ) ;
                   1575:     }
                   1576:
                   1577: static void EditCharCell( HPS hps, SIZEF *psize )
                   1578: /*
                   1579: ** Edit segment to change char cell (font size)
                   1580: */
                   1581:     {
                   1582:     int i ;
                   1583:     LONG rl, rc ;
                   1584:     SIZEF sizH, sizV ;
                   1585:     char buf[64] ;
                   1586:     int iVert = 0 ;
                   1587:
                   1588:     sizH = *psize ;
                   1589:     sizV.cx = sizH.cy ;
                   1590:     sizV.cy = sizH.cx ;
                   1591:     GpiSetDrawingMode( hps, DM_RETAIN ) ;
                   1592:     GpiOpenSegment( hps, iSeg ) ;
                   1593:     GpiSetEditMode( hps, SEGEM_REPLACE ) ;
                   1594:     i=0 ;
                   1595:     while( GpiSetElementPointer( hps, i ) ) {
                   1596:         rc = GpiQueryElementPointer( hps) ;
                   1597:         if( rc != i ) break ;
                   1598:         rl = GpiQueryElementType( hps, &rc, 0, NULL ) ;
                   1599:         if( rc == 0x34 || rc == 0x74 ) {
                   1600:             LONG gdata ;
                   1601:             GpiQueryElement( hps, 5, 4, (PBYTE)&gdata ) ;
                   1602:             if( gdata == 0 ) iVert = 0 ;
                   1603:             else iVert = 1 ;
                   1604:             }
                   1605:         else if( rc==0x33 || rc==0x03 ) GpiSetCharBox(hps, iVert?&sizV:&sizH ) ;
                   1606:         ++i ;
                   1607:         }
                   1608:     GpiSetEditMode( hps, SEGEM_INSERT ) ;
                   1609:     GpiCloseSegment( hps ) ;
                   1610:     }
                   1611:
                   1612: static int BufRead( HFILE hfile, void *buf, int nBytes, ULONG *pcbR )
                   1613: /*
                   1614: ** pull next plot command out of buffer read from GNUPLOT
                   1615: */
                   1616:     {
                   1617:     ULONG ulR, ulRR ;
                   1618:     int rc ;
                   1619:     static char buffer[GNUBUF] ;
                   1620:     static char *pbuffer = buffer+GNUBUF, *ebuffer = buffer+GNUBUF ;
                   1621:
                   1622:     for( ; nBytes > 0 ; nBytes-- ) {
                   1623:         if( pbuffer >= ebuffer ) {
                   1624:             ulR = GNUBUF ;
                   1625:             rc = DosRead( hfile, buffer, ulR, &ulRR ) ;
                   1626:             if( rc != 0 ) return rc ;
                   1627:             if( ulRR == 0 ) return 1 ;
                   1628:             pbuffer = buffer ;
                   1629:             ebuffer = pbuffer+ulRR ;
                   1630:             }
                   1631:         *(char*)buf++ = *pbuffer++ ;
                   1632:         }
                   1633:     return 0L ;
                   1634:     }
                   1635:
                   1636:
                   1637: int GetNewFont( HWND hwnd, HPS hps )
                   1638: /*
                   1639: ** Get a new font using standard font dialog
                   1640: */
                   1641:     {
                   1642:     static FONTDLG pfdFontdlg;      /* Font dialog info structure */
                   1643:     static int i1 =1 ;
                   1644:     static int     iSize ;
                   1645:     char szPtList[64] ;
                   1646:     HWND    hwndFontDlg;     /* Font dialog window handle */
                   1647:     char    *p ;
                   1648:     char szFamilyname[FACESIZE];
                   1649:
                   1650:     if( i1 ) {
                   1651:         strcpy( pfdFontdlg.fAttrs.szFacename, strchr( szFontNameSize, '.' ) + 1 ) ;
                   1652:         strcpy( szFamilyname, strchr( szFontNameSize, '.' ) + 1 ) ;
                   1653:         sscanf( szFontNameSize, "%d", &iSize ) ;
                   1654:         memset(&pfdFontdlg, 0, sizeof(FONTDLG));
                   1655:
                   1656:         pfdFontdlg.cbSize = sizeof(FONTDLG);
                   1657:         pfdFontdlg.hpsScreen = hps;
                   1658:  /*   szFamilyname[0] = 0;*/
                   1659:         pfdFontdlg.pszFamilyname = szFamilyname;
                   1660:         pfdFontdlg.usFamilyBufLen = FACESIZE;
                   1661:         pfdFontdlg.fl = FNTS_HELPBUTTON |
                   1662:                         FNTS_CENTER | FNTS_VECTORONLY |
                   1663:                         FNTS_OWNERDRAWPREVIEW ;
                   1664:         pfdFontdlg.clrFore = CLR_BLACK;
                   1665:         pfdFontdlg.clrBack = CLR_WHITE;
                   1666:         pfdFontdlg.usWeight = FWEIGHT_NORMAL ; //5 ;
                   1667:         pfdFontdlg.fAttrs.usCodePage = 0;
                   1668:         pfdFontdlg.fAttrs.usRecordLength = sizeof(FATTRS) ;
                   1669:         }
                   1670:     sprintf( szPtList, "%d 8 10 12 14 18 24", iSize ) ;
                   1671:     pfdFontdlg.pszPtSizeList = szPtList ;
                   1672:     pfdFontdlg.fxPointSize = MAKEFIXED(iSize,0);
                   1673:     hwndFontDlg = WinFontDlg(HWND_DESKTOP, hwnd, &pfdFontdlg);
                   1674:     if( i1 ) {
                   1675:         pfdFontdlg.fl = FNTS_HELPBUTTON |
                   1676:                         FNTS_CENTER | FNTS_VECTORONLY |
                   1677:                         FNTS_INITFROMFATTRS ;
                   1678:         i1=0;
                   1679:         }
                   1680:     if (hwndFontDlg && (pfdFontdlg.lReturn == DID_OK)) {
                   1681:         iSize = FIXEDINT( pfdFontdlg.fxPointSize ) ;
                   1682:         sprintf( szFontNameSize, "%d.%s", iSize, pfdFontdlg.fAttrs.szFacename ) ;
                   1683:         return 1 ;
                   1684:         }
                   1685:     else return 0 ;
                   1686:     }
                   1687:
                   1688: void SigHandler( int sig )
                   1689: /*
                   1690: **  Handle termination signal to free up resources before
                   1691: **  termination.
                   1692: */
                   1693:     {
                   1694:     if( sig == SIGTERM ) {
                   1695:         if( bPersist ) {
                   1696:             DosKillThread( tidSpawn ) ;
                   1697:             signal( SIGTERM, SIG_ACK ) ;
                   1698:             return ;
                   1699:             }
                   1700:         DosEnterCritSec() ;
                   1701:         DosKillThread( tidSpawn ) ;
                   1702:         DosKillThread( tidDraw ) ;
                   1703:         DosExitCritSec() ;
                   1704:         exit(0) ;
                   1705:         }
                   1706:     }
                   1707:
                   1708: /* disable debugging info */
                   1709: #define TEXT_DEBUG(x) /* fprintf x; */
                   1710:
                   1711: /* used in determining height of processed text */
                   1712:
                   1713: //static float max_height, min_height;
                   1714:
                   1715: /* process a bit of string, and return the last character used.
                   1716:  * p is start of string
                   1717:  * brace is TRUE to keep processing to }, FALSE for do one character
                   1718:  * fontname & fontsize are obvious
                   1719:  * base is the current baseline
                   1720:  * widthflag is TRUE if the width of this should count,
                   1721:  *              FALSE for zero width boxes
                   1722:  * showflag is TRUE if this should be shown,
                   1723:  *             FALSE if it should not be shown (like TeX \phantom)
                   1724:  */
                   1725:
                   1726: static char *starttext = NULL ;
                   1727: static int  textlen = 0 ;
                   1728: static BOOL bText = FALSE ;
                   1729: static int  textwidth = 0 ;
                   1730: static POINTL ptlText ;
                   1731: static FILE *ff ;
                   1732: static char *ParseText(HPS hps, char *p, BOOL brace, char *fontname,
                   1733:                        int fontsize, int base, BOOL widthflag, BOOL showflag)
                   1734: {
                   1735:     POINTL aptl[TXTBOX_COUNT] ;
                   1736:     BOOL bChangeFont = FALSE ;
                   1737:        TEXT_DEBUG((ff,"RECURSE WITH [%p] %s, %d %s %.1f %.1f %d %d\n", p, p, brace, fontname, fontsize, base, widthflag, showflag))
                   1738:
                   1739:     /* Start each recursion with a clean string */
                   1740:
                   1741: //{FILE *ff;int i=textlen;ff=fopen("deb","a");
                   1742: //for(i=0;i<textlen;i++)fputc(starttext[i], ff);fputc('\n',ff) ; fclose(ff);}
                   1743:         if( textlen > 0 ) {
                   1744:             GpiQueryTextBox( hps, textlen, starttext, TXTBOX_COUNT, aptl ) ;
                   1745:             if( bHorz ) textwidth += aptl[TXTBOX_BOTTOMRIGHT].x ;
                   1746:             else        textwidth += aptl[TXTBOX_BOTTOMRIGHT].y ;
                   1747:             }
                   1748:         if( bText ) {
                   1749:             if(textlen > 0 ) {
                   1750:                 GpiCharStringAt( hps, &ptlText, textlen, starttext ) ;
                   1751:                 ptlText.x += aptl[TXTBOX_CONCAT].x + (bHorz?0:(-base)) ;
                   1752:                 ptlText.y += aptl[TXTBOX_CONCAT].y + (bHorz?base:0) ;
                   1753:                 }
                   1754:             else {
                   1755:                 ptlText.x += (bHorz?0:(-base)) ;
                   1756:                 ptlText.y += (bHorz?base:0) ;
                   1757:                 }
                   1758:             }
                   1759:         textlen = 0 ;
                   1760:         starttext = p ;
                   1761:         if( fontname != NULL ) {
                   1762:             char szFont[FONTBUF] ;
                   1763:             sprintf(szFont, "%d.%s", fontsize, fontname ) ;
                   1764:             SwapFont( hps, szFont ) ;
                   1765:             bChangeFont = TRUE ;
                   1766:             }
                   1767:     if( base != 0 ) GpiSetCharBox( hps, &sizCurSubSup ) ;
                   1768:
                   1769:     for ( ; *p; ++p)
                   1770:     {    int shift;
                   1771:
                   1772:         switch (*p)
                   1773:         {
                   1774:             case '}'  :
                   1775:                 /*{{{  deal with it*/
                   1776:                 if (brace) {
                   1777:                     brace = 0 ;
                   1778:                     break ;
                   1779:                     }
                   1780:
                   1781:                 break;
                   1782:                 /*}}}*/
                   1783:
                   1784:             case '_'  :
                   1785:             case '^'  :
                   1786:                 /*{{{  deal with super/sub script*/
                   1787:
                   1788:                 shift = (*p == '^') ? lSupOffset : lSubOffset;
                   1789:                 p = ParseText(hps, p+1, FALSE, NULL/*fontname*/, fontsize*0.7, base+shift, widthflag, showflag);
                   1790:                 break;
                   1791:                 /*}}}*/
                   1792:
                   1793:             case '{'  :
                   1794:             {
                   1795:                 char *savepos=NULL, save=0;
                   1796:                 char *localfontname=fontname, ch;
                   1797:                 char localfontbuf[FONTBUF] ;
                   1798:                 int recode=1;
                   1799:                 int f=fontsize;
                   1800:                 BOOL bChangeFont = FALSE ;
                   1801:                 char *q=localfontbuf ;
                   1802:
                   1803:                 /*{{{  recurse (possibly with a new font) */
                   1804:
                   1805:                 TEXT_DEBUG((ff,"Dealing with {\n"))
                   1806:
                   1807:                 if (*++p == '/')
                   1808:                 {    /* then parse a fontname, optional fontsize */
                   1809:                     while (*++p == ' ');
                   1810:                     if (*p=='-')
                   1811:                     {
                   1812:                         recode=0;
                   1813:                         while (*++p == ' ');
                   1814:                     }
                   1815:                     localfontname = p;
                   1816:                     while ((ch = *p) > ' ' && ch != '=') {
                   1817:                             localfontname=localfontbuf ;
                   1818:                             if(*p=='_') *q=' ' ;
                   1819:                             else *q=*p ;
                   1820:                         ++p;++q;
                   1821:                         }
                   1822:                     *q = '\0' ;
                   1823:                     FontExpand( localfontbuf ) ;
                   1824:                     save = *(savepos=p);
                   1825:                     if (ch == '=')
                   1826:                     {
                   1827:                         *p++ = '\0';
                   1828:                         /*{{{  get optional font size*/
                   1829:                         TEXT_DEBUG((ff,"Calling strtod(%s) ...", p))
                   1830:                         f = strtod(p, &p);
                   1831:                         TEXT_DEBUG((ff,"Retured %.1f and %s\n", f, p))
                   1832:
                   1833:                         if (!f) f = fontsize;
                   1834:
                   1835:                         TEXT_DEBUG((ff,"Font size %.1f\n", f))
                   1836:                         /*}}}*/
                   1837:                     }
                   1838:                     else
                   1839:                     {
                   1840:                         *p++ = '\0';
                   1841:                         f = fontsize;
                   1842:                     }
                   1843:
                   1844:                     while (*p == ' ')
                   1845:                         ++p;
                   1846:                     if (! (*localfontname)) {
                   1847:                         localfontname = fontname;
                   1848:                         if( f != fontsize )
                   1849:                             localfontname = strchr( szFontNameSize, '.' ) + 1 ;
                   1850:                         }
                   1851:                 }
                   1852:                 /*}}}*/
                   1853:
                   1854:                 TEXT_DEBUG((ff,"Before recursing, we are at [%p] %s\n", p, p))
                   1855:
                   1856:                 p = ParseText(hps,p, TRUE, localfontname, f, base, widthflag, showflag);
                   1857:
                   1858:                 TEXT_DEBUG((ff,"BACK WITH %s\n", p));
                   1859:                 if (savepos)
                   1860:                     /* restore overwritten character */
                   1861:                     *savepos = save;
                   1862:
                   1863:                 break;
                   1864:             }
                   1865:
                   1866:             case '@' :
                   1867:                 /*{{{  phantom box - prints next 'char', then restores currentpoint */
                   1868:
                   1869:                 p = ParseText(hps,++p, FALSE, NULL/*fontname*/, fontsize, base, FALSE, showflag);
                   1870:
                   1871:                 break;
                   1872:                 /*}}}*/
                   1873:
                   1874:             case '&' :
                   1875:                 /*{{{  character skip - skips space equal to length of character(s) */
                   1876:
                   1877:                 p = ParseText(hps,++p, FALSE, NULL/*fontname*/, fontsize, base, widthflag, FALSE);
                   1878:
                   1879:                 break;
                   1880:                 /*}}}*/
                   1881:
                   1882:             case '\\'  :
                   1883:                 {
                   1884:                 char buffer[4] ; /* should need only one char.. */
                   1885:                 char *q = buffer ;
                   1886:                 *q = '\0' ;
                   1887:                 ParseText(hps,q, FALSE, NULL, fontsize, base, widthflag, showflag);
                   1888:                 /*{{{  is it an escape */
                   1889:                 /* special cases */
                   1890:
                   1891:                 if (p[1]=='\\' || p[1]=='{' || p[1]=='}')
                   1892:                 {
                   1893:                     *q++=p[1] ;
                   1894:                     ++p ;
                   1895:                 }
                   1896: #if 0
                   1897:                 else if (p[1] >= '0' && p[1] <= '7')
                   1898:                 {
                   1899:                     /* up to 3 octal digits */
                   1900:                     int c = 0 ;
                   1901:                     c+=p[1];
                   1902:                     ++p;
                   1903:                     if (p[1] >= '0' && p[1] <= '7')
                   1904:                     {
                   1905:                         c*=8; c+=p[1];
                   1906:                         ++p;
                   1907:                         if (p[1] >= '0' && p[1] <= '7')
                   1908:                         {
                   1909:                             c*=8; c+=p[1];
                   1910:                             ++p;
                   1911:                         }
                   1912:                     }
                   1913:                     *q++ = c ;
                   1914:                     break;
                   1915:                 }
                   1916: #endif
                   1917:                 *q = '\0' ;
                   1918:                 textlen = 1 ;
                   1919:                 starttext=buffer ;
                   1920:                 ParseText(hps,q, FALSE, NULL/*fontname*/, fontsize, base, widthflag, showflag);
                   1921:                 starttext=p+1 ;
                   1922:                 textlen = 0 ;
                   1923:                 /*}}}*/
                   1924:                 }
                   1925:                 break ;
                   1926:
                   1927:             default:
                   1928:                 ++textlen ;
                   1929:
                   1930:             /*}}}*/
                   1931:
                   1932:         }
                   1933:
                   1934:         /* like TeX, we only do one character in a recursion, unless it's
                   1935:          * in braces
                   1936:          */
                   1937:
                   1938:         if (!brace) break ;
                   1939:         }
                   1940:         if( textlen > 0 ) {
                   1941:             GpiQueryTextBox( hps, textlen, starttext, TXTBOX_COUNT, aptl ) ;
                   1942:             if( widthflag ) {
                   1943:                 if( bHorz ) textwidth += aptl[TXTBOX_BOTTOMRIGHT].x ;
                   1944:                 else        textwidth += aptl[TXTBOX_BOTTOMRIGHT].y ;
                   1945:                 }
                   1946:             }
                   1947:         if( bText ) {
                   1948:             if( textlen > 0 ) {
                   1949:                 if( showflag)
                   1950:                     GpiCharStringAt( hps, &ptlText, textlen, starttext ) ;
                   1951:                 if( widthflag ) {
                   1952:                     ptlText.x += aptl[TXTBOX_CONCAT].x ;
                   1953:                     ptlText.y += aptl[TXTBOX_CONCAT].y ;
                   1954:                     }
                   1955:                 }
                   1956:             if( base != 0 ) {
                   1957:                 ptlText.x -= (bHorz?0:(-base)) ;
                   1958:                 ptlText.y -= (bHorz?base:0) ;
                   1959:                 }
                   1960:             }
                   1961:         if( bChangeFont ) {
                   1962:             SwapFont( hps, NULL ) ;
                   1963:             bChangeFont = FALSE ;
                   1964:             }
                   1965:     if( base != 0 ) GpiSetCharBox( hps, &sizBaseFont ) ;
                   1966:
                   1967:
                   1968:         textlen = 0 ;
                   1969:         starttext = p+1 ;
                   1970:     return p;
                   1971: }
                   1972:
                   1973: static void CharStringAt(HPS hps, int x, int y, int len, char *str)
                   1974: {
                   1975:     /* flush any pending graphics (all the XShow routines do this...) */
                   1976:
                   1977:      char *fontname ;
                   1978:      int fontsize ;
                   1979:
                   1980:     if (!strlen(str))
                   1981:         return;
                   1982:
                   1983:     /* set up the globals */
                   1984:
                   1985:         ptlText.x = x ;
                   1986:         ptlText.y = y ;
                   1987:         bText = TRUE ;
                   1988:         starttext = NULL ;
                   1989:         textlen = 0 ;
                   1990:         textwidth = 0 ;
                   1991:         sscanf( szFontNameSize, "%d", &fontsize ) ;
                   1992:         fontname = strchr( szFontNameSize, '.' ) + 1 ;
                   1993:
                   1994:     while (*(str = ParseText(hps, str, TRUE, NULL,
                   1995:                      fontsize,
                   1996:                      0.0, TRUE, TRUE)));
                   1997:
                   1998: }
                   1999:
                   2000: static int QueryTextBox( HPS hps, int len, char *str )
                   2001: {
                   2002:      char *fontname ;
                   2003:      int fontsize ;
                   2004:     if (!strlen(str))
                   2005:         return 0 ;
                   2006:
                   2007:
                   2008:     /* set up the globals */
                   2009:
                   2010:         bText = FALSE ;
                   2011:         starttext = NULL ;
                   2012:         textlen = 0 ;
                   2013:         textwidth = 0 ;
                   2014:         sscanf( szFontNameSize, "%d", &fontsize ) ;
                   2015:         fontname = strchr( szFontNameSize, '.' ) + 1 ;
                   2016:
                   2017:     while (*(str = ParseText(hps, str, TRUE, NULL,
                   2018:                      fontsize,
                   2019:                      0.0, TRUE, TRUE)));
                   2020:
                   2021:     return textwidth ;
                   2022: }
                   2023:
                   2024: void FontExpand( char *name )
                   2025:     {
                   2026:     if     ( strcmp(name,"S")==0 ) strcpy( name, "Symbol Set" ) ;
                   2027:     else if( strcmp(name,"H")==0 ) strcpy( name, "Helvetica" ) ;
                   2028:     else if( strcmp(name,"T")==0 ) strcpy( name, "Times New Roman" ) ;
                   2029:     else if( strcmp(name,"C")==0 ) strcpy( name, "Courier" ) ;
                   2030:     }
                   2031:
                   2032: /*=======================================*/
                   2033: static POINTL pCur ;
                   2034: static int iLinebegin = 1 ;
                   2035: static int iLtype = 0 ;
                   2036: static int iState = 0 ;
                   2037: static double togo = 0.0 ;
                   2038: static int iPatt[8][9]
                   2039:   = {
                   2040:     {   0,   0,   0,   0,   0,   0,   0,   0,  0 },
                   2041:     { 300, 200,  -1,   0,   0,   0,   0,   0,  0 },
                   2042:     { 150, 150,  -1,   0,   0,   0,   0,   0,  0 },
                   2043:     { 300, 200, 150, 200,  -1,   0,   0,   0,  0 },
                   2044:     { 500, 200,  -1,   0,   0,   0,   0,   0,  0 },
                   2045:     { 300, 200, 150, 200, 150, 200,  -1,   0,  0 },
                   2046:     { 300, 200, 150, 200, 150, 200, 150, 200, -1 },
                   2047:     { 500, 200, 150, 200,  -1,   0,   0,   0,  0 }
                   2048:     } ;
                   2049:
                   2050: void LMove( HPS hps, POINTL *p )
                   2051:     {
                   2052:     double ds, dx, dy ;
                   2053:     if( iLinebegin ) {
                   2054:         pCur = *p ;
                   2055:         GpiMove( hps, p ) ;
                   2056:         }
                   2057:     else if( iLtype == 0 ) GpiMove( hps, p ) ;
                   2058:     else {
                   2059:         dx = p->x - pCur.x ;
                   2060:         dy = p->y - pCur.y ;
                   2061:         ds = sqrt( dx*dx + dy*dy ) ;
                   2062:         dx /= ds ; dy /= ds ;
                   2063:         while( ds > 0.0 ) {
                   2064:             if( ds < togo ) {
                   2065:                 togo -= ds ;
                   2066:                 ds = 0.0 ;
                   2067:                 GpiMove( hps, p ) ;
                   2068:                 pCur = *p ;
                   2069:                 }
                   2070:             else {
                   2071:                 POINTL pn ;
                   2072:                 pn.x = pCur.x + togo * dx ;
                   2073:                 pn.y = pCur.y + togo * dy ;
                   2074:                 GpiMove( hps, &pn ) ;
                   2075:                 pCur = pn ;
                   2076:                 ds -= togo ;
                   2077:                 iState++ ;
                   2078:                 if( iPatt[iLtype][iState] < 0 ) {
                   2079:                     togo = iPatt[iLtype][0] ;
                   2080:                     iState = 0 ;
                   2081:         }
                   2082:                 else togo = iPatt[iLtype][iState] ;
                   2083:     }
                   2084:             }
                   2085:         }
                   2086:     }
                   2087:
                   2088: void LLine( HPS hps, POINTL *p )
                   2089:     {
                   2090:     double ds, dx, dy ;
                   2091:     if( iLinebegin ) iLinebegin = 0 ;
                   2092:
                   2093:     if( iLtype == 0 ) GpiLine( hps, p ) ;
                   2094:     else {
                   2095:         dx = p->x - pCur.x ;
                   2096:         dy = p->y - pCur.y ;
                   2097:         ds = sqrt( dx*dx + dy*dy ) ;
                   2098:         dx /= ds ; dy /= ds ;
                   2099:         while( ds > 0.0 ) {
                   2100:             if( ds < togo ) {
                   2101:                 togo -= ds ;
                   2102:                 ds = 0.0 ;
                   2103:                 if( iState&1 ) GpiMove( hps, p ) ;
                   2104:                 else GpiLine( hps, p ) ;
                   2105:                 pCur = *p ;
                   2106:                 }
                   2107:             else {
                   2108:                 POINTL pn ;
                   2109:                 pn.x = pCur.x + togo * dx ;
                   2110:                 pn.y = pCur.y + togo * dy ;
                   2111:                 if( iState&1 ) GpiMove( hps, &pn ) ;
                   2112:                 else GpiLine( hps, &pn ) ;
                   2113:                 pCur = pn ;
                   2114:                 ds -= togo ;
                   2115:                 iState++ ;
                   2116:                 if( iPatt[iLtype][iState] < 0 ) {
                   2117:                     togo = iPatt[iLtype][0] ;
                   2118:                     iState = 0 ;
                   2119:                     }
                   2120:                 else togo = iPatt[iLtype][iState] ;
                   2121:                 }
                   2122:             }
                   2123:         }
                   2124:     }
                   2125:
                   2126: void LType( int iType )
                   2127:     {
                   2128:     iLinebegin = 1 ;
                   2129:     if( iType > 7 ) iType = 0 ;
                   2130:     iLtype = iType ;
                   2131:     iState = 0 ;
                   2132:     togo = iPatt[iLtype][0] ;
                   2133:     }
                   2134:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>