Annotation of OpenXM_contrib/gnuplot/os2/gclient.c, Revision 1.1
1.1 ! maekawa 1: #ifdef INCRCSDATA
! 2: static char RCSid[]="$Id: gclient.c,v 1.15 1998/03/22 22:34:21 drd Exp $" ;
! 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,<, 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,<, 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>