home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume40 / gnuplot / part09 < prev    next >
Encoding:
Text File  |  1993-10-21  |  79.2 KB  |  2,827 lines

  1. Newsgroups: comp.sources.misc
  2. From: woo@playfair.stanford.edu ("Alexander Woo")
  3. Subject: v40i021:  gnuplot - interactive function plotting utility, Part09/33
  4. Message-ID: <1993Oct21.144458.1933@sparky.sterling.com>
  5. X-Md4-Signature: 8af1f68792598ced9024ea8f4973f8e3
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Thu, 21 Oct 1993 14:44:58 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: woo@playfair.stanford.edu ("Alexander Woo")
  12. Posting-number: Volume 40, Issue 21
  13. Archive-name: gnuplot/part09
  14. Environment: UNIX, MS-DOS, VMS
  15. Supersedes: gnuplot3: Volume 24, Issue 23-48
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  gnuplot/docs/latextut/eg1.plt gnuplot/misc.c
  22. #   gnuplot/win/wtext.c
  23. # Wrapped by kent@sparky on Wed Oct 20 17:14:42 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 9 (of 33)."'
  27. if test -f 'gnuplot/docs/latextut/eg1.plt' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'gnuplot/docs/latextut/eg1.plt'\"
  29. else
  30.   echo shar: Extracting \"'gnuplot/docs/latextut/eg1.plt'\" \(65 characters\)
  31.   sed "s/^X//" >'gnuplot/docs/latextut/eg1.plt' <<'END_OF_FILE'
  32. Xset terminal latex
  33. Xset output "eg1.tex"
  34. Xplot [-3.14:3.14] sin(x)
  35. END_OF_FILE
  36.   if test 65 -ne `wc -c <'gnuplot/docs/latextut/eg1.plt'`; then
  37.     echo shar: \"'gnuplot/docs/latextut/eg1.plt'\" unpacked with wrong size!
  38.   fi
  39.   # end of 'gnuplot/docs/latextut/eg1.plt'
  40. fi
  41. if test -f 'gnuplot/misc.c' -a "${1}" != "-c" ; then 
  42.   echo shar: Will not clobber existing file \"'gnuplot/misc.c'\"
  43. else
  44.   echo shar: Extracting \"'gnuplot/misc.c'\" \(25786 characters\)
  45.   sed "s/^X//" >'gnuplot/misc.c' <<'END_OF_FILE'
  46. X#ifndef lint
  47. Xstatic char *RCSid = "$Id: misc.c%v 3.50 1993/07/09 05:35:24 woo Exp $";
  48. X#endif
  49. X
  50. X
  51. X/* GNUPLOT - misc.c */
  52. X/*
  53. X * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  54. X *
  55. X * Permission to use, copy, and distribute this software and its
  56. X * documentation for any purpose with or without fee is hereby granted, 
  57. X * provided that the above copyright notice appear in all copies and 
  58. X * that both that copyright notice and this permission notice appear 
  59. X * in supporting documentation.
  60. X *
  61. X * Permission to modify the software is granted, but not the right to
  62. X * distribute the modified code.  Modifications are to be distributed 
  63. X * as patches to released version.
  64. X *  
  65. X * This software is provided "as is" without express or implied warranty.
  66. X * 
  67. X *
  68. X * AUTHORS
  69. X *
  70. X *   Original Software:
  71. X *     Thomas Williams,  Colin Kelley.
  72. X * 
  73. X *   Gnuplot 2.0 additions:
  74. X *       Russell Lang, Dave Kotz, John Campbell.
  75. X *
  76. X *   Gnuplot 3.0 additions:
  77. X *       Gershon Elber and many others.
  78. X *
  79. X */
  80. X
  81. X#include <stdio.h>
  82. X#include <math.h>
  83. X#ifndef __PUREC__
  84. X#ifndef VMS
  85. X#ifdef AMIGA_AC_5
  86. X#include <exec/types.h>
  87. X#else
  88. X#include <sys/types.h>
  89. X#endif /* AMIGA_AC_5 */
  90. X#else
  91. X#include <types.h>
  92. X#endif
  93. X#endif /* __PUREC__ */
  94. X#include "plot.h"
  95. X#include "setshow.h"
  96. X#ifndef _Windows
  97. X#include "help.h"
  98. X#endif
  99. X
  100. X#if !defined(__TURBOC__) && !defined (_IBMR2) && !defined (ATARI) && !defined (AMIGA_SC_6_1) && !defined(OSF1)
  101. Xextern char *malloc();
  102. Xextern char *realloc();
  103. X#endif
  104. X
  105. X#if defined(__TURBOC__) && (defined(MSDOS) || defined(_Windows))
  106. X#include <alloc.h>        /* for malloc, farmalloc, farrealloc */
  107. X#endif
  108. X#if defined(sequent)
  109. X#include <sys/types.h>          /* typedef long size_t; */
  110. X#endif
  111. X
  112. Xextern int c_token;
  113. Xextern char replot_line[];
  114. Xextern struct at_type at;
  115. Xextern struct ft_entry ft[];
  116. Xextern struct udft_entry *first_udf;
  117. Xextern struct udvt_entry *first_udv;
  118. X
  119. Xextern struct at_type *temp_at();
  120. X
  121. Xextern TBOOLEAN interactive;
  122. Xextern char *infile_name;
  123. Xextern int inline_num;
  124. X
  125. X/* State information for load_file(), to recover from errors
  126. X * and properly handle recursive load_file calls
  127. X */
  128. Xtypedef struct lf_state_struct LFS;
  129. Xstruct lf_state_struct {
  130. X    FILE *fp;                /* file pointer for load file */
  131. X    char *name;            /* name of file */
  132. X    TBOOLEAN interactive;        /* value of interactive flag on entry */
  133. X    int inline_num;            /* inline_num on entry */
  134. X    LFS *prev;                /* defines a stack */
  135. X} *lf_head = NULL;            /* NULL if not in load_file */
  136. X
  137. Xstatic TBOOLEAN lf_pop();
  138. Xstatic void lf_push();
  139. XFILE *lf_top();
  140. X
  141. X
  142. X/*
  143. X * instead of <strings.h>
  144. X */
  145. X#ifdef _Windows
  146. X#include <string.h>
  147. X#else
  148. X#ifndef AMIGA_SC_6_1
  149. Xextern int strcmp();
  150. X#endif /* !AMIGA_SC_6_1 */
  151. X#endif
  152. X
  153. X/* alloc:
  154. X * allocate memory 
  155. X * This is a protected version of malloc. It causes an int_error 
  156. X * if there is not enough memory, but first it tries FreeHelp() 
  157. X * to make some room, and tries again. If message is NULL, we 
  158. X * allow NULL return. Otherwise, we handle the error, using the
  159. X * message to create the int_error string. Note cp/sp_extend uses realloc,
  160. X * so it depends on this using malloc().
  161. X */
  162. X
  163. Xchar *
  164. Xalloc(size, message)
  165. X    unsigned long size;        /* # of bytes */
  166. X    char *message;            /* description of what is being allocated */
  167. X{
  168. X    char *p;                /* the new allocation */
  169. X    char errbuf[100];        /* error message string */
  170. X
  171. X    p = malloc((size_t)size);
  172. X    if (p == (char *)NULL) {
  173. X#ifndef vms
  174. X#ifndef _Windows
  175. X       FreeHelp();            /* out of memory, try to make some room */
  176. X#endif
  177. X#endif
  178. X       p = malloc((size_t)size);        /* try again */
  179. X       if (p == (char *)NULL) {
  180. X          /* really out of memory */
  181. X          if (message != NULL) {
  182. X             (void) sprintf(errbuf, "out of memory for %s", message);
  183. X             int_error(errbuf, NO_CARET);
  184. X             /* NOTREACHED */
  185. X          }
  186. X          /* else we return NULL */
  187. X       }
  188. X    }
  189. X    return(p);
  190. X}
  191. X
  192. X/*
  193. X * cp_alloc() allocates a curve_points structure that can hold 'num'
  194. X * points.
  195. X */
  196. Xstruct curve_points *
  197. Xcp_alloc(num)
  198. X    int num;
  199. X{
  200. X    struct curve_points *cp;
  201. X    cp = (struct curve_points *) alloc((unsigned long)sizeof(struct curve_points), "curve");
  202. X    cp->p_max = (num >= 0 ? num : 0);
  203. X    if (num > 0) {
  204. X       cp->points = (struct coordinate GPHUGE *)
  205. X        gpfaralloc((unsigned long)num * sizeof(struct coordinate), "curve points");
  206. X    } else
  207. X       cp->points = (struct coordinate GPHUGE *) NULL;
  208. X    cp->next_cp = NULL;
  209. X    cp->title = NULL;
  210. X    return(cp);
  211. X}
  212. X
  213. X
  214. X/*
  215. X * cp_extend() reallocates a curve_points structure to hold "num"
  216. X * points. This will either expand or shrink the storage.
  217. X */
  218. Xcp_extend(cp, num)
  219. X    struct curve_points *cp;
  220. X    int num;
  221. X{
  222. X    struct coordinate GPHUGE *new;
  223. X
  224. X#if (defined(MSDOS) || defined(_Windows))  &&  !defined(WIN32)
  225. X    /* Make sure we do not allocate more than 64k points in msdos since 
  226. X     * indexing is done with 16-bit int
  227. X     * Leave some bytes for malloc maintainance.
  228. X     */
  229. X    if (num > 32700)
  230. X        int_error("Array index must be less than 32k in msdos", NO_CARET);
  231. X#endif /* MSDOS */
  232. X
  233. X    if (num == cp->p_max) return(0);
  234. X
  235. X    if (num > 0) {
  236. X       if (cp->points == NULL) {
  237. X          cp->points = (struct coordinate GPHUGE *)
  238. X            gpfaralloc((unsigned long)num * sizeof(struct coordinate), "curve points");
  239. X       } else {
  240. X          new = (struct coordinate GPHUGE *)
  241. X            gpfarrealloc(cp->points, (unsigned long)num * sizeof(struct coordinate));
  242. X          if (new == (struct coordinate GPHUGE *) NULL) {
  243. X             int_error("No memory available for expanding curve points",
  244. X                     NO_CARET);
  245. X             /* NOTREACHED */
  246. X          }
  247. X          cp->points = new;
  248. X       }
  249. X       cp->p_max = num;
  250. X    } else {
  251. X       if (cp->points != (struct coordinate GPHUGE *) NULL)
  252. X        gpfarfree(cp->points);
  253. X       cp->points = (struct coordinate GPHUGE *) NULL;
  254. X       cp->p_max = 0;
  255. X    }
  256. X}
  257. X
  258. X/*
  259. X * cp_free() releases any memory which was previously malloc()'d to hold
  260. X *   curve points (and recursively down the linked list).
  261. X */
  262. Xcp_free(cp)
  263. Xstruct curve_points *cp;
  264. X{
  265. X    if (cp) {
  266. X        cp_free(cp->next_cp);
  267. X        if (cp->title)
  268. X            free((char *)cp->title);
  269. X        if (cp->points)
  270. X            gpfarfree((char *)cp->points);
  271. X        free((char *)cp);
  272. X    }
  273. X}
  274. X
  275. X/*
  276. X * iso_alloc() allocates a iso_curve structure that can hold 'num'
  277. X * points.
  278. X */
  279. Xstruct iso_curve *
  280. Xiso_alloc(num)
  281. X    int num;
  282. X{
  283. X    struct iso_curve *ip;
  284. X    ip = (struct iso_curve *) alloc((unsigned long)sizeof(struct iso_curve), "iso curve");
  285. X    ip->p_max = (num >= 0 ? num : 0);
  286. X    if (num > 0) {
  287. X       ip->points = (struct coordinate GPHUGE *)
  288. X        gpfaralloc((unsigned long)num * sizeof(struct coordinate), "iso curve points");
  289. X    } else
  290. X       ip->points = (struct coordinate GPHUGE *) NULL;
  291. X    ip->next = NULL;
  292. X    return(ip);
  293. X}
  294. X
  295. X/*
  296. X * iso_extend() reallocates a iso_curve structure to hold "num"
  297. X * points. This will either expand or shrink the storage.
  298. X */
  299. Xiso_extend(ip, num)
  300. X    struct iso_curve *ip;
  301. X    int num;
  302. X{
  303. X    struct coordinate GPHUGE *new;
  304. X
  305. X    if (num == ip->p_max) return(0);
  306. X
  307. X#if (defined(MSDOS) || defined(_Windows))  &&  !defined(WIN32)
  308. X    /* Make sure we do not allocate more than 64k points in msdos since 
  309. X     * indexing is done with 16-bit int
  310. X     * Leave some bytes for malloc maintainance.
  311. X     */
  312. X    if (num > 32700)
  313. X        int_error("Array index must be less than 32k in msdos", NO_CARET);
  314. X#endif /* MSDOS */
  315. X
  316. X    if (num > 0) {
  317. X       if (ip->points == NULL) {
  318. X          ip->points = (struct coordinate GPHUGE *)
  319. X            gpfaralloc((unsigned long)num * sizeof(struct coordinate), "iso curve points");
  320. X       } else {
  321. X          new = (struct coordinate GPHUGE *)
  322. X            gpfarrealloc(ip->points, (unsigned long)num * sizeof(struct coordinate));
  323. X          if (new == (struct coordinate GPHUGE *) NULL) {
  324. X             int_error("No memory available for expanding curve points",
  325. X                     NO_CARET);
  326. X             /* NOTREACHED */
  327. X          }
  328. X          ip->points = new;
  329. X       }
  330. X       ip->p_max = num;
  331. X    } else {
  332. X       if (ip->points != (struct coordinate GPHUGE *) NULL)
  333. X        gpfarfree(ip->points);
  334. X       ip->points = (struct coordinate GPHUGE *) NULL;
  335. X       ip->p_max = 0;
  336. X    }
  337. X}
  338. X
  339. X/*
  340. X * iso_free() releases any memory which was previously malloc()'d to hold
  341. X *   iso curve points.
  342. X */
  343. Xiso_free(ip)
  344. Xstruct iso_curve *ip;
  345. X{
  346. X    if (ip) {
  347. X        if (ip->points)
  348. X            gpfarfree((char *)ip->points);
  349. X        free((char *)ip);
  350. X    }
  351. X}
  352. X
  353. X/*
  354. X * sp_alloc() allocates a surface_points structure that can hold 'num_iso_1'
  355. X * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
  356. X * 'num_samp_1' samples.
  357. X * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
  358. X */
  359. Xstruct surface_points *
  360. Xsp_alloc(num_samp_1,num_iso_1,num_samp_2,num_iso_2)
  361. X    int num_samp_1,num_iso_1,num_samp_2,num_iso_2;
  362. X{
  363. X    struct surface_points *sp;
  364. X
  365. X    sp = (struct surface_points *) alloc((unsigned long)sizeof(struct surface_points), "surface");
  366. X    sp->next_sp = NULL;
  367. X    sp->title = NULL;
  368. X    sp->contours = NULL;
  369. X    sp->iso_crvs = NULL;
  370. X    sp->num_iso_read = 0;
  371. X
  372. X    if (num_iso_2 > 0 && num_samp_1 > 0) {
  373. X    int i;
  374. X    struct iso_curve *icrv;
  375. X
  376. X    for (i = 0; i < num_iso_1; i++) {
  377. X        icrv = iso_alloc(num_samp_2);
  378. X        icrv->next = sp->iso_crvs;
  379. X        sp->iso_crvs = icrv;
  380. X    }
  381. X    for (i = 0; i < num_iso_2; i++) {
  382. X        icrv = iso_alloc(num_samp_1);
  383. X        icrv->next = sp->iso_crvs;
  384. X        sp->iso_crvs = icrv;
  385. X    }
  386. X    } else
  387. X    sp->iso_crvs = (struct iso_curve *) NULL;
  388. X
  389. X    return(sp);
  390. X}
  391. X
  392. X/*
  393. X * sp_replace() updates a surface_points structure so it can hold 'num_iso_1'
  394. X * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
  395. X * 'num_samp_1' samples.
  396. X * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
  397. X */
  398. Xsp_replace(sp,num_samp_1,num_iso_1,num_samp_2,num_iso_2)
  399. X       struct surface_points *sp;
  400. X       int num_samp_1,num_iso_1,num_samp_2,num_iso_2;
  401. X{
  402. X    int i;
  403. X    struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  404. X
  405. X    while ( icrvs ) {
  406. X    icrv = icrvs;
  407. X    icrvs = icrvs->next;
  408. X    iso_free( icrv );
  409. X    }
  410. X    sp->iso_crvs = NULL;
  411. X    
  412. X    if (num_iso_2 > 0 && num_samp_1 > 0) {
  413. X    for (i = 0; i < num_iso_1; i++) {
  414. X        icrv = iso_alloc(num_samp_2);
  415. X        icrv->next = sp->iso_crvs;
  416. X        sp->iso_crvs = icrv;
  417. X    }
  418. X    for (i = 0; i < num_iso_2; i++) {
  419. X        icrv = iso_alloc(num_samp_1);
  420. X        icrv->next = sp->iso_crvs;
  421. X        sp->iso_crvs = icrv;
  422. X    }
  423. X    } else
  424. X    sp->iso_crvs = (struct iso_curve *) NULL;
  425. X}
  426. X
  427. X/*
  428. X * sp_free() releases any memory which was previously malloc()'d to hold
  429. X *   surface points.
  430. X */
  431. Xsp_free(sp)
  432. Xstruct surface_points *sp;
  433. X{
  434. X    if (sp) {
  435. X        sp_free(sp->next_sp);
  436. X        if (sp->title)
  437. X            free((char *)sp->title);
  438. X        if (sp->contours) {
  439. X            struct gnuplot_contours *cntr, *cntrs = sp->contours;
  440. X
  441. X            while (cntrs) {
  442. X                cntr = cntrs;
  443. X                cntrs = cntrs->next;
  444. X                gpfarfree(cntr->coords);
  445. X                free(cntr);
  446. X            }
  447. X        }
  448. X        if (sp->iso_crvs) {
  449. X            struct iso_curve *icrv, *icrvs = sp->iso_crvs;
  450. X
  451. X            while (icrvs) {
  452. X                icrv = icrvs;
  453. X                icrvs = icrvs->next;
  454. X                iso_free(icrv);
  455. X            }
  456. X        }
  457. X        free((char *)sp);
  458. X    }
  459. X}
  460. X
  461. X
  462. X
  463. Xsave_functions(fp)
  464. XFILE *fp;
  465. X{
  466. Xregister struct udft_entry *udf = first_udf;
  467. X
  468. X    if (fp) {
  469. X        while (udf) {
  470. X            if (udf->definition)
  471. X                fprintf(fp,"%s\n",udf->definition);
  472. X            udf = udf->next_udf;
  473. X        }
  474. X        (void) fclose(fp);
  475. X    } else
  476. X        os_error("Cannot open save file",c_token);            
  477. X}
  478. X
  479. X
  480. Xsave_variables(fp)
  481. XFILE *fp;
  482. X{
  483. Xregister struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  484. X
  485. X    if (fp) {
  486. X        while (udv) {
  487. X            if (!udv->udv_undef) {
  488. X                fprintf(fp,"%s = ",udv->udv_name);
  489. X                disp_value(fp,&(udv->udv_value));
  490. X                (void) putc('\n',fp);
  491. X            }
  492. X            udv = udv->next_udv;
  493. X        }
  494. X        (void) fclose(fp);
  495. X    } else
  496. X        os_error("Cannot open save file",c_token);            
  497. X}
  498. X
  499. X
  500. Xsave_all(fp)
  501. XFILE *fp;
  502. X{
  503. Xregister struct udft_entry *udf = first_udf;
  504. Xregister struct udvt_entry *udv = first_udv->next_udv;    /* skip pi */
  505. X
  506. X    if (fp) {
  507. X        save_set_all(fp);
  508. X        while (udf) {
  509. X            if (udf->definition)
  510. X                fprintf(fp,"%s\n",udf->definition);
  511. X            udf = udf->next_udf;
  512. X        }
  513. X        while (udv) {
  514. X            if (!udv->udv_undef) {
  515. X                fprintf(fp,"%s = ",udv->udv_name);
  516. X                disp_value(fp,&(udv->udv_value));
  517. X                (void) putc('\n',fp);
  518. X            }
  519. X            udv = udv->next_udv;
  520. X        }
  521. X        fprintf(fp,"%s\n",replot_line);
  522. X        (void) fclose(fp);
  523. X    } else
  524. X        os_error("Cannot open save file",c_token);            
  525. X}
  526. X
  527. X
  528. Xsave_set(fp)
  529. XFILE *fp;
  530. X{
  531. X    if (fp) {
  532. X        save_set_all(fp);
  533. X        (void) fclose(fp);
  534. X    } else
  535. X        os_error("Cannot open save file",c_token);            
  536. X}
  537. X
  538. X
  539. Xsave_set_all(fp)
  540. XFILE *fp;
  541. X{
  542. Xstruct text_label *this_label;
  543. Xstruct arrow_def *this_arrow;
  544. Xchar *quote;
  545. X    fprintf(fp,"set terminal %s %s\n", term_tbl[term].name, term_options);
  546. X    fprintf(fp,"set output %s\n",strcmp(outstr,"STDOUT")? outstr : "" );
  547. X    fprintf(fp,"set %sclip points\n", (clip_points)? "" : "no");
  548. X    fprintf(fp,"set %sclip one\n", (clip_lines1)? "" : "no");
  549. X    fprintf(fp,"set %sclip two\n", (clip_lines2)? "" : "no");
  550. X    fprintf(fp,"set %sborder\n",draw_border ? "" : "no");
  551. X    if (boxwidth<0.0)
  552. X        fprintf(fp,"set boxwidth\n");
  553. X    else
  554. X        fprintf(fp,"set boxwidth %g\n",boxwidth);
  555. X    if (dgrid3d)
  556. X        fprintf(fp,"set dgrid3d %d,%d, %d\n",
  557. X            dgrid3d_row_fineness,
  558. X            dgrid3d_col_fineness,
  559. X            dgrid3d_norm_value);
  560. X
  561. X    fprintf(fp,"set dummy %s,%s\n",dummy_var[0], dummy_var[1]);
  562. X    fprintf(fp,"set format x \"%s\"\n", xformat);
  563. X    fprintf(fp,"set format y \"%s\"\n", yformat);
  564. X    fprintf(fp,"set format z \"%s\"\n", zformat);
  565. X    fprintf(fp,"set %sgrid\n", (grid)? "" : "no");
  566. X    switch (key) {
  567. X        case -1 :
  568. X            fprintf(fp,"set key\n");
  569. X            break;
  570. X        case 0 :
  571. X            fprintf(fp,"set nokey\n");
  572. X            break;
  573. X        case 1 :
  574. X            fprintf(fp,"set key %g,%g,%g\n",key_x,key_y,key_z);
  575. X            break;
  576. X    }
  577. X    fprintf(fp,"set nolabel\n");
  578. X    for (this_label = first_label; this_label != NULL;
  579. X            this_label = this_label->next) {
  580. X        fprintf(fp,"set label %d \"%s\" at %g,%g,%g ",
  581. X               this_label->tag,
  582. X               this_label->text, this_label->x,
  583. X                         this_label->y,
  584. X                         this_label->z);
  585. X        switch(this_label->pos) {
  586. X            case LEFT :
  587. X                fprintf(fp,"left");
  588. X                break;
  589. X            case CENTRE :
  590. X                fprintf(fp,"centre");
  591. X                break;
  592. X            case RIGHT :
  593. X                fprintf(fp,"right");
  594. X                break;
  595. X        }
  596. X        fputc('\n',fp);
  597. X    }
  598. X    fprintf(fp,"set noarrow\n");
  599. X    for (this_arrow = first_arrow; this_arrow != NULL;
  600. X            this_arrow = this_arrow->next) {
  601. X        fprintf(fp,"set arrow %d from %g,%g,%g to %g,%g,%g%s\n",
  602. X               this_arrow->tag,
  603. X               this_arrow->sx, this_arrow->sy, this_arrow->sz,
  604. X               this_arrow->ex, this_arrow->ey, this_arrow->ez,
  605. X               this_arrow->head ? "" : " nohead");
  606. X    }
  607. X    fprintf(fp,"set nologscale\n");
  608. X    if (is_log_x) fprintf(fp,"set logscale x %g\n", base_log_x);
  609. X    if (is_log_y) fprintf(fp,"set logscale y %g\n", base_log_y);
  610. X    if (is_log_z) fprintf(fp,"set logscale z %g\n", base_log_z);
  611. X    fprintf(fp,"set offsets %g, %g, %g, %g\n",loff,roff,toff,boff);
  612. X    fprintf(fp,"set %spolar\n", (polar)? "" : "no");
  613. X    fprintf(fp,"set angles %s\n", (angles_format == ANGLES_RADIANS)?
  614. X                        "radians" : "degrees");
  615. X    fprintf(fp,"set %sparametric\n", (parametric)? "" : "no");
  616. X    fprintf(fp,"set view %g, %g, %g, %g\n",
  617. X        surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  618. X    fprintf(fp,"set samples %d, %d\n",samples_1,samples_2);
  619. X    fprintf(fp,"set isosamples %d, %d\n",iso_samples_1,iso_samples_2);
  620. X    fprintf(fp,"set %ssurface\n",(draw_surface) ? "" : "no");
  621. X    fprintf(fp,"set %scontour",(draw_contour) ? "" : "no");
  622. X    switch (draw_contour) {
  623. X        case CONTOUR_NONE: fprintf(fp, "\n"); break;
  624. X        case CONTOUR_BASE: fprintf(fp, " base\n"); break;
  625. X        case CONTOUR_SRF:  fprintf(fp, " surface\n"); break;
  626. X        case CONTOUR_BOTH: fprintf(fp, " both\n"); break;
  627. X    }
  628. X     fprintf(fp,"set %sclabel\n",(label_contours) ? "" : "no");
  629. X    fprintf(fp,"set %shidden3d\n",(hidden3d) ? "" : "no");
  630. X    fprintf(fp,"set cntrparam order %d\n", contour_order);
  631. X    fprintf(fp,"set cntrparam ");
  632. X    switch (contour_kind) {
  633. X        case CONTOUR_KIND_LINEAR:    fprintf(fp, "linear\n"); break;
  634. X        case CONTOUR_KIND_CUBIC_SPL: fprintf(fp, "cubicspline\n"); break;
  635. X        case CONTOUR_KIND_BSPLINE:   fprintf(fp, "bspline\n"); break;
  636. X    }
  637. X    fprintf(fp,"set cntrparam levels ");
  638. X    switch (levels_kind) {
  639. X        int i;
  640. X        case LEVELS_AUTO:
  641. X            fprintf(fp, "auto %d\n", contour_levels);
  642. X            break;
  643. X        case LEVELS_INCREMENTAL:
  644. X            fprintf(fp, "incremental %g,%g,%g\n",
  645. X                levels_list[0], levels_list[1], 
  646. X                levels_list[0]+levels_list[1]*contour_levels);
  647. X            break;
  648. X        case LEVELS_DISCRETE:
  649. X            fprintf(fp, "discrete ");
  650. X                fprintf(fp, "%g", levels_list[0]);
  651. X            for(i = 1; i < contour_levels; i++)
  652. X                fprintf(fp, ",%g ", levels_list[i]);
  653. X            fprintf(fp, "\n");
  654. X    }
  655. X    fprintf(fp,"set cntrparam points %d\n", contour_pts);
  656. X    fprintf(fp,"set size %g,%g\n",xsize,ysize);
  657. X    fprintf(fp,"set data style ");
  658. X    switch (data_style) {
  659. X        case LINES: fprintf(fp,"lines\n"); break;
  660. X        case POINTSTYLE: fprintf(fp,"points\n"); break;
  661. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  662. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  663. X        case DOTS: fprintf(fp,"dots\n"); break;
  664. X        case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  665. X        case BOXES: fprintf(fp,"boxes\n"); break;
  666. X        case BOXERROR: fprintf(fp,"boxerrorbars\n"); break;
  667. X        case STEPS: fprintf(fp,"steps\n"); break;       /* JG */
  668. X    }
  669. X    fprintf(fp,"set function style ");
  670. X    switch (func_style) {
  671. X        case LINES: fprintf(fp,"lines\n"); break;
  672. X        case POINTSTYLE: fprintf(fp,"points\n"); break;
  673. X        case IMPULSES: fprintf(fp,"impulses\n"); break;
  674. X        case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
  675. X        case DOTS: fprintf(fp,"dots\n"); break;
  676. X        case ERRORBARS: fprintf(fp,"errorbars\n"); break;
  677. X        case BOXES: fprintf(fp,"boxes\n"); break;
  678. X        case BOXERROR: fprintf(fp,"boxerrorbars\n"); break;
  679. X        case STEPS: fprintf(fp,"steps\n"); break;       /* JG */
  680. X    }
  681. X        fprintf(fp,"set %sxzeroaxis\n", (xzeroaxis)? "" : "no");
  682. X        fprintf(fp,"set %syzeroaxis\n", (yzeroaxis)? "" : "no");
  683. X        fprintf(fp,"set tics %s\n", (tic_in)? "in" : "out");
  684. X        fprintf(fp,"set ticslevel %g\n", ticslevel);
  685. X        save_tics(fp, xtics, 'x', &xticdef);
  686. X        save_tics(fp, ytics, 'y', &yticdef);
  687. X        save_tics(fp, ztics, 'z', &zticdef);
  688. X        for (quote = &(title[0]); quote && *quote && (*quote != '"'); quote++)
  689. X            ;
  690. X        fprintf(fp,"set title %c%s%c %d,%d\n",*quote ? '\'' : '"',title,*quote ? '\'' : '"',title_xoffset,title_yoffset);
  691. X    
  692. X        if (timedate)
  693. X        fprintf(fp,"set time %d,%d\n",time_xoffset,time_yoffset);
  694. X    else
  695. X        fprintf(fp,"set notime\n");
  696. X     fprintf(fp,"set rrange [%g : %g]\n",rmin,rmax);
  697. X    fprintf(fp,"set trange [%g : %g]\n",tmin,tmax);
  698. X    fprintf(fp,"set urange [%g : %g]\n",umin,umax);
  699. X    fprintf(fp,"set vrange [%g : %g]\n",vmin,vmax);
  700. X        for (quote = &(xlabel[0]); quote && *quote && (*quote != '"'); quote++)
  701. X            ;
  702. X        fprintf(fp,"set xlabel %c%s%c %d,%d\n",*quote ? '\'' : '"',xlabel,*quote ? '\'' : '"',xlabel_xoffset,xlabel_yoffset);
  703. X        fprintf(fp,"set xrange [%g : %g]\n",xmin,xmax);
  704. X        for (quote = &(ylabel[0]); quote && *quote && (*quote != '"'); quote++)
  705. X            ;
  706. X        fprintf(fp,"set ylabel %c%s%c %d,%d\n",*quote ? '\'' : '"',ylabel,*quote ? '\'' : '"',ylabel_xoffset,ylabel_yoffset);
  707. X        fprintf(fp,"set yrange [%g : %g]\n",ymin,ymax);
  708. X        for (quote = &(zlabel[0]); quote && *quote && (*quote != '"'); quote++)
  709. X            ;
  710. X        fprintf(fp,"set zlabel %c%s%c %d,%d\n",*quote ? '\'' : '"',zlabel,*quote ? '\'' : '"',zlabel_xoffset,zlabel_yoffset);
  711. X    fprintf(fp,"set zrange [%g : %g]\n",zmin,zmax);
  712. X    fprintf(fp,"set %s %c\n", 
  713. X        autoscale_r ? "autoscale" : "noautoscale", 'r');
  714. X    fprintf(fp,"set %s %c\n", 
  715. X        autoscale_t ? "autoscale" : "noautoscale", 't');
  716. X    fprintf(fp,"set %s %c%c\n", 
  717. X        (autoscale_y||autoscale_x) ? "autoscale" : "noautoscale", 
  718. X        autoscale_x ? 'x' : ' ', autoscale_y ? 'y' : ' ');
  719. X    fprintf(fp,"set %s %c\n", 
  720. X        autoscale_z ? "autoscale" : "noautoscale", 'z');
  721. X    fprintf(fp,"set zero %g\n",zero);
  722. X}
  723. X
  724. Xsave_tics(fp, onoff, axis, tdef)
  725. X    FILE *fp;
  726. X    TBOOLEAN onoff;
  727. X    char axis;
  728. X    struct ticdef *tdef;
  729. X{
  730. X    if (onoff) {
  731. X       fprintf(fp,"set %ctics", axis);
  732. X       switch(tdef->type) {
  733. X          case TIC_COMPUTED: {
  734. X             break;
  735. X          }
  736. X          case TIC_MONTH:{
  737. X              fprintf(fp,"\nset %cmtics",axis);
  738. X            break;
  739. X          }
  740. X            case TIC_DAY:{
  741. X            fprintf(fp,"\nset %cdtics",axis);
  742. X            break;
  743. X            }
  744. X          case TIC_SERIES: {
  745. X                 if (tdef->def.series.end >= VERYLARGE)
  746. X                 fprintf(fp, " %g,%g", tdef->def.series.start,
  747. X                                        tdef->def.series.incr);
  748. X                         else
  749. X                 fprintf(fp, " %g,%g,%g", tdef->def.series.start,
  750. X                                        tdef->def.series.incr, tdef->def.series.end);
  751. X             break;
  752. X          }
  753. X          case TIC_USER: {
  754. X             register struct ticmark *t;
  755. X             fprintf(fp, " (");
  756. X             for (t = tdef->def.user; t != NULL; t=t->next) {
  757. X                if (t->label)
  758. X                  fprintf(fp, "\"%s\" ", t->label);
  759. X                if (t->next)
  760. X                  fprintf(fp, "%g, ", t->position);
  761. X                else
  762. X                  fprintf(fp, "%g", t->position);
  763. X             }
  764. X             fprintf(fp, ")");
  765. X             break;
  766. X          } 
  767. X       }
  768. X       fprintf(fp, "\n");
  769. X    } else {
  770. X       fprintf(fp,"set no%ctics\n", axis);
  771. X    }
  772. X}
  773. X
  774. Xload_file(fp, name)
  775. X    FILE *fp;
  776. X    char *name;
  777. X{
  778. X    register int len;
  779. X    extern char input_line[];
  780. X
  781. X    int start, left;
  782. X    int more;
  783. X    int stop = FALSE;
  784. X
  785. X    lf_push(fp);            /* save state for errors and recursion */
  786. X
  787. X    if (fp == (FILE *)NULL) {
  788. X       char errbuf[BUFSIZ];
  789. X       (void) sprintf(errbuf, "Cannot open load file '%s'", name);
  790. X       os_error(errbuf, c_token);
  791. X    } else {
  792. X       /* go into non-interactive mode during load */
  793. X       /* will be undone below, or in load_file_error */
  794. X       interactive = FALSE;
  795. X       inline_num = 0;
  796. X       infile_name = name;
  797. X
  798. X       while (!stop) {        /* read all commands in file */
  799. X          /* read one command */
  800. X          left = MAX_LINE_LEN;
  801. X          start = 0;
  802. X          more = TRUE;
  803. X
  804. X          while (more) {
  805. X             if (fgets(&(input_line[start]), left, fp) == (char *)NULL) {
  806. X                stop = TRUE; /* EOF in file */
  807. X                input_line[start] = '\0';
  808. X                more = FALSE;    
  809. X             } else {
  810. X                inline_num++;
  811. X                len = strlen(input_line) - 1;
  812. X                if (input_line[len] == '\n') { /* remove any newline */
  813. X                    input_line[len] = '\0';
  814. X                    /* Look, len was 1-1 = 0 before, take care here! */
  815. X                    if (len > 0) --len;
  816. X                } else if (len+1 >= left)
  817. X                  int_error("Input line too long",NO_CARET);
  818. X                 
  819. X                if (input_line[len] == '\\') { /* line continuation */
  820. X                    start = len;
  821. X                    left  = MAX_LINE_LEN - start; /* left -=len;*/
  822. X                } else
  823. X                  more = FALSE;
  824. X             }
  825. X          }
  826. X
  827. X          if (strlen(input_line) > 0) {
  828. X             screen_ok = FALSE;    /* make sure command line is
  829. X                               echoed on error */
  830. X             do_line();
  831. X          }
  832. X       }
  833. X    }
  834. X
  835. X    /* pop state */
  836. X    (void) lf_pop();        /* also closes file fp */
  837. X}
  838. X
  839. X/* pop from load_file state stack */
  840. Xstatic TBOOLEAN                /* FALSE if stack was empty */
  841. Xlf_pop()                    /* called by load_file and load_file_error */
  842. X{
  843. X    LFS *lf;
  844. X
  845. X    if (lf_head == NULL)
  846. X     return(FALSE);
  847. X    else {
  848. X       lf = lf_head;
  849. X       if (lf->fp != (FILE *)NULL)
  850. X        (void) fclose(lf->fp);
  851. X       interactive = lf->interactive;
  852. X       inline_num = lf->inline_num;
  853. X       infile_name = lf->name;
  854. X       lf_head = lf->prev;
  855. X       free((char *)lf);
  856. X       return(TRUE);
  857. X    }
  858. X}
  859. X
  860. X/* push onto load_file state stack */
  861. X/* essentially, we save information needed to undo the load_file changes */
  862. Xstatic void
  863. Xlf_push(fp)            /* called by load_file */
  864. X    FILE *fp;
  865. X{
  866. X    LFS *lf;
  867. X    
  868. X    lf = (LFS *)alloc((unsigned long)sizeof(LFS), (char *)NULL);
  869. X    if (lf == (LFS *)NULL) {
  870. X       if (fp != (FILE *)NULL)
  871. X        (void) fclose(fp);        /* it won't be otherwise */
  872. X       int_error("not enough memory to load file", c_token);
  873. X    }
  874. X     
  875. X    lf->fp = fp;            /* save this file pointer */
  876. X    lf->name = infile_name;    /* save current name */
  877. X    lf->interactive = interactive;    /* save current state */
  878. X    lf->inline_num = inline_num; /* save current line number */
  879. X    lf->prev = lf_head;        /* link to stack */
  880. X    lf_head = lf;
  881. X}
  882. X
  883. XFILE *lf_top()        /* used for reread  vsnyder@math.jpl.nasa.gov */
  884. X{   if (lf_head == (LFS *) NULL) return((FILE *)NULL);
  885. X    return(lf_head->fp);
  886. X}
  887. X
  888. X
  889. Xload_file_error()            /* called from main */
  890. X{
  891. X    /* clean up from error in load_file */
  892. X    /* pop off everything on stack */
  893. X    while(lf_pop())
  894. X     ;
  895. X}
  896. X
  897. X/* find char c in string str; return p such that str[p]==c;
  898. X * if c not in str then p=strlen(str)
  899. X */
  900. Xint
  901. Xinstring(str, c)
  902. X    char *str;
  903. X    char c;
  904. X{
  905. X    int pos = 0;
  906. X
  907. X    while (str != NULL && *str != '\0' && c != *str) {
  908. X       str++; 
  909. X       pos++;
  910. X    }
  911. X    return (pos);
  912. X}
  913. X
  914. Xshow_functions()
  915. X{
  916. Xregister struct udft_entry *udf = first_udf;
  917. X
  918. X    fprintf(stderr,"\n\tUser-Defined Functions:\n");
  919. X
  920. X    while (udf) {
  921. X        if (udf->definition)
  922. X            fprintf(stderr,"\t%s\n",udf->definition);
  923. X        else
  924. X            fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
  925. X        udf = udf->next_udf;
  926. X    }
  927. X}
  928. X
  929. X
  930. Xshow_at()
  931. X{
  932. X    (void) putc('\n',stderr);
  933. X    disp_at(temp_at(),0);
  934. X}
  935. X
  936. X
  937. Xdisp_at(curr_at, level)
  938. Xstruct at_type *curr_at;
  939. Xint level;
  940. X{
  941. Xregister int i, j;
  942. Xregister union argument *arg;
  943. X
  944. X    for (i = 0; i < curr_at->a_count; i++) {
  945. X        (void) putc('\t',stderr);
  946. X        for (j = 0; j < level; j++)
  947. X            (void) putc(' ',stderr);    /* indent */
  948. X
  949. X            /* print name of instruction */
  950. X
  951. X        fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
  952. X        arg = &(curr_at->actions[i].arg);
  953. X
  954. X            /* now print optional argument */
  955. X
  956. X        switch(curr_at->actions[i].index) {
  957. X          case PUSH:    fprintf(stderr," %s\n", arg->udv_arg->udv_name);
  958. X                    break;
  959. X          case PUSHC:    (void) putc(' ',stderr);
  960. X                    disp_value(stderr,&(arg->v_arg));
  961. X                    (void) putc('\n',stderr);
  962. X                    break;
  963. X          case PUSHD1:    fprintf(stderr," %c dummy\n",
  964. X                      arg->udf_arg->udf_name[0]);
  965. X                    break;
  966. X          case PUSHD2:    fprintf(stderr," %c dummy\n",
  967. X                      arg->udf_arg->udf_name[1]);
  968. X                    break;
  969. X          case CALL:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  970. X                    if(level < 6) {
  971. X                    if (arg->udf_arg->at) {
  972. X                        (void) putc('\n',stderr);
  973. X                        disp_at(arg->udf_arg->at,level+2); /* recurse! */
  974. X                    } else
  975. X                        fputs(" (undefined)\n",stderr);
  976. X                    } else
  977. X                        (void) putc('\n',stderr);
  978. X                    break;
  979. X          case CALLN:    fprintf(stderr," %s", arg->udf_arg->udf_name);
  980. X                    if(level < 6) {
  981. X                    if (arg->udf_arg->at) {
  982. X                        (void) putc('\n',stderr);
  983. X                        disp_at(arg->udf_arg->at,level+2); /* recurse! */
  984. X                    } else
  985. X                        fputs(" (undefined)\n",stderr);
  986. X                    } else
  987. X                        (void) putc('\n',stderr);
  988. X                    break;
  989. X          case JUMP:
  990. X          case JUMPZ:
  991. X          case JUMPNZ:
  992. X          case JTERN:
  993. X                    fprintf(stderr," +%d\n",arg->j_arg);
  994. X                    break;
  995. X          default:
  996. X                    (void) putc('\n',stderr);
  997. X        }
  998. X    }
  999. X}
  1000. END_OF_FILE
  1001.   if test 25786 -ne `wc -c <'gnuplot/misc.c'`; then
  1002.     echo shar: \"'gnuplot/misc.c'\" unpacked with wrong size!
  1003.   fi
  1004.   # end of 'gnuplot/misc.c'
  1005. fi
  1006. if test -f 'gnuplot/win/wtext.c' -a "${1}" != "-c" ; then 
  1007.   echo shar: Will not clobber existing file \"'gnuplot/win/wtext.c'\"
  1008. else
  1009.   echo shar: Extracting \"'gnuplot/win/wtext.c'\" \(49542 characters\)
  1010.   sed "s/^X//" >'gnuplot/win/wtext.c' <<'END_OF_FILE'
  1011. X#ifndef lint
  1012. Xstatic char *RCSid = "$Id: wtext.c%v 3.50.1.13 1993/08/19 03:21:26 woo Exp $";
  1013. X#endif
  1014. X
  1015. X/* GNUPLOT - win/wtext.c */
  1016. X/*
  1017. X * Copyright (C) 1992   Russell Lang
  1018. X *
  1019. X * Permission to use, copy, and distribute this software and its
  1020. X * documentation for any purpose with or without fee is hereby granted, 
  1021. X * provided that the above copyright notice appear in all copies and 
  1022. X * that both that copyright notice and this permission notice appear 
  1023. X * in supporting documentation.
  1024. X *
  1025. X * Permission to modify the software is granted, but not the right to
  1026. X * distribute the modified code.  Modifications are to be distributed 
  1027. X * as patches to released version.
  1028. X *  
  1029. X * This software is provided "as is" without express or implied warranty.
  1030. X * 
  1031. X *
  1032. X * AUTHORS
  1033. X * 
  1034. X *   Russell Lang
  1035. X * 
  1036. X * Send your comments or suggestions to 
  1037. X *  info-gnuplot@dartmouth.edu.
  1038. X * This is a mailing list; to join it send a note to 
  1039. X *  info-gnuplot-request@dartmouth.edu.  
  1040. X * Send bug reports to
  1041. X *  bug-gnuplot@dartmouth.edu.
  1042. X */
  1043. X
  1044. X/* WARNING: Do not write to stdout/stderr with functions not listed 
  1045. X   in win/wtext.h */
  1046. X
  1047. X#define STRICT
  1048. X#include <windows.h>
  1049. X#include <windowsx.h>
  1050. X#if WINVER >= 0x030a
  1051. X#include <commdlg.h>
  1052. X#endif
  1053. X#include <string.h>    /* use only far items */
  1054. X#ifndef __MSC__
  1055. X#include <mem.h>
  1056. X#endif
  1057. X#include <stdlib.h>
  1058. X#include <ctype.h>
  1059. X#include <dos.h>
  1060. X
  1061. X#include "wgnuplib.h"
  1062. X#include "wresourc.h"
  1063. X#include "wcommon.h"
  1064. X
  1065. X/* font stuff */
  1066. X#define TEXTFONTSIZE 9
  1067. X#define TEXTFONTNAME "Terminal"
  1068. X
  1069. X#define EOF -1        /* instead of using <stdio.h> */
  1070. X/* limits */
  1071. X#define MAXSTR 256
  1072. XPOINT ScreenMinSize = {16,4};
  1073. XLRESULT CALLBACK _export WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  1074. XLRESULT CALLBACK _export WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  1075. Xvoid ReadTextIni(LPTW lptw);
  1076. Xvoid LimitMark(LPTW lptw, POINT FAR *lppt);
  1077. X
  1078. Xchar szNoMemory[] = "out of memory";
  1079. XCOLORREF TextColorTable[16] = { 
  1080. X    RGB(0,0,0),            /* black */
  1081. X    RGB(0,0,128),        /* dark blue */
  1082. X    RGB(0,128,0),        /* dark green */
  1083. X    RGB(0,128,128),        /* dark cyan */
  1084. X    RGB(128,0,0),        /* dark red */
  1085. X    RGB(128,0,128),        /* dark magenta */
  1086. X    RGB(128,128,0),        /* dark yellow */
  1087. X    RGB(128,128,128),    /* dark grey */
  1088. X    RGB(192,192,192),    /* light grey */
  1089. X    RGB(0,0,255),        /* blue */
  1090. X    RGB(0,255,0),        /* green */
  1091. X    RGB(0,255,255),        /* cyan */
  1092. X    RGB(255,0,0),        /* red */
  1093. X    RGB(255,0,255),        /* magenta */
  1094. X    RGB(255,255,0),        /* yellow */
  1095. X    RGB(255,255,255),    /* white */
  1096. X};
  1097. X#define NOTEXT 0xF0
  1098. X#define MARKFORE RGB(255,255,255)
  1099. X#define MARKBACK RGB(0,0,128)
  1100. X#define TextFore(attr) TextColorTable[(attr) & 15]
  1101. X#define TextBack(attr) TextColorTable[(attr>>4) & 15]
  1102. X
  1103. X
  1104. Xvoid WDPROC
  1105. XTextMessage(void)
  1106. X{
  1107. X    MSG msg;
  1108. X
  1109. X    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  1110. X        {
  1111. X        TranslateMessage(&msg);
  1112. X        DispatchMessage(&msg);
  1113. X        }
  1114. X    return;
  1115. X}
  1116. X
  1117. X
  1118. X
  1119. Xvoid
  1120. XCreateTextClass(LPTW lptw)
  1121. X{
  1122. XWNDCLASS wndclass;
  1123. X    wndclass.style = CS_HREDRAW | CS_VREDRAW;
  1124. X    wndclass.lpfnWndProc = WndTextProc;
  1125. X    wndclass.cbClsExtra = 0;
  1126. X    wndclass.cbWndExtra = 2 * sizeof(void FAR *);
  1127. X    wndclass.hInstance = lptw->hInstance;
  1128. X    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1129. X    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1130. X    wndclass.hbrBackground = NULL;
  1131. X    lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ? 
  1132. X        GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
  1133. X    wndclass.lpszMenuName = NULL;
  1134. X    wndclass.lpszClassName = szTextClass;
  1135. X    RegisterClass(&wndclass);
  1136. X
  1137. X    wndclass.style = CS_HREDRAW | CS_VREDRAW;
  1138. X    wndclass.lpfnWndProc = WndParentProc;
  1139. X    wndclass.cbClsExtra = 0;
  1140. X    wndclass.cbWndExtra = 2 * sizeof(void FAR *);
  1141. X    wndclass.hInstance = lptw->hInstance;
  1142. X    if (lptw->hIcon)
  1143. X        wndclass.hIcon = lptw->hIcon;
  1144. X    else
  1145. X        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1146. X    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1147. X    wndclass.hbrBackground = GetStockBrush(WHITE_BRUSH);
  1148. X    wndclass.lpszMenuName = NULL;
  1149. X    wndclass.lpszClassName = szParentClass;
  1150. X    RegisterClass(&wndclass);
  1151. X}
  1152. X
  1153. X
  1154. X/* make text window */
  1155. Xint WDPROC
  1156. XTextInit(LPTW lptw)
  1157. X{
  1158. X    RECT rect;
  1159. X    HMENU sysmenu;
  1160. X    HGLOBAL hglobal;
  1161. X    char buf[80];
  1162. X    
  1163. X    ReadTextIni(lptw);
  1164. X
  1165. X    if (!lptw->hPrevInstance)
  1166. X        CreateTextClass(lptw);
  1167. X
  1168. X    if (lptw->KeyBufSize == 0)
  1169. X        lptw->KeyBufSize = 256;
  1170. X
  1171. X    if (lptw->ScreenSize.x < ScreenMinSize.x)
  1172. X        lptw->ScreenSize.x = ScreenMinSize.x;
  1173. X    if (lptw->ScreenSize.y < ScreenMinSize.y)
  1174. X        lptw->ScreenSize.y = ScreenMinSize.y;
  1175. X
  1176. X    lptw->CursorPos.x = lptw->CursorPos.y = 0;
  1177. X    lptw->bFocus = FALSE;
  1178. X    lptw->bGetCh = FALSE;
  1179. X    lptw->CaretHeight = 0;
  1180. X    if (!lptw->nCmdShow)
  1181. X        lptw->nCmdShow = SW_SHOWNORMAL;
  1182. X    if (!lptw->Attr)
  1183. X        lptw->Attr = 0xf0;    /* black on white */
  1184. X
  1185. X    hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
  1186. X    lptw->ScreenBuffer = (BYTE FAR *)GlobalLock(hglobal);
  1187. X    if (lptw->ScreenBuffer == (BYTE FAR *)NULL) {
  1188. X        MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  1189. X        return(1);
  1190. X    }
  1191. X    _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x * lptw->ScreenSize.y);
  1192. X    hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
  1193. X    lptw->AttrBuffer = (BYTE FAR *)GlobalLock(hglobal);
  1194. X    if (lptw->AttrBuffer == (BYTE FAR *)NULL) {
  1195. X        MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  1196. X        return(1);
  1197. X    }
  1198. X    _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x * lptw->ScreenSize.y);
  1199. X    hglobal = GlobalAlloc(LHND, lptw->KeyBufSize);
  1200. X    lptw->KeyBuf = (BYTE FAR *)GlobalLock(hglobal);
  1201. X    if (lptw->KeyBuf == (BYTE FAR *)NULL) {
  1202. X        MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  1203. X        return(1);
  1204. X    }
  1205. X    lptw->KeyBufIn = lptw->KeyBufOut = lptw->KeyBuf;
  1206. X
  1207. X    lptw->hWndParent = CreateWindow(szParentClass, lptw->Title,
  1208. X          WS_OVERLAPPEDWINDOW,
  1209. X          lptw->Origin.x, lptw->Origin.y,
  1210. X          lptw->Size.x, lptw->Size.y,
  1211. X          NULL, NULL, lptw->hInstance, lptw);
  1212. X    if (lptw->hWndParent == (HWND)NULL) {
  1213. X        MessageBox((HWND)NULL,"Couldn't open parent text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  1214. X        return(1);
  1215. X    }
  1216. X    ShowWindow(lptw->hWndParent, lptw->nCmdShow);
  1217. X    GetClientRect(lptw->hWndParent, &rect);
  1218. X
  1219. X    lptw->hWndText = CreateWindow(szTextClass, lptw->Title,
  1220. X          WS_CHILD | WS_VSCROLL | WS_HSCROLL,
  1221. X          0, lptw->ButtonHeight,
  1222. X          rect.right, rect.bottom-lptw->ButtonHeight,
  1223. X          lptw->hWndParent, NULL, lptw->hInstance, lptw);
  1224. X    if (lptw->hWndText == (HWND)NULL) {
  1225. X        MessageBox((HWND)NULL,"Couldn't open text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  1226. X        return(1);
  1227. X    }
  1228. X
  1229. X    lptw->hPopMenu = CreatePopupMenu();
  1230. X    AppendMenu(lptw->hPopMenu, MF_STRING, M_COPY_CLIP, "&Copy to Clipboard");
  1231. X    AppendMenu(lptw->hPopMenu, MF_STRING, M_PASTE, "&Paste");
  1232. X#if WINVER >= 0x030a
  1233. X    AppendMenu(lptw->hPopMenu, MF_STRING, M_CHOOSE_FONT, "Choose &Font...");
  1234. X#endif
  1235. X    AppendMenu(lptw->hPopMenu, MF_STRING | (lptw->bSysColors ? MF_CHECKED : MF_UNCHECKED), 
  1236. X        M_SYSCOLORS, "&System Colors");
  1237. X    if (lptw->IniFile != (LPSTR)NULL) {
  1238. X        wsprintf(buf,"&Update %s",lptw->IniFile);
  1239. X        AppendMenu(lptw->hPopMenu, MF_STRING, M_WRITEINI, (LPSTR)buf);
  1240. X    }
  1241. X
  1242. X    sysmenu = GetSystemMenu(lptw->hWndParent,0);    /* get the sysmenu */
  1243. X    AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
  1244. X    AppendMenu(sysmenu, MF_POPUP, (UINT)lptw->hPopMenu, "&Options");
  1245. X    AppendMenu(sysmenu, MF_STRING, M_ABOUT, "&About");
  1246. X
  1247. X    if (lptw->lpmw)
  1248. X        LoadMacros(lptw);
  1249. X
  1250. X    ShowWindow(lptw->hWndText, SW_SHOWNORMAL);
  1251. X    BringWindowToTop(lptw->hWndText);
  1252. X    SetFocus(lptw->hWndText);
  1253. X    TextMessage();
  1254. X    return(0);
  1255. X}
  1256. X
  1257. X/* close a text window */
  1258. Xvoid WDPROC
  1259. XTextClose(LPTW lptw)
  1260. X{
  1261. X    HGLOBAL hglobal;
  1262. X
  1263. X    /* close window */
  1264. X    if (lptw->hWndParent)
  1265. X        DestroyWindow(lptw->hWndParent);
  1266. X    TextMessage();
  1267. X
  1268. X    hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->ScreenBuffer) );
  1269. X    if (hglobal) {
  1270. X        GlobalUnlock(hglobal);
  1271. X        GlobalFree(hglobal);
  1272. X    }
  1273. X    hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->AttrBuffer) );
  1274. X    if (hglobal) {
  1275. X        GlobalUnlock(hglobal);
  1276. X        GlobalFree(hglobal);
  1277. X    }
  1278. X    hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
  1279. X    if (hglobal) {
  1280. X        GlobalUnlock(hglobal);
  1281. X        GlobalFree(hglobal);
  1282. X    }
  1283. X
  1284. X    if (lptw->lpmw)
  1285. X        CloseMacros(lptw);
  1286. X    lptw->hWndParent = (HWND)NULL;
  1287. X}
  1288. X    
  1289. Xvoid
  1290. XWriteTextIni(LPTW lptw)
  1291. X{
  1292. X    RECT rect;
  1293. X    LPSTR file = lptw->IniFile;
  1294. X    LPSTR section = lptw->IniSection;
  1295. X    char profile[80];
  1296. X    int iconic;
  1297. X
  1298. X    
  1299. X    if ((file == (LPSTR)NULL) || (section == (LPSTR)NULL))
  1300. X        return;
  1301. X    
  1302. X    iconic = IsIconic(lptw->hWndParent);
  1303. X    if (iconic)
  1304. X        ShowWindow(lptw->hWndParent, SW_SHOWNORMAL);
  1305. X    GetWindowRect(lptw->hWndParent,&rect);
  1306. X    wsprintf(profile, "%d %d", rect.left, rect.top);
  1307. X    WritePrivateProfileString(section, "TextOrigin", profile, file);
  1308. X    wsprintf(profile, "%d %d", rect.right-rect.left, rect.bottom-rect.top);
  1309. X    WritePrivateProfileString(section, "TextSize", profile, file);
  1310. X    wsprintf(profile, "%d", iconic);
  1311. X    WritePrivateProfileString(section, "TextMinimized", profile, file);
  1312. X    wsprintf(profile, "%s,%d", lptw->fontname, lptw->fontsize);
  1313. X    WritePrivateProfileString(section, "TextFont", profile, file);
  1314. X    wsprintf(profile, "%d", lptw->bSysColors);
  1315. X    WritePrivateProfileString(section, "SysColors", profile, file);
  1316. X    if (iconic)
  1317. X        ShowWindow(lptw->hWndParent, SW_SHOWMINIMIZED);
  1318. X    return;
  1319. X}
  1320. X
  1321. Xvoid
  1322. XReadTextIni(LPTW lptw)
  1323. X{
  1324. X    LPSTR file = lptw->IniFile;
  1325. X    LPSTR section = lptw->IniSection;
  1326. X    char profile[81];
  1327. X    LPSTR p;
  1328. X    BOOL bOKINI;
  1329. X
  1330. X    bOKINI = (file != (LPSTR)NULL) && (section != (LPSTR)NULL);
  1331. X    profile[0] = '\0';
  1332. X
  1333. X    if (bOKINI)
  1334. X      GetPrivateProfileString(section, "TextOrigin", "", profile, 80, file);
  1335. X    if ( (p = GetInt(profile, &lptw->Origin.x)) == NULL)
  1336. X        lptw->Origin.x = CW_USEDEFAULT;
  1337. X    if ( (p = GetInt(p, &lptw->Origin.y)) == NULL)
  1338. X        lptw->Origin.y = CW_USEDEFAULT;
  1339. X    if ( (file != (LPSTR)NULL) && (section != (LPSTR)NULL) )
  1340. X      GetPrivateProfileString(section, "TextSize", "", profile, 80, file);
  1341. X    if ( (p = GetInt(profile, &lptw->Size.x)) == NULL)
  1342. X        lptw->Size.x = CW_USEDEFAULT;
  1343. X    if ( (p = GetInt(p, &lptw->Size.y)) == NULL)
  1344. X        lptw->Size.y = CW_USEDEFAULT;
  1345. X
  1346. X    if (bOKINI)
  1347. X      GetPrivateProfileString(section, "TextFont", "", profile, 80, file);
  1348. X    {
  1349. X        char FAR *size;
  1350. X        size = _fstrchr(profile,',');
  1351. X        if (size) {
  1352. X            *size++ = '\0';
  1353. X            if ( (p = GetInt(size, &lptw->fontsize)) == NULL)
  1354. X                lptw->fontsize = TEXTFONTSIZE;
  1355. X        }
  1356. X        _fstrcpy(lptw->fontname, profile);
  1357. X        if (lptw->fontsize == 0)
  1358. X            lptw->fontsize = TEXTFONTSIZE;
  1359. X        if (!(*lptw->fontname))
  1360. X            _fstrcpy(lptw->fontname,TEXTFONTNAME);
  1361. X    }
  1362. X
  1363. X    if (bOKINI) {
  1364. X        int iconic;
  1365. X        GetPrivateProfileString(section, "TextMinimized", "", profile, 80, file);
  1366. X        if ((p = GetInt(profile, &iconic)) == NULL)
  1367. X            iconic = 0;
  1368. X        if (iconic)
  1369. X            lptw->nCmdShow = SW_SHOWMINIMIZED;
  1370. X    }
  1371. X    lptw->bSysColors = FALSE;
  1372. X    GetPrivateProfileString(section, "SysColors", "", profile, 80, file);
  1373. X    if ((p = GetInt(profile, &lptw->bSysColors)) == NULL)
  1374. X        lptw->bSysColors = 0;
  1375. X}
  1376. X
  1377. X
  1378. X/* Bring Cursor into text window */
  1379. Xvoid WDPROC
  1380. XTextToCursor(LPTW lptw)
  1381. X{
  1382. Xint nXinc=0;
  1383. Xint nYinc=0;
  1384. Xint cxCursor;
  1385. Xint cyCursor;
  1386. X    cyCursor = lptw->CursorPos.y * lptw->CharSize.y;
  1387. X    if ( (cyCursor + lptw->CharSize.y > lptw->ScrollPos.y + lptw->ClientSize.y) 
  1388. X      || (cyCursor < lptw->ScrollPos.y) ) {
  1389. X        nYinc = max(0, cyCursor + lptw->CharSize.y - lptw->ClientSize.y) - lptw->ScrollPos.y;
  1390. X        nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
  1391. X    }
  1392. X    cxCursor = lptw->CursorPos.x * lptw->CharSize.x;
  1393. X    if ( (cxCursor + lptw->CharSize.x > lptw->ScrollPos.x + lptw->ClientSize.x)
  1394. X      || (cxCursor < lptw->ScrollPos.x) ) {
  1395. X        nXinc = max(0, cxCursor + lptw->CharSize.x - lptw->ClientSize.x/2) - lptw->ScrollPos.x;
  1396. X        nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
  1397. X    }
  1398. X    if (nYinc || nXinc) {
  1399. X        lptw->ScrollPos.y += nYinc;
  1400. X        lptw->ScrollPos.x += nXinc;
  1401. X        ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
  1402. X        SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
  1403. X        SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
  1404. X        UpdateWindow(lptw->hWndText);
  1405. X    }
  1406. X}
  1407. X
  1408. Xvoid
  1409. XNewLine(LPTW lptw)
  1410. X{
  1411. X    lptw->CursorPos.x = 0;
  1412. X    lptw->CursorPos.y++;
  1413. X    if (lptw->CursorPos.y >= lptw->ScreenSize.y) {
  1414. X        int i =  lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
  1415. X        _fmemmove(lptw->ScreenBuffer, lptw->ScreenBuffer+lptw->ScreenSize.x, i);
  1416. X        _fmemset(lptw->ScreenBuffer + i, ' ', lptw->ScreenSize.x);
  1417. X        _fmemmove(lptw->AttrBuffer, lptw->AttrBuffer+lptw->ScreenSize.x, i);
  1418. X        _fmemset(lptw->AttrBuffer + i, NOTEXT, lptw->ScreenSize.x);
  1419. X        lptw->CursorPos.y--;
  1420. X        ScrollWindow(lptw->hWndText,0,-lptw->CharSize.y,NULL,NULL);
  1421. X        lptw->MarkBegin.y--;
  1422. X        lptw->MarkEnd.y--;
  1423. X        LimitMark(lptw, &lptw->MarkBegin);
  1424. X        LimitMark(lptw, &lptw->MarkEnd);
  1425. X        UpdateWindow(lptw->hWndText);
  1426. X    }
  1427. X    if (lptw->CursorFlag)
  1428. X        TextToCursor(lptw);
  1429. X    TextMessage();
  1430. X}
  1431. X
  1432. X/* Update count characters in window at cursor position */
  1433. X/* Updates cursor position */
  1434. Xvoid
  1435. XUpdateText(LPTW lptw, int count)
  1436. X{
  1437. XHDC hdc;
  1438. Xint xpos, ypos;
  1439. X    xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
  1440. X    ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
  1441. X    hdc = GetDC(lptw->hWndText);
  1442. X    if (lptw->bSysColors) {
  1443. X        SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  1444. X        SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  1445. X    }
  1446. X    else {
  1447. X        SetTextColor(hdc, TextFore(lptw->Attr));
  1448. X        SetBkColor(hdc, TextBack(lptw->Attr));
  1449. X    }
  1450. X    SelectFont(hdc, lptw->hfont);
  1451. X    TextOut(hdc,xpos,ypos,
  1452. X        (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + 
  1453. X        lptw->CursorPos.x), count);
  1454. X    (void)ReleaseDC(lptw->hWndText,hdc);
  1455. X    lptw->CursorPos.x += count;
  1456. X    if (lptw->CursorPos.x >= lptw->ScreenSize.x)
  1457. X        NewLine(lptw);
  1458. X}
  1459. X
  1460. Xint WDPROC
  1461. XTextPutCh(LPTW lptw, BYTE ch)
  1462. X{
  1463. Xint pos;
  1464. X    switch(ch) {
  1465. X        case '\r':
  1466. X            lptw->CursorPos.x = 0;
  1467. X            if (lptw->CursorFlag)
  1468. X                TextToCursor(lptw);
  1469. X            break;
  1470. X        case '\n':
  1471. X            NewLine(lptw);
  1472. X            break;
  1473. X        case 7:
  1474. X            MessageBeep(-1);
  1475. X            if (lptw->CursorFlag)
  1476. X                TextToCursor(lptw);
  1477. X            break;
  1478. X        case '\t':
  1479. X            {
  1480. X            int n;
  1481. X                for ( n = 8 - (lptw->CursorPos.x % 8); n>0; n-- )
  1482. X                    TextPutCh(lptw, ' ');
  1483. X            }
  1484. X            break;
  1485. X        case 0x08:
  1486. X        case 0x7f:
  1487. X            lptw->CursorPos.x--;
  1488. X            if (lptw->CursorPos.x < 0) {
  1489. X                lptw->CursorPos.x = lptw->ScreenSize.x - 1;
  1490. X                lptw->CursorPos.y--;
  1491. X            }
  1492. X            if (lptw->CursorPos.y < 0)
  1493. X                lptw->CursorPos.y = 0;
  1494. X            break;
  1495. X        default:
  1496. X            pos = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
  1497. X            lptw->ScreenBuffer[pos] = ch;
  1498. X            lptw->AttrBuffer[pos] = lptw->Attr;
  1499. X            UpdateText(lptw, 1);
  1500. X    }
  1501. X    return ch;
  1502. X}
  1503. X
  1504. Xvoid 
  1505. XTextPutStr(LPTW lptw, LPSTR str)
  1506. X{
  1507. XBYTE FAR *p, FAR *pa;
  1508. Xint count, limit;
  1509. X    while (*str) {
  1510. X        p = lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
  1511. X        pa = lptw->AttrBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
  1512. X        limit = lptw->ScreenSize.x - lptw->CursorPos.x;
  1513. X        for (count=0; (count < limit) && *str && (isprint(*str) || *str=='\t'); count++) {
  1514. X            if (*str=='\t') {
  1515. X                int n;
  1516. X                for ( n = 8 - ((lptw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) {
  1517. X                    *p++ = ' ';
  1518. X                    *pa++ = lptw->Attr;
  1519. X                }
  1520. X                str++;
  1521. X                count--;
  1522. X            }
  1523. X            else {
  1524. X                *p++ = *str++;
  1525. X                *pa++ = lptw->Attr;
  1526. X            }
  1527. X        }
  1528. X        if (count>0) {
  1529. X            UpdateText(lptw, count);
  1530. X        }
  1531. X        if (*str=='\n') {
  1532. X            NewLine(lptw);
  1533. X            str++;
  1534. X        }
  1535. X        else if (*str && !isprint(*str) && *str!='\t') {
  1536. X            TextPutCh(lptw, *str++);
  1537. X        }
  1538. X    }
  1539. X}
  1540. X
  1541. X
  1542. Xvoid
  1543. XLimitMark(LPTW lptw, POINT FAR *lppt)
  1544. X{
  1545. X    if (lppt->x < 0)
  1546. X        lppt->x = 0;
  1547. X    if (lppt->y < 0) {
  1548. X        lppt->x = 0;
  1549. X        lppt->y = 0;
  1550. X    }
  1551. X    if (lppt->x > lptw->ScreenSize.x)
  1552. X        lppt->x = lptw->ScreenSize.x;
  1553. X    if (lppt->y >= lptw->ScreenSize.y) {
  1554. X        lppt->x = 0;
  1555. X        lppt->y = lptw->ScreenSize.y;
  1556. X    }
  1557. X}
  1558. X
  1559. Xvoid
  1560. XClearMark(LPTW lptw, POINT pt)
  1561. X{
  1562. XRECT rect1, rect2, rect3;
  1563. Xint tmp;
  1564. X  if ((lptw->MarkBegin.x != lptw->MarkEnd.x) || 
  1565. X      (lptw->MarkBegin.y != lptw->MarkEnd.y) ) {
  1566. X    if (lptw->MarkBegin.x > lptw->MarkEnd.x) {
  1567. X        tmp = lptw->MarkBegin.x;
  1568. X        lptw->MarkBegin.x = lptw->MarkEnd.x;
  1569. X        lptw->MarkEnd.x = tmp;
  1570. X    }
  1571. X    if (lptw->MarkBegin.y > lptw->MarkEnd.y) {
  1572. X        tmp = lptw->MarkBegin.y;
  1573. X        lptw->MarkBegin.y = lptw->MarkEnd.y;
  1574. X        lptw->MarkEnd.y = tmp;
  1575. X    }
  1576. X    /* calculate bounding rectangle in character coordinates */
  1577. X    if (lptw->MarkBegin.y != lptw->MarkEnd.y) {
  1578. X        rect1.left = 0;
  1579. X        rect1.right = lptw->ScreenSize.x;
  1580. X    }
  1581. X    else {
  1582. X        rect1.left = lptw->MarkBegin.x;
  1583. X        rect1.right = lptw->MarkEnd.x + 1;
  1584. X    }
  1585. X    rect1.top = lptw->MarkBegin.y;
  1586. X    rect1.bottom = lptw->MarkEnd.y + 1;
  1587. X    /* now convert to client coordinates */
  1588. X    rect1.left   = rect1.left   * lptw->CharSize.x - lptw->ScrollPos.x;
  1589. X    rect1.right  = rect1.right  * lptw->CharSize.x - lptw->ScrollPos.x;
  1590. X    rect1.top    = rect1.top    * lptw->CharSize.y - lptw->ScrollPos.y;
  1591. X    rect1.bottom = rect1.bottom * lptw->CharSize.y - lptw->ScrollPos.y;
  1592. X    /* get client rect and calculate intersection */
  1593. X    GetClientRect(lptw->hWndText, &rect2);
  1594. X    IntersectRect(&rect3,  &rect1, &rect2);
  1595. X    /* update window if necessary */
  1596. X    if (!IsRectEmpty(&rect3)) {
  1597. X        InvalidateRect(lptw->hWndText, &rect3, TRUE);
  1598. X    }
  1599. X  }
  1600. X  LimitMark(lptw, &pt);
  1601. X  lptw->MarkBegin.x = lptw->MarkEnd.x = pt.x;
  1602. X  lptw->MarkBegin.y = lptw->MarkEnd.y = pt.y;
  1603. X  UpdateWindow(lptw->hWndText);
  1604. X}
  1605. X
  1606. X
  1607. X/* output a line including attribute changes as needed */
  1608. Xvoid
  1609. XDoLine(LPTW lptw, HDC hdc, int xpos, int ypos, int offset, int count)
  1610. X{
  1611. X    BYTE FAR *pa, attr;
  1612. X    int idx, num;
  1613. X    pa = lptw->AttrBuffer + offset;
  1614. Xif ((offset < 0) || (offset >= lptw->ScreenSize.x*lptw->ScreenSize.y))
  1615. XMessageBox((HWND)NULL, "panic", "panic", MB_OK | MB_ICONEXCLAMATION);
  1616. X    idx = 0;
  1617. X    num = count;
  1618. X    while (num > 0) {
  1619. X        attr = *pa;
  1620. X        while ((num > 0) && (attr == *pa)) {
  1621. X            /* skip over bytes with same attribute */
  1622. X            num--;
  1623. X            pa++;
  1624. X        }
  1625. X        if (lptw->bSysColors) {
  1626. X            SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  1627. X            SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  1628. X        }
  1629. X        else {
  1630. X            SetTextColor(hdc, TextFore(attr));
  1631. X            SetBkColor(hdc, TextBack(attr));
  1632. X        }
  1633. X        TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset + idx),
  1634. X            count-num-idx);
  1635. X        xpos += lptw->CharSize.x * (count-num-idx);
  1636. X        idx = count-num;
  1637. X    }
  1638. X}
  1639. X
  1640. Xvoid
  1641. XDoMark(LPTW lptw, POINT pt, POINT end, BOOL mark)
  1642. X{
  1643. Xint xpos, ypos;
  1644. XHDC hdc;
  1645. Xint count;
  1646. Xint offset;
  1647. X    offset = lptw->ScreenSize.x * pt.y + pt.x;
  1648. X    hdc = GetDC(lptw->hWndText);
  1649. X    SelectFont(hdc, lptw->hfont);
  1650. X    if (lptw->bSysColors) {
  1651. X        SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  1652. X        SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  1653. X    }
  1654. X    else {
  1655. X        SetTextColor(hdc, MARKFORE);
  1656. X        SetBkColor(hdc, MARKBACK);
  1657. X    }
  1658. X    while (pt.y < end.y) {
  1659. X        /* multiple lines */
  1660. X        xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
  1661. X        ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
  1662. X        count = lptw->ScreenSize.x - pt.x;
  1663. X        if (mark)
  1664. X            TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
  1665. X        else {
  1666. X            DoLine(lptw, hdc, xpos, ypos, offset, count);
  1667. X            if (lptw->bSysColors) {
  1668. X                SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  1669. X                SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  1670. X            }
  1671. X            else {
  1672. X                SetTextColor(hdc, MARKFORE);
  1673. X                SetBkColor(hdc, MARKBACK);
  1674. X            }
  1675. X        }
  1676. X        offset += count;
  1677. X        pt.y++;
  1678. X        pt.x=0;
  1679. X    }
  1680. X    /* partial line */
  1681. X    xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
  1682. X    ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
  1683. X    count = end.x - pt.x;
  1684. X    if (end.y != lptw->ScreenSize.y) {
  1685. X        if (mark)
  1686. X            TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
  1687. X        else
  1688. X            DoLine(lptw, hdc, xpos, ypos, offset, count);
  1689. X    }
  1690. X    (void)ReleaseDC(lptw->hWndText,hdc);
  1691. X}
  1692. X
  1693. Xvoid
  1694. XUpdateMark(LPTW lptw, POINT pt)
  1695. X{
  1696. Xint begin, point, end;
  1697. X    LimitMark(lptw, &pt);
  1698. X    begin = lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x;
  1699. X    point = lptw->ScreenSize.x*pt.y + pt.x;
  1700. X    end   = lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x;
  1701. X
  1702. X    if (begin <= end) {
  1703. X        /* forward mark */
  1704. X        if (point >= end) {
  1705. X            /* extend marked area */
  1706. X            DoMark(lptw, lptw->MarkEnd, pt, TRUE);
  1707. X        }
  1708. X        else if (point >= begin) {
  1709. X            /* retract marked area */
  1710. X            DoMark(lptw, pt, lptw->MarkEnd, FALSE);
  1711. X        }
  1712. X        else {    /* retract and reverse */
  1713. X            DoMark(lptw, lptw->MarkBegin, lptw->MarkEnd, FALSE);
  1714. X            DoMark(lptw, pt, lptw->MarkBegin, TRUE);
  1715. X        }
  1716. X    }
  1717. X    else {
  1718. X        /* reverse mark */
  1719. X        if (point <= end) {
  1720. X            /* extend marked area */
  1721. X            DoMark(lptw, pt, lptw->MarkEnd, TRUE);
  1722. X        }
  1723. X        else if (point <= begin) {
  1724. X            /* retract marked area */
  1725. X            DoMark(lptw, lptw->MarkEnd, pt, FALSE);
  1726. X        }
  1727. X        else {    /* retract and reverse */
  1728. X            DoMark(lptw, lptw->MarkEnd, lptw->MarkBegin, FALSE);
  1729. X            DoMark(lptw, lptw->MarkBegin, pt, TRUE);
  1730. X        }
  1731. X    }
  1732. X    lptw->MarkEnd.x = pt.x;
  1733. X    lptw->MarkEnd.y = pt.y;
  1734. X}
  1735. X
  1736. X
  1737. X#if WINVER >= 0x030a
  1738. X/* Windows 3.1 drag-drop feature */
  1739. Xchar szFile[80];
  1740. Xvoid
  1741. XDragFunc(LPTW lptw, HDROP hdrop)
  1742. X{
  1743. X    int i, cFiles;
  1744. X    LPSTR p;
  1745. X    if ( (lptw->DragPre==(LPSTR)NULL) || (lptw->DragPost==(LPSTR)NULL) )
  1746. X        return;
  1747. X    cFiles = DragQueryFile(hdrop, 0xffff, (LPSTR)NULL, 0);
  1748. X    for (i=0; i<cFiles; i++) {
  1749. X        DragQueryFile(hdrop, i, szFile, 80);
  1750. X        for (p=lptw->DragPre; *p; p++)
  1751. X            SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
  1752. X        for (p=szFile; *p; p++)
  1753. X            SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
  1754. X        for (p=lptw->DragPost; *p; p++)
  1755. X            SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
  1756. X    }
  1757. X    DragFinish(hdrop);
  1758. X}
  1759. X#endif
  1760. X
  1761. X
  1762. Xvoid
  1763. XTextCopyClip(LPTW lptw)
  1764. X{
  1765. X    int size, count;
  1766. X    HGLOBAL hGMem;
  1767. X    LPSTR cbuf, cp;
  1768. X    POINT pt, end;
  1769. X    TEXTMETRIC tm;
  1770. X    UINT type;
  1771. X    HDC hdc;
  1772. X
  1773. X    if ((lptw->MarkBegin.x == lptw->MarkEnd.x) && 
  1774. X        (lptw->MarkBegin.y == lptw->MarkEnd.y) ) {
  1775. X        /* copy user text */
  1776. X        return;
  1777. X    }
  1778. X
  1779. X    size = (lptw->MarkEnd.y - lptw->MarkBegin.y + 1) 
  1780. X        * (lptw->ScreenSize.x + 2) + 1;
  1781. X    hGMem = GlobalAlloc(GMEM_MOVEABLE, (DWORD)size);
  1782. X    cbuf = cp = (LPSTR)GlobalLock(hGMem);
  1783. X    if (cp == (LPSTR)NULL)
  1784. X        return;
  1785. X    
  1786. X    pt.x = lptw->MarkBegin.x;
  1787. X    pt.y = lptw->MarkBegin.y;
  1788. X    end.x   = lptw->MarkEnd.x;
  1789. X    end.y   = lptw->MarkEnd.y;
  1790. X
  1791. X    while (pt.y < end.y) {
  1792. X        /* copy to global buffer */
  1793. X        count = lptw->ScreenSize.x - pt.x;
  1794. X        _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
  1795. X        /* remove trailing spaces */
  1796. X        for (count=count-1; count>=0; count--) {
  1797. X            if (cp[count]!=' ')
  1798. X                break;
  1799. X            cp[count] = '\0';
  1800. X        }
  1801. X        cp[++count] = '\r';
  1802. X        cp[++count] = '\n';
  1803. X        cp[++count] = '\0';
  1804. X        cp += count;
  1805. X        pt.y++;
  1806. X        pt.x=0;
  1807. X    }
  1808. X    /* partial line */
  1809. X    count = end.x - pt.x;
  1810. X    if (end.y != lptw->ScreenSize.y) {
  1811. X        _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
  1812. X        cp[count] = '\0';
  1813. X    }
  1814. X    size = _fstrlen(cbuf) + 1;
  1815. X    GlobalUnlock(hGMem);
  1816. X    hGMem = GlobalReAlloc(hGMem, (DWORD)size, GMEM_MOVEABLE);
  1817. X    /* find out what type to put into clipboard */
  1818. X    hdc = GetDC(lptw->hWndText);
  1819. X    SelectFont(hdc, lptw->hfont);
  1820. X    GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
  1821. X    if (tm.tmCharSet == OEM_CHARSET)
  1822. X        type = CF_OEMTEXT;
  1823. X    else
  1824. X        type = CF_TEXT;
  1825. X    ReleaseDC(lptw->hWndText, hdc);
  1826. X    /* give buffer to clipboard */
  1827. X    OpenClipboard(lptw->hWndParent);
  1828. X    EmptyClipboard();
  1829. X    SetClipboardData(type, hGMem);
  1830. X    CloseClipboard();
  1831. X}
  1832. X
  1833. Xvoid
  1834. XTextMakeFont(LPTW lptw)
  1835. X{
  1836. X    LOGFONT lf;
  1837. X    TEXTMETRIC tm;
  1838. X    LPSTR p;
  1839. X    HDC hdc;
  1840. X
  1841. X    hdc = GetDC(lptw->hWndText);
  1842. X    _fmemset(&lf, 0, sizeof(LOGFONT));
  1843. X    _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
  1844. X    lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  1845. X    lf.lfPitchAndFamily = FIXED_PITCH;
  1846. X    lf.lfCharSet = DEFAULT_CHARSET;
  1847. X    if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
  1848. X        lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
  1849. X        lf.lfItalic = TRUE;
  1850. X    }
  1851. X    if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
  1852. X        lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
  1853. X        lf.lfWeight = FW_BOLD;
  1854. X    }
  1855. X    if (lptw->hfont != 0)
  1856. X        DeleteFont(lptw->hfont);
  1857. X    lptw->hfont = CreateFontIndirect((LOGFONT FAR *)&lf);
  1858. X    /* get text size */
  1859. X    SelectFont(hdc, lptw->hfont);
  1860. X    GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
  1861. X    lptw->CharSize.y = tm.tmHeight;
  1862. X    lptw->CharSize.x = tm.tmAveCharWidth;
  1863. X    lptw->CharAscent = tm.tmAscent;
  1864. X    if (lptw->bFocus)
  1865. X        CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
  1866. X    ReleaseDC(lptw->hWndText, hdc);
  1867. X    return;
  1868. X}
  1869. X
  1870. Xvoid
  1871. XTextSelectFont(LPTW lptw) {
  1872. X#if WINVER >= 0x030a
  1873. X    LOGFONT lf;
  1874. X    CHOOSEFONT cf;
  1875. X    HDC hdc;
  1876. X    char lpszStyle[LF_FACESIZE]; 
  1877. X    LPSTR p;
  1878. X
  1879. X    /* Set all structure fields to zero. */
  1880. X    _fmemset(&cf, 0, sizeof(CHOOSEFONT));
  1881. X    _fmemset(&lf, 0, sizeof(LOGFONT));
  1882. X    cf.lStructSize = sizeof(CHOOSEFONT);
  1883. X    cf.hwndOwner = lptw->hWndParent;
  1884. X    _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
  1885. X    if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
  1886. X        _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
  1887. X        lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
  1888. X    }
  1889. X    else if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
  1890. X        _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
  1891. X        lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
  1892. X    }
  1893. X    else
  1894. X        _fstrcpy(lpszStyle,"Regular");
  1895. X    cf.lpszStyle = lpszStyle;
  1896. X    hdc = GetDC(lptw->hWndText);
  1897. X    lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  1898. X    ReleaseDC(lptw->hWndText, hdc);
  1899. X    lf.lfPitchAndFamily = FIXED_PITCH;
  1900. X    cf.lpLogFont = &lf;
  1901. X    cf.nFontType = SCREEN_FONTTYPE;
  1902. X    cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_USESTYLE;
  1903. X    if (ChooseFont(&cf)) {
  1904. X        RECT rect;
  1905. X        _fstrcpy(lptw->fontname,lf.lfFaceName);
  1906. X        lptw->fontsize = cf.iPointSize / 10;
  1907. X        if (cf.nFontType & BOLD_FONTTYPE)
  1908. X            lstrcat(lptw->fontname," Bold");
  1909. X        if (cf.nFontType & ITALIC_FONTTYPE)
  1910. X            lstrcat(lptw->fontname," Italic");
  1911. X        TextMakeFont(lptw);
  1912. X        /* force a window update */
  1913. X        GetClientRect(lptw->hWndText, (LPRECT) &rect);
  1914. X        SendMessage(lptw->hWndText, WM_SIZE, SIZE_RESTORED, 
  1915. X            MAKELPARAM(rect.right-rect.left, rect.bottom-rect.top));
  1916. X        GetClientRect(lptw->hWndText, (LPRECT) &rect);
  1917. X        InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
  1918. X        UpdateWindow(lptw->hWndText);
  1919. X    }
  1920. X#endif
  1921. X}
  1922. X
  1923. X
  1924. X/* parent overlapped window */
  1925. XLRESULT CALLBACK _export
  1926. XWndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1927. X{
  1928. X    HDC hdc;
  1929. X    PAINTSTRUCT ps;
  1930. X    RECT rect;
  1931. X    LPTW lptw;
  1932. X
  1933. X    lptw = (LPTW)GetWindowLong(hwnd, 0);
  1934. X
  1935. X    switch(message) {
  1936. X        case WM_SYSCOMMAND:
  1937. X            switch(LOWORD(wParam))
  1938. X            {
  1939. X                case M_COPY_CLIP:
  1940. X                case M_PASTE:
  1941. X                case M_CHOOSE_FONT:
  1942. X                case M_SYSCOLORS:
  1943. X                case M_WRITEINI:
  1944. X                case M_ABOUT:
  1945. X                  SendMessage(lptw->hWndText, WM_COMMAND, wParam, lParam);
  1946. X            }
  1947. X            break;
  1948. X        case WM_SETFOCUS: 
  1949. X            if (IsWindow(lptw->hWndText)) {
  1950. X                SetFocus(lptw->hWndText);
  1951. X                return(0);
  1952. X            }
  1953. X            break;
  1954. X        case WM_GETMINMAXINFO:
  1955. X            {
  1956. X            POINT far * MMinfo = (POINT far *)lParam;
  1957. X            TEXTMETRIC tm;
  1958. X            hdc = GetDC(hwnd);
  1959. X            SelectFont(hdc, GetStockFont(OEM_FIXED_FONT));
  1960. X            GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
  1961. X            ReleaseDC(hwnd,hdc);
  1962. X            /* minimum size */
  1963. X            MMinfo[3].x = ScreenMinSize.x*tm.tmAveCharWidth
  1964. X                + GetSystemMetrics(SM_CXVSCROLL) + 2*GetSystemMetrics(SM_CXFRAME);
  1965. X            MMinfo[3].y = ScreenMinSize.y*tm.tmHeight
  1966. X                + GetSystemMetrics(SM_CYHSCROLL) + 2*GetSystemMetrics(SM_CYFRAME)
  1967. X                + GetSystemMetrics(SM_CYCAPTION);
  1968. X            }
  1969. X            return(0);
  1970. X        case WM_SIZE:
  1971. X            SetWindowPos(lptw->hWndText, (HWND)NULL, 0, lptw->ButtonHeight,
  1972. X                LOWORD(lParam), HIWORD(lParam)-lptw->ButtonHeight, 
  1973. X                SWP_NOZORDER | SWP_NOACTIVATE);
  1974. X            return(0);
  1975. X        case WM_COMMAND:
  1976. X            if (IsWindow(lptw->hWndText))
  1977. X                SetFocus(lptw->hWndText);
  1978. X            SendMessage(lptw->hWndText, message, wParam, lParam); /* pass on menu commands */
  1979. X            return(0);
  1980. X        case WM_PAINT:
  1981. X            {
  1982. X            hdc = BeginPaint(hwnd, &ps);
  1983. X            if (lptw->ButtonHeight) {
  1984. X                HBRUSH hbrush;
  1985. X                GetClientRect(hwnd, &rect);
  1986. X                hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  1987. X                rect.bottom = lptw->ButtonHeight-1;
  1988. X                FillRect(hdc, &rect, hbrush);
  1989. X                DeleteBrush(hbrush);
  1990. X                SelectPen(hdc, GetStockPen(BLACK_PEN));
  1991. X                MoveTo(hdc, rect.left, lptw->ButtonHeight-1);
  1992. X                LineTo(hdc, rect.right, lptw->ButtonHeight-1);
  1993. X            }
  1994. X            EndPaint(hwnd, &ps);
  1995. X            return 0;
  1996. X            }
  1997. X#if WINVER >= 0x030a
  1998. X        case WM_DROPFILES:
  1999. X            {
  2000. X            WORD version = LOWORD(GetVersion());
  2001. X            if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
  2002. X                DragFunc(lptw, (HDROP)wParam);
  2003. X            }
  2004. X            break;
  2005. X#endif
  2006. X        case WM_CREATE:
  2007. X            {
  2008. X            RECT crect, wrect;
  2009. X            TEXTMETRIC tm;
  2010. X            lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
  2011. X            SetWindowLong(hwnd, 0, (LONG)lptw);
  2012. X            lptw->hWndParent = hwnd;
  2013. X            /* get character size */
  2014. X            TextMakeFont(lptw);
  2015. X            hdc = GetDC(hwnd);
  2016. X            SelectFont(hdc, lptw->hfont);
  2017. X            GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
  2018. X            lptw->CharSize.y = tm.tmHeight;
  2019. X            lptw->CharSize.x = tm.tmAveCharWidth;
  2020. X            lptw->CharAscent = tm.tmAscent;
  2021. X            ReleaseDC(hwnd,hdc);
  2022. X            GetClientRect(hwnd, &crect);
  2023. X            if ( (lptw->CharSize.y*lptw->ScreenSize.y < crect.bottom)
  2024. X              || (lptw->CharSize.x*lptw->ScreenSize.x < crect.right) ) {
  2025. X                /* shrink size */
  2026. X                GetWindowRect(lptw->hWndParent,&wrect);
  2027. X                MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
  2028. X                 wrect.right-wrect.left + (lptw->CharSize.x*lptw->ScreenSize.x - crect.right),
  2029. X                 wrect.bottom-wrect.top + (lptw->CharSize.y*lptw->ScreenSize.y+lptw->ButtonHeight - crect.bottom),
  2030. X                 TRUE);
  2031. X            }
  2032. X            }
  2033. X#if WINVER >= 0x030a
  2034. X            {
  2035. X            WORD version = LOWORD(GetVersion());
  2036. X            if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
  2037. X                if ( (lptw->DragPre!=(LPSTR)NULL) && (lptw->DragPost!=(LPSTR)NULL) )
  2038. X                    DragAcceptFiles(hwnd, TRUE);
  2039. X            }
  2040. X#endif
  2041. X            break;
  2042. X        case WM_DESTROY:
  2043. X#if WINVER >= 0x030a
  2044. X            {
  2045. X            WORD version = LOWORD(GetVersion());
  2046. X            if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
  2047. X                DragAcceptFiles(hwnd, FALSE);
  2048. X            }
  2049. X#endif
  2050. X            DeleteFont(lptw->hfont);
  2051. X            lptw->hfont = 0;
  2052. X            break;
  2053. X        case WM_CLOSE:
  2054. X            if (lptw->shutdown) {
  2055. X                FARPROC lpShutDown = lptw->shutdown;
  2056. X                (*lpShutDown)();
  2057. X            }
  2058. X            break;
  2059. X    }
  2060. X    return DefWindowProc(hwnd, message, wParam, lParam);
  2061. X}
  2062. X
  2063. X/* child text window */
  2064. XLRESULT CALLBACK _export
  2065. XWndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  2066. X{
  2067. X    HDC hdc;
  2068. X    PAINTSTRUCT ps;
  2069. X    RECT rect;
  2070. X    int nYinc, nXinc;
  2071. X    LPTW lptw;
  2072. X
  2073. X    lptw = (LPTW)GetWindowLong(hwnd, 0);
  2074. X
  2075. X    switch(message) {
  2076. X        case WM_SETFOCUS: 
  2077. X            lptw->bFocus = TRUE;
  2078. X            CreateCaret(hwnd, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
  2079. X            SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
  2080. X                lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
  2081. X                 - lptw->CaretHeight - lptw->ScrollPos.y);
  2082. X            if (lptw->bGetCh)
  2083. X                ShowCaret(hwnd);
  2084. X            break;
  2085. X        case WM_KILLFOCUS: 
  2086. X            DestroyCaret();
  2087. X            lptw->bFocus = FALSE;
  2088. X            break;
  2089. X        case WM_SIZE:
  2090. X            lptw->ClientSize.y = HIWORD(lParam);
  2091. X            lptw->ClientSize.x = LOWORD(lParam);
  2092. X
  2093. X            lptw->ScrollMax.y = max(0, lptw->CharSize.y*lptw->ScreenSize.y - lptw->ClientSize.y);
  2094. X            lptw->ScrollPos.y = min(lptw->ScrollPos.y, lptw->ScrollMax.y);
  2095. X
  2096. X            SetScrollRange(hwnd, SB_VERT, 0, lptw->ScrollMax.y, FALSE);
  2097. X            SetScrollPos(hwnd, SB_VERT, lptw->ScrollPos.y, TRUE);
  2098. X
  2099. X            lptw->ScrollMax.x = max(0, lptw->CharSize.x*lptw->ScreenSize.x - lptw->ClientSize.x);
  2100. X            lptw->ScrollPos.x = min(lptw->ScrollPos.x, lptw->ScrollMax.x);
  2101. X
  2102. X            SetScrollRange(hwnd, SB_HORZ, 0, lptw->ScrollMax.x, FALSE);
  2103. X            SetScrollPos(hwnd, SB_HORZ, lptw->ScrollPos.x, TRUE);
  2104. X
  2105. X            if (lptw->bFocus && lptw->bGetCh) {
  2106. X                SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
  2107. X                    lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent 
  2108. X                    - lptw->CaretHeight - lptw->ScrollPos.y);
  2109. X                ShowCaret(hwnd);
  2110. X            }
  2111. X            return(0);
  2112. X        case WM_VSCROLL:
  2113. X            switch(LOWORD(wParam)) {
  2114. X                case SB_TOP:
  2115. X                    nYinc = -lptw->ScrollPos.y;
  2116. X                    break;
  2117. X                case SB_BOTTOM:
  2118. X                    nYinc = lptw->ScrollMax.y - lptw->ScrollPos.y;
  2119. X                    break;
  2120. X                case SB_LINEUP:
  2121. X                    nYinc = -lptw->CharSize.y;
  2122. X                    break;
  2123. X                case SB_LINEDOWN:
  2124. X                    nYinc = lptw->CharSize.y;
  2125. X                    break;
  2126. X                case SB_PAGEUP:
  2127. X                    nYinc = min(-1,-lptw->ClientSize.y);
  2128. X                    break;
  2129. X                case SB_PAGEDOWN:
  2130. X                    nYinc = max(1,lptw->ClientSize.y);
  2131. X                    break;
  2132. X                case SB_THUMBPOSITION:
  2133. X                    nYinc = LOWORD(lParam) - lptw->ScrollPos.y;
  2134. X                    break;
  2135. X                default:
  2136. X                    nYinc = 0;
  2137. X                }
  2138. X            if ( (nYinc = max(-lptw->ScrollPos.y, 
  2139. X                min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y)))
  2140. X                != 0 ) {
  2141. X                lptw->ScrollPos.y += nYinc;
  2142. X                ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
  2143. X                SetScrollPos(hwnd,SB_VERT,lptw->ScrollPos.y,TRUE);
  2144. X                UpdateWindow(hwnd);
  2145. X            }
  2146. X            return(0);
  2147. X        case WM_HSCROLL:
  2148. X            switch(LOWORD(wParam)) {
  2149. X                case SB_LINEUP:
  2150. X                    nXinc = -lptw->CharSize.x;
  2151. X                    break;
  2152. X                case SB_LINEDOWN:
  2153. X                    nXinc = lptw->CharSize.x;
  2154. X                    break;
  2155. X                case SB_PAGEUP:
  2156. X                    nXinc = min(-1,-lptw->ClientSize.x);
  2157. X                    break;
  2158. X                case SB_PAGEDOWN:
  2159. X                    nXinc = max(1,lptw->ClientSize.x);
  2160. X                    break;
  2161. X                case SB_THUMBPOSITION:
  2162. X                    nXinc = LOWORD(lParam) - lptw->ScrollPos.x;
  2163. X                    break;
  2164. X                default:
  2165. X                    nXinc = 0;
  2166. X                }
  2167. X            if ( (nXinc = max(-lptw->ScrollPos.x, 
  2168. X                min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x)))
  2169. X                != 0 ) {
  2170. X                lptw->ScrollPos.x += nXinc;
  2171. X                ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
  2172. X                SetScrollPos(hwnd,SB_HORZ,lptw->ScrollPos.x,TRUE);
  2173. X                UpdateWindow(hwnd);
  2174. X            }
  2175. X            return(0);
  2176. X        case WM_KEYDOWN:
  2177. X            if (GetKeyState(VK_SHIFT) < 0) {
  2178. X              switch(wParam) {
  2179. X                case VK_HOME:
  2180. X                    SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
  2181. X                    break;
  2182. X                case VK_END:
  2183. X                    SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
  2184. X                    break;
  2185. X                case VK_PRIOR:
  2186. X                    SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
  2187. X                    break;
  2188. X                case VK_NEXT:
  2189. X                    SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
  2190. X                    break;
  2191. X                case VK_UP:
  2192. X                    SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
  2193. X                    break;
  2194. X                case VK_DOWN:
  2195. X                    SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
  2196. X                    break;
  2197. X                case VK_LEFT:
  2198. X                    SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
  2199. X                    break;
  2200. X                case VK_RIGHT:
  2201. X                    SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
  2202. X                    break;
  2203. X              }
  2204. X            }
  2205. X            else {
  2206. X              switch(wParam) {
  2207. X                case VK_HOME:
  2208. X                case VK_END:
  2209. X                case VK_PRIOR:
  2210. X                case VK_NEXT:
  2211. X                case VK_UP:
  2212. X                case VK_DOWN:
  2213. X                case VK_LEFT:
  2214. X                case VK_RIGHT:
  2215. X                case VK_DELETE:
  2216. X                { /* store key in circular buffer */
  2217. X                long count;
  2218. X                    count = lptw->KeyBufIn - lptw->KeyBufOut;
  2219. X                    if (count < 0) count += lptw->KeyBufSize;
  2220. X                    if (count < lptw->KeyBufSize-2) {
  2221. X                        *lptw->KeyBufIn++ = 0;
  2222. X                        if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
  2223. X                            lptw->KeyBufIn = lptw->KeyBuf;    /* wrap around */
  2224. X                        *lptw->KeyBufIn++ = HIWORD(lParam) & 0xff;
  2225. X                        if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
  2226. X                            lptw->KeyBufIn = lptw->KeyBuf;    /* wrap around */
  2227. X                    }
  2228. X                }
  2229. X              }
  2230. X            }
  2231. X            break;
  2232. X        case WM_RBUTTONDOWN:
  2233. X            {
  2234. X            POINT pt;
  2235. X            pt.x = LOWORD(lParam);
  2236. X            pt.y = HIWORD(lParam);
  2237. X            ClientToScreen(hwnd,&pt);
  2238. X            TrackPopupMenu(lptw->hPopMenu, TPM_LEFTALIGN, 
  2239. X                pt.x, pt.y, 0, hwnd, NULL);
  2240. X            }
  2241. X            return(0);
  2242. X        case WM_LBUTTONDOWN:
  2243. X            { /* start marking text */
  2244. X            POINT pt;
  2245. X            pt.x = LOWORD(lParam);
  2246. X            pt.y = HIWORD(lParam);
  2247. X            pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
  2248. X            pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
  2249. X            ClearMark(lptw, pt);
  2250. X            }
  2251. X            SetCapture(hwnd);    /* track the mouse */
  2252. X            lptw->Marking = TRUE;
  2253. X            break;
  2254. X        case WM_LBUTTONUP:
  2255. X            { /* finish marking text */
  2256. X            /* ensure begin mark is before end mark */
  2257. X            ReleaseCapture();
  2258. X            lptw->Marking = FALSE;
  2259. X            if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
  2260. X                (lptw->ScreenSize.x*lptw->MarkEnd.y   + lptw->MarkEnd.x)) {
  2261. X                POINT tmp;
  2262. X                tmp.x = lptw->MarkBegin.x;
  2263. X                tmp.y = lptw->MarkBegin.y;
  2264. X                lptw->MarkBegin.x = lptw->MarkEnd.x;
  2265. X                lptw->MarkBegin.y = lptw->MarkEnd.y;
  2266. X                lptw->MarkEnd.x   = tmp.x;
  2267. X                lptw->MarkEnd.y   = tmp.y;
  2268. X            }
  2269. X            }
  2270. X            break;
  2271. X        case WM_MOUSEMOVE:
  2272. X            if ( (wParam & MK_LBUTTON) && lptw->Marking ) {
  2273. X            RECT rect;
  2274. X            POINT pt;
  2275. X            pt.x = LOWORD(lParam);
  2276. X            pt.y = HIWORD(lParam);
  2277. X            GetClientRect(hwnd, &rect);
  2278. X            if (PtInRect(&rect, pt)) {
  2279. X                pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
  2280. X                pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
  2281. X                UpdateMark(lptw, pt);
  2282. X            }
  2283. X            else {
  2284. X              int nXinc;
  2285. X              int nYinc;
  2286. X              do {
  2287. X                nXinc = 0;
  2288. X                nYinc = 0;
  2289. X                if (pt.x > rect.right) {
  2290. X                    nXinc = lptw->CharSize.x * 4;
  2291. X                    pt.x = (rect.right + lptw->ScrollPos.x)/lptw->CharSize.x + 2;
  2292. X                }
  2293. X                else if (pt.x < rect.left) {
  2294. X                    nXinc = -lptw->CharSize.x * 4;
  2295. X                    pt.x = (rect.left + lptw->ScrollPos.x)/lptw->CharSize.x - 2;
  2296. X                }
  2297. X                else
  2298. X                    pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
  2299. X                if (pt.y > rect.bottom) {
  2300. X                    nYinc = lptw->CharSize.y;
  2301. X                    pt.y = (rect.bottom + lptw->ScrollPos.y)/lptw->CharSize.y + 1;
  2302. X                }
  2303. X                else if (pt.y < rect.top) {
  2304. X                    nYinc = -lptw->CharSize.y;
  2305. X                    pt.y = (rect.top + lptw->ScrollPos.y)/lptw->CharSize.y - 1;
  2306. X                }
  2307. X                else
  2308. X                    pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
  2309. X                LimitMark(lptw, &pt);
  2310. X                nXinc = max(nXinc, -lptw->ScrollPos.x);
  2311. X                nYinc = max(nYinc, -lptw->ScrollPos.y);
  2312. X                nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
  2313. X                nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
  2314. X                if (nYinc || nXinc) {
  2315. X                    lptw->ScrollPos.y += nYinc;
  2316. X                    lptw->ScrollPos.x += nXinc;
  2317. X                    ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
  2318. X                    SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
  2319. X                    SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
  2320. X                    UpdateWindow(lptw->hWndText);
  2321. X                }
  2322. X                UpdateMark(lptw, pt);
  2323. X                GetCursorPos(&pt);
  2324. X                ScreenToClient(hwnd, &pt);
  2325. X              }
  2326. X              while( (nYinc || nXinc) && !PtInRect(&rect, pt) &&
  2327. X                (GetAsyncKeyState(VK_LBUTTON) < 0) );
  2328. X            }
  2329. X            }
  2330. X            break;
  2331. X        case WM_CHAR:
  2332. X            { /* store key in circular buffer */
  2333. X            long count;
  2334. X                count = lptw->KeyBufIn - lptw->KeyBufOut;
  2335. X                if (count < 0) count += lptw->KeyBufSize;
  2336. X                if (count < lptw->KeyBufSize-1) {
  2337. X                    *lptw->KeyBufIn++ = wParam;
  2338. X                    if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
  2339. X                        lptw->KeyBufIn = lptw->KeyBuf;    /* wrap around */
  2340. X                }
  2341. X            }
  2342. X            return(0);
  2343. X        case WM_COMMAND:
  2344. X            if (LOWORD(wParam) < NUMMENU)
  2345. X                SendMacro(lptw, LOWORD(wParam));
  2346. X            else
  2347. X            switch(LOWORD(wParam))
  2348. X            {
  2349. X                case M_COPY_CLIP:
  2350. X                    TextCopyClip(lptw);
  2351. X                    return 0;
  2352. X                case M_PASTE:
  2353. X                    {
  2354. X                    HGLOBAL hGMem;
  2355. X                    BYTE FAR *cbuf;
  2356. X                    TEXTMETRIC tm;
  2357. X                    UINT type;
  2358. X                    /* find out what type to get from clipboard */
  2359. X                    hdc = GetDC(hwnd);
  2360. X                    SelectFont(hdc, lptw->hfont);
  2361. X                    GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
  2362. X                    if (tm.tmCharSet == OEM_CHARSET)
  2363. X                        type = CF_OEMTEXT;
  2364. X                    else
  2365. X                        type = CF_TEXT;
  2366. X                    ReleaseDC(lptw->hWndText, hdc);
  2367. X                    /* now get it from clipboard */
  2368. X                    OpenClipboard(hwnd);
  2369. X                    hGMem = GetClipboardData(type);
  2370. X                    if (hGMem) {
  2371. X                        cbuf = (BYTE FAR *) GlobalLock(hGMem);
  2372. X                        while (*cbuf) {
  2373. X                            if (*cbuf != '\n')
  2374. X                                SendMessage(lptw->hWndText,WM_CHAR,*cbuf,1L);
  2375. X                            cbuf++;
  2376. X                        }
  2377. X                        GlobalUnlock(hGMem);
  2378. X                    }
  2379. X                    CloseClipboard();
  2380. X                    return 0;
  2381. X                    }
  2382. X                case M_CHOOSE_FONT:
  2383. X                    TextSelectFont(lptw);
  2384. X                    return 0;
  2385. X                case M_SYSCOLORS:
  2386. X                    lptw->bSysColors = !lptw->bSysColors;
  2387. X                    if (lptw->bSysColors) 
  2388. X                        CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_CHECKED);
  2389. X                    else
  2390. X                        CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_UNCHECKED);
  2391. X                    SendMessage(hwnd, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);
  2392. X                    InvalidateRect(hwnd, (LPRECT)NULL, 1);
  2393. X                    UpdateWindow(hwnd);
  2394. X                    return 0;
  2395. X                case M_WRITEINI:
  2396. X                    WriteTextIni(lptw);
  2397. X                    return 0;
  2398. X                case M_ABOUT:
  2399. X                    AboutBox(hwnd,lptw->AboutText);
  2400. X                    return 0;
  2401. X            }
  2402. X            return(0);
  2403. X        case WM_SYSCOLORCHANGE:
  2404. X            DeleteBrush(lptw->hbrBackground);
  2405. X            lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ? 
  2406. X                GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
  2407. X            return(0);
  2408. X        case WM_ERASEBKGND:
  2409. X            return(1);    /* we will erase it ourselves */
  2410. X        case WM_PAINT:
  2411. X            {
  2412. X            POINT source, width, dest;
  2413. X            POINT MarkBegin, MarkEnd;
  2414. X            hdc = BeginPaint(hwnd, &ps);
  2415. X            if (ps.fErase)
  2416. X                FillRect(hdc, &ps.rcPaint, lptw->hbrBackground);
  2417. X            SelectFont(hdc, lptw->hfont);
  2418. X            SetMapMode(hdc, MM_TEXT);
  2419. X            SetBkMode(hdc,OPAQUE);
  2420. X            GetClientRect(hwnd, &rect);
  2421. X            source.x = (rect.left + lptw->ScrollPos.x) / lptw->CharSize.x;        /* source */
  2422. X            source.y = (rect.top + lptw->ScrollPos.y) / lptw->CharSize.y;
  2423. X            dest.x = source.x * lptw->CharSize.x - lptw->ScrollPos.x;                 /* destination */
  2424. X            dest.y = source.y * lptw->CharSize.y - lptw->ScrollPos.y;
  2425. X            width.x = ((rect.right  + lptw->ScrollPos.x + lptw->CharSize.x - 1) / lptw->CharSize.x) - source.x; /* width */
  2426. X            width.y = ((rect.bottom + lptw->ScrollPos.y + lptw->CharSize.y - 1) / lptw->CharSize.y) - source.y;
  2427. X            if (source.x < 0)
  2428. X                source.x = 0;
  2429. X            if (source.y < 0)
  2430. X                source.y = 0;
  2431. X            if (source.x+width.x > lptw->ScreenSize.x)
  2432. X                width.x = lptw->ScreenSize.x - source.x;
  2433. X            if (source.y+width.y > lptw->ScreenSize.y)
  2434. X                width.y = lptw->ScreenSize.y - source.y;
  2435. X            /* ensure begin mark is before end mark */
  2436. X            if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
  2437. X                (lptw->ScreenSize.x*lptw->MarkEnd.y   + lptw->MarkEnd.x)) {
  2438. X                MarkBegin.x = lptw->MarkEnd.x;
  2439. X                MarkBegin.y = lptw->MarkEnd.y;
  2440. X                MarkEnd.x   = lptw->MarkBegin.x;
  2441. X                MarkEnd.y   = lptw->MarkBegin.y;
  2442. X            }
  2443. X            else {
  2444. X                MarkBegin.x = lptw->MarkBegin.x;
  2445. X                MarkBegin.y = lptw->MarkBegin.y;
  2446. X                MarkEnd.x   = lptw->MarkEnd.x;
  2447. X                MarkEnd.y   = lptw->MarkEnd.y;
  2448. X            }
  2449. X            /* for each line */
  2450. X            while (width.y>0) {
  2451. X                if ( (source.y >= MarkBegin.y) && (source.y <= MarkEnd.y) ) {
  2452. X                    int start, end;
  2453. X                    int count, offset;
  2454. X                    if (source.y == MarkBegin.y)
  2455. X                        start = MarkBegin.x;
  2456. X                    else
  2457. X                        start = 0;
  2458. X                    if (source.y == MarkEnd.y)
  2459. X                        end = MarkEnd.x;
  2460. X                    else
  2461. X                        end = lptw->ScreenSize.x;
  2462. X                    /* do stuff before marked text */
  2463. X                    offset = 0;
  2464. X                    count = start - source.x;
  2465. X                    if (count > 0)
  2466. X                      DoLine(lptw, hdc, dest.x, dest.y, 
  2467. X                        source.y*lptw->ScreenSize.x + source.x, count);
  2468. X                    /* then the marked text */
  2469. X                    offset += count;
  2470. X                    count = end - start;
  2471. X                    if ((count > 0) && (offset < width.x)){
  2472. X                      if (lptw->bSysColors) {
  2473. X                        SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  2474. X                        SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  2475. X                      }
  2476. X                      else {
  2477. X                        SetTextColor(hdc, MARKFORE);
  2478. X                        SetBkColor(hdc, MARKBACK);
  2479. X                      }
  2480. X                      TextOut(hdc, dest.x + lptw->CharSize.x*offset, dest.y, 
  2481. X                        (LPSTR)(lptw->ScreenBuffer + source.y*lptw->ScreenSize.x 
  2482. X                        + source.x + offset), count);
  2483. X                    }
  2484. X                    /* then stuff after marked text */
  2485. X                    offset += count;
  2486. X                    count = width.x + source.x - end;
  2487. X                    if ((count > 0) && (offset < width.x))
  2488. X                      DoLine(lptw, hdc, dest.x + lptw->CharSize.x*offset, dest.y, 
  2489. X                        source.y*lptw->ScreenSize.x + source.x + offset, count);
  2490. X                }
  2491. X                else {
  2492. X                    DoLine(lptw, hdc, dest.x, dest.y, 
  2493. X                        source.y*lptw->ScreenSize.x + source.x, width.x);
  2494. X                }
  2495. X                dest.y += lptw->CharSize.y;
  2496. X                source.y++;
  2497. X                width.y--;
  2498. X            }
  2499. X            EndPaint(hwnd, &ps);
  2500. X            return 0;
  2501. X            }
  2502. X        case WM_CREATE:
  2503. X            lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
  2504. X            SetWindowLong(hwnd, 0, (LONG)lptw);
  2505. X            lptw->hWndText = hwnd;
  2506. X            break;
  2507. X        case WM_DESTROY:
  2508. X            DeleteBrush(lptw->hbrBackground);
  2509. X            break;
  2510. X    }
  2511. X    return DefWindowProc(hwnd, message, wParam, lParam);
  2512. X}
  2513. X
  2514. X
  2515. X/* ================================== */
  2516. X/* replacement stdio routines */
  2517. X
  2518. X/* TRUE if key hit, FALSE if no key */
  2519. Xint WDPROC
  2520. XTextKBHit(LPTW lptw)
  2521. X{
  2522. X    return (lptw->KeyBufIn != lptw->KeyBufOut);
  2523. X}
  2524. X
  2525. X/* get character from keyboard, no echo */
  2526. X/* need to add extended codes */
  2527. Xint WDPROC
  2528. XTextGetCh(LPTW lptw)
  2529. X{
  2530. X    int ch;
  2531. X    TextToCursor(lptw);
  2532. X    lptw->bGetCh = TRUE;
  2533. X    if (lptw->bFocus) {
  2534. X        SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
  2535. X            lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent 
  2536. X            - lptw->CaretHeight - lptw->ScrollPos.y);
  2537. X        ShowCaret(lptw->hWndText);
  2538. X    }
  2539. X    do {
  2540. X        TextMessage();
  2541. X    } while (!TextKBHit(lptw));
  2542. X    ch = *lptw->KeyBufOut++;
  2543. X    if (ch=='\r')
  2544. X        ch = '\n';
  2545. X    if (lptw->KeyBufOut - lptw->KeyBuf >= lptw->KeyBufSize)
  2546. X        lptw->KeyBufOut = lptw->KeyBuf;    /* wrap around */
  2547. X    if (lptw->bFocus)
  2548. X        HideCaret(lptw->hWndText);
  2549. X    lptw->bGetCh = FALSE;
  2550. X    return ch;
  2551. X}
  2552. X
  2553. X/* get character from keyboard, with echo */
  2554. Xint WDPROC
  2555. XTextGetChE(LPTW lptw)
  2556. X{
  2557. Xint ch;
  2558. X    ch = TextGetCh(lptw);
  2559. X    TextPutCh(lptw, (BYTE)ch);
  2560. X    return ch;
  2561. X}
  2562. X
  2563. XLPSTR WDPROC
  2564. XTextGetS(LPTW lptw, LPSTR str, unsigned int size)
  2565. X{
  2566. X    LPSTR next = str;
  2567. X    while (--size>0) {
  2568. X        switch(*next = TextGetChE(lptw)) {
  2569. X            case EOF:
  2570. X                *next = NULL;
  2571. X                if (next == str) return (char *)NULL;
  2572. X                return str;
  2573. X            case '\n':
  2574. X                *(next+1) = NULL;
  2575. X                return str;
  2576. X            case 0x08:
  2577. X            case 0x7f:
  2578. X                if (next > str)
  2579. X                    --next;
  2580. X                break;
  2581. X            default:
  2582. X                ++next;
  2583. X        }
  2584. X    }
  2585. X    *next = NULL;
  2586. X    return str;
  2587. X}
  2588. X
  2589. Xint WDPROC
  2590. XTextPutS(LPTW lptw, LPSTR str)
  2591. X{
  2592. X    TextPutStr(lptw, str);
  2593. X    return str[_fstrlen(str)-1];
  2594. X}
  2595. X
  2596. X/* ================================== */
  2597. X/* routines added for elvis */
  2598. X
  2599. Xvoid WDPROC
  2600. XTextGotoXY(LPTW lptw, int x, int y)
  2601. X{
  2602. X    lptw->CursorPos.x = x;
  2603. X    lptw->CursorPos.y = y;
  2604. X}
  2605. X
  2606. Xint  WDPROC
  2607. XTextWhereX(LPTW lptw)
  2608. X{
  2609. X    return lptw->CursorPos.x;
  2610. X}
  2611. X
  2612. Xint  WDPROC
  2613. XTextWhereY(LPTW lptw)
  2614. X{
  2615. X    return lptw->CursorPos.y;
  2616. X}
  2617. X
  2618. Xvoid WDPROC
  2619. XTextCursorHeight(LPTW lptw, int height)
  2620. X{
  2621. X    lptw->CaretHeight = height;
  2622. X    if (lptw->bFocus)
  2623. X        CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
  2624. X}
  2625. X
  2626. Xvoid WDPROC
  2627. XTextClearEOL(LPTW lptw)
  2628. X{
  2629. XHDC hdc;
  2630. Xint xpos, ypos;
  2631. Xint from, len;
  2632. XPOINT pt;
  2633. X    pt.x = pt.y = 0;
  2634. X    ClearMark(lptw, pt);
  2635. X    from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
  2636. X    len = lptw->ScreenSize.x-lptw->CursorPos.x;
  2637. X    _fmemset(lptw->ScreenBuffer + from, ' ', len);
  2638. X    _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
  2639. X    xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
  2640. X    ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
  2641. X    hdc = GetDC(lptw->hWndText);
  2642. X    if (lptw->bSysColors) {
  2643. X        SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  2644. X        SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  2645. X    }
  2646. X    else {
  2647. X        SetTextColor(hdc, TextFore(lptw->Attr));
  2648. X        SetBkColor(hdc, TextBack(lptw->Attr));
  2649. X    }
  2650. X    SelectFont(hdc, (lptw->hfont));
  2651. X    TextOut(hdc,xpos,ypos,
  2652. X        (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + 
  2653. X        lptw->CursorPos.x), lptw->ScreenSize.x-lptw->CursorPos.x);
  2654. X    (void)ReleaseDC(lptw->hWndText,hdc);
  2655. X}
  2656. X
  2657. Xvoid WDPROC
  2658. XTextClearEOS(LPTW lptw)
  2659. X{
  2660. XRECT rect;
  2661. Xint from, len;
  2662. XPOINT pt;
  2663. X    pt.x = pt.y = 0;
  2664. X    ClearMark(lptw, pt);
  2665. X    from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
  2666. X    len = lptw->ScreenSize.x-lptw->CursorPos.x + 
  2667. X            (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
  2668. X    _fmemset(lptw->ScreenBuffer + from, ' ', len);
  2669. X    _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
  2670. X    GetClientRect(lptw->hWndText, (LPRECT) &rect);
  2671. X    InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
  2672. X    UpdateWindow(lptw->hWndText);
  2673. X}
  2674. X
  2675. Xvoid WDPROC
  2676. XTextInsertLine(LPTW lptw)
  2677. X{
  2678. XRECT rect;
  2679. Xint from, to, len;
  2680. XPOINT pt;
  2681. X    pt.x = pt.y = 0;
  2682. X    ClearMark(lptw, pt);
  2683. X    from = lptw->CursorPos.y*lptw->ScreenSize.x,
  2684. X    to = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
  2685. X    len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
  2686. X    _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
  2687. X    _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
  2688. X    _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
  2689. X    _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
  2690. X    GetClientRect(lptw->hWndText, (LPRECT) &rect);
  2691. X    InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
  2692. X    UpdateWindow(lptw->hWndText);
  2693. X    if (lptw->CursorFlag)
  2694. X        TextToCursor(lptw);
  2695. X}
  2696. X
  2697. Xvoid WDPROC
  2698. XTextDeleteLine(LPTW lptw)
  2699. X{
  2700. XRECT rect;
  2701. Xint from, to, len;
  2702. XPOINT pt;
  2703. X    pt.x = pt.y = 0;
  2704. X    ClearMark(lptw, pt);
  2705. X    to = lptw->CursorPos.y*lptw->ScreenSize.x,
  2706. X    from = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
  2707. X    len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
  2708. X    _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
  2709. X    _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
  2710. X    from = lptw->ScreenSize.x*(lptw->ScreenSize.y -1);
  2711. X    _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
  2712. X    _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
  2713. X    GetClientRect(lptw->hWndText, (LPRECT) &rect);
  2714. X    InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
  2715. X    UpdateWindow(lptw->hWndText);
  2716. X    if (lptw->CursorFlag)
  2717. X        TextToCursor(lptw);
  2718. X}
  2719. X
  2720. Xvoid WDPROC
  2721. XTextScrollReverse(LPTW lptw)
  2722. X{
  2723. XRECT rect;
  2724. Xint len = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1); 
  2725. X    _fmemmove(lptw->ScreenBuffer+lptw->ScreenSize.x, lptw->ScreenBuffer, len);
  2726. X    _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x);
  2727. X    _fmemmove(lptw->AttrBuffer+lptw->ScreenSize.x, lptw->AttrBuffer, len);
  2728. X    _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x);
  2729. X    if (lptw->CursorPos.y)
  2730. X        lptw->CursorPos.y--;
  2731. X    ScrollWindow(lptw->hWndText,0,+lptw->CharSize.y,NULL,NULL);
  2732. X    GetClientRect(lptw->hWndText, (LPRECT) &rect);
  2733. X    rect.top = lptw->ScreenSize.y*lptw->CharSize.y;
  2734. X    if (rect.top < rect.bottom)
  2735. X        InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
  2736. X    lptw->MarkBegin.y++;
  2737. X    lptw->MarkEnd.y++;
  2738. X    LimitMark(lptw, &lptw->MarkBegin);
  2739. X    LimitMark(lptw, &lptw->MarkEnd);
  2740. X    UpdateWindow(lptw->hWndText);
  2741. X}
  2742. X
  2743. Xvoid WDPROC 
  2744. XTextAttr(LPTW lptw, BYTE attr)
  2745. X{
  2746. X    lptw->Attr = attr;
  2747. X}
  2748. X
  2749. X/* About Box */
  2750. XBOOL CALLBACK _export
  2751. XAboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  2752. X{
  2753. X    switch (wMsg) {
  2754. X        case WM_INITDIALOG:
  2755. X            {
  2756. X            char buf[80];
  2757. X            GetWindowText(GetParent(hDlg),buf,80);
  2758. X            SetDlgItemText(hDlg, AB_TEXT1, buf);
  2759. X            SetDlgItemText(hDlg, AB_TEXT2, (LPSTR)lParam);
  2760. X#ifdef __DLL__
  2761. X            wsprintf(buf,"WGNUPLOT.DLL Version %s",(LPSTR)WGNUPLOTVERSION);
  2762. X            SetDlgItemText(hDlg, AB_TEXT3, buf);
  2763. X#endif
  2764. X            }
  2765. X            return TRUE;
  2766. X        case WM_DRAWITEM:
  2767. X            {
  2768. X            LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
  2769. X#ifdef WIN32
  2770. X            DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassLong(GetParent(hDlg), GCL_HICON));
  2771. X#else
  2772. X            DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassWord(GetParent(hDlg), GCW_HICON));
  2773. X#endif
  2774. X            }
  2775. X            return FALSE;
  2776. X        case WM_COMMAND:
  2777. X            switch (LOWORD(wParam)) {
  2778. X                case IDCANCEL:
  2779. X                case IDOK:
  2780. X                    EndDialog(hDlg, LOWORD(wParam));
  2781. X                    return TRUE;
  2782. X            }
  2783. X            break;
  2784. X    }
  2785. X    return FALSE;
  2786. X}
  2787. X
  2788. X
  2789. Xvoid WDPROC
  2790. XAboutBox(HWND hwnd, LPSTR str)
  2791. X{
  2792. XDLGPROC lpfnAboutDlgProc;
  2793. X#ifdef __DLL__
  2794. X    lpfnAboutDlgProc = (DLGPROC)GetProcAddress(hdllInstance, "AboutDlgProc");
  2795. X#else
  2796. X    lpfnAboutDlgProc = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, hdllInstance);
  2797. X#endif
  2798. X    DialogBoxParam(hdllInstance,"AboutDlgBox",hwnd,lpfnAboutDlgProc,(LPARAM)str);
  2799. X    EnableWindow(hwnd,TRUE);
  2800. X#ifndef __DLL__
  2801. X    FreeProcInstance((FARPROC)lpfnAboutDlgProc);
  2802. X#endif
  2803. X}
  2804. END_OF_FILE
  2805.   if test 49542 -ne `wc -c <'gnuplot/win/wtext.c'`; then
  2806.     echo shar: \"'gnuplot/win/wtext.c'\" unpacked with wrong size!
  2807.   fi
  2808.   # end of 'gnuplot/win/wtext.c'
  2809. fi
  2810. echo shar: End of archive 9 \(of 33\).
  2811. cp /dev/null ark9isdone
  2812. MISSING=""
  2813. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
  2814.     if test ! -f ark${I}isdone ; then
  2815.     MISSING="${MISSING} ${I}"
  2816.     fi
  2817. done
  2818. if test "${MISSING}" = "" ; then
  2819.     echo You have unpacked all 33 archives.
  2820.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2821. else
  2822.     echo You still must unpack the following archives:
  2823.     echo "        " ${MISSING}
  2824. fi
  2825. exit 0
  2826. exit 0 # Just in case...
  2827.