Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1574 lines
48 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* disp.c -- MW display routines */
  5. #define NOKEYSTATE
  6. #define NOSYSCOMMANDS
  7. #define NOSHOWWINDOW
  8. //#define NOATOM
  9. #define NOCLIPBOARD
  10. #define NOGDICAPMASKS
  11. #define NOCTLMGR
  12. #define NOWINSTYLES
  13. //#define NOVIRTUALKEYCODES
  14. #define NOSYSMETRICS
  15. #define NOMENUS
  16. #define NOSOUND
  17. #define NOCOMM
  18. #define NOOPENFILE
  19. #define NOWH
  20. #define NOWINOFFSETS
  21. #define NOMETAFILE
  22. #define NOMB
  23. #define NODRAWTEXT
  24. #include <windows.h>
  25. #define NOUAC
  26. #include "mw.h"
  27. #include "debug.h"
  28. #include "cmddefs.h"
  29. #include "dispdefs.h"
  30. #include "wwdefs.h"
  31. #define NOKCCODES /* Removes all kc code defines */
  32. #include "ch.h"
  33. #include "docdefs.h"
  34. #include "fmtdefs.h"
  35. #include "propdefs.h"
  36. #include "macro.h"
  37. #include "printdef.h"
  38. #include "fontdefs.h"
  39. #if defined(OLE)
  40. #include "obj.h"
  41. #endif
  42. #ifdef DBCS
  43. #include "dbcs.h"
  44. #endif
  45. #ifdef CASHMERE /* No VisiMode in WinMemo */
  46. extern int vfVisiMode;
  47. #endif /* CASHMERE */
  48. extern int vcchBlted;
  49. extern int vidxpInsertCache;
  50. extern int vdlIns;
  51. extern int vfInsLast;
  52. extern struct PAP vpapAbs;
  53. extern struct SEP vsepAbs;
  54. extern int rgval[];
  55. extern struct DOD (**hpdocdod)[];
  56. extern typeCP cpMacCur;
  57. extern int vfSelHidden;
  58. extern struct WWD rgwwd[];
  59. extern int wwCur, wwMac;
  60. extern struct FLI vfli;
  61. extern struct SEL selCur;
  62. extern struct WWD *pwwdCur;
  63. extern int docCur;
  64. extern struct CHP (**vhgchpFormat)[];
  65. extern int vichpFormat;
  66. extern typeCP cpMinCur;
  67. extern typeCP cpMinDocument;
  68. extern int vfInsertOn;
  69. extern int vfTextBltValid;
  70. extern typeCP vcpFirstParaCache;
  71. extern typeCP vcpLimParaCache;
  72. extern unsigned vpgn;
  73. extern struct SEP vsepAbs;
  74. extern CHAR stBuf[];
  75. extern typeCP CpEdge();
  76. extern typeCP CpMacText();
  77. extern int vdocPageCache;
  78. extern int vfPictSel;
  79. extern int vfAwfulNoise;
  80. extern int vfSkipNextBlink;
  81. extern int dypMax;
  82. extern HDC vhMDC;
  83. extern HWND vhWndPageInfo;
  84. extern struct FMI vfmiScreen;
  85. extern int docScrap;
  86. extern long rgbBkgrnd;
  87. extern long ropErase;
  88. extern BOOL vfMonochrome;
  89. extern int dxpbmMDC;
  90. extern int dypbmMDC;
  91. extern HBITMAP hbmNull;
  92. extern int vfOutOfMemory;
  93. extern int vfSeeSel;
  94. extern int vfInsEnd; /* Is insert point at end-of-line? */
  95. extern int vipgd;
  96. extern typeCP vcpMinPageCache;
  97. extern typeCP vcpMacPageCache;
  98. /* actual position of the cursor line */
  99. extern int vxpCursLine;
  100. extern int vypCursLine;
  101. extern int vdypCursLine;
  102. extern int vfScrollInval; /* means scroll did not take and UpdateWw must be repeated */
  103. extern BOOL vfDead;
  104. extern HRGN vhrgnClip;
  105. /* G L O B A L S
  106. int dlsMac = 0;*/
  107. #ifdef DBCS
  108. int donteat = 0; /* propagate not to eat message */
  109. #endif
  110. /* D I S P L A Y F L I */
  111. /* Display formatted line in window ww at line dl */
  112. DisplayFli(ww, dl, fDontDisplay)
  113. int ww;
  114. int dl;
  115. int fDontDisplay; /* True if we set up dl info but don't display */
  116. {
  117. #ifdef KOREA // jinwoo: 92, 9, 28
  118. /* process Subscript separatedly from descent */
  119. #ifdef NODESC
  120. extern int isSubs;
  121. #endif
  122. #endif
  123. typeCP dcp;
  124. typeCP dcpMac;
  125. struct WWD *pwwd = &rgwwd[ww];
  126. HDC hDC = pwwd->hDC;
  127. int xp; /* Current xp to write text */
  128. int yp; /* Current yp to write text */
  129. int xpMin = pwwd->xpMin; /* Minimum xp in window */
  130. int xpMac = pwwd->xpMac; /* Maximum xp in window */
  131. int ypLine; /* Screen yp for current line */
  132. int dxp; /* Width of current run */
  133. int dyp; /* Line height */
  134. int dxpExtra; /* Width of pad for each space */
  135. typeCP cpMin;
  136. typeCP cpMac;
  137. int xpSel; /* xp of the start of the selection */
  138. int dxpSel = 0; /* Width of the selection. */
  139. CHAR chMark = '\0'; /* style character */
  140. struct CHP *pchp;
  141. BOOL fTabsKludge = (vfli.ichLastTab >= 0);
  142. BOOL fInsertOn = FALSE;
  143. int cBreakRun; /* break characters in run (no relation to Dick or Jane) */
  144. #ifdef SMFONT
  145. RECT rcOpaque;
  146. #endif /* SMFONT */
  147. #ifdef DDISP
  148. CommSzNumNum(" DisplayFli: dl/fDontDisplay ", dl, fDontDisplay);
  149. #endif
  150. Assert(ww >= 0 && ww < wwMax);
  151. #ifdef SMFONT
  152. Assert(!fDontDisplay || vfli.fGraphics)
  153. #endif /* SMFONT */
  154. Scribble(5,'D');
  155. /* Fill up EDL and set some useful locals */
  156. {
  157. register struct EDL *pedl = &(**pwwd->hdndl)[dl];
  158. if (dl == vdlIns)
  159. {
  160. /* Overwriting chars blted during fast insert; reset blt count */
  161. vcchBlted = 0;
  162. vidxpInsertCache = -1;
  163. }
  164. pedl->xpLeft = vfli.xpLeft;
  165. pedl->xpMac = vfli.xpReal;
  166. cpMin = pedl->cpMin = vfli.cpMin;
  167. pedl->dcpMac = (cpMac = vfli.cpMac) - cpMin;
  168. dyp = pedl->dyp = vfli.dypLine;
  169. pedl->ichCpMin = vfli.ichCpMin;
  170. pedl->dcpDepend = (cpMin == cpMac) ? 0xff : vfli.dcpDepend;
  171. pedl->fValid = TRUE;
  172. pedl->fGraphics = vfli.fGraphics;
  173. pedl->fSplat = vfli.fSplat;
  174. /* The position of current line equals the position of the previous line
  175. + height of this line. */
  176. #ifdef SMFONT
  177. pedl->yp = rcOpaque.bottom = dyp + (ypLine = rcOpaque.top = (dl == 0 ?
  178. pwwd->ypMin : (pedl - 1)->yp));
  179. #else /* not SMFONT */
  180. pedl->yp = dyp + (ypLine = (dl == 0 ? pwwd->ypMin :
  181. (pedl - 1)->yp));
  182. #endif /* SMFONT */
  183. if (pedl->fIchCpIncr = (vfli.ichCpMac != 0))
  184. {
  185. /* Look at final text column */
  186. ++cpMac;
  187. /* Since this is true, we can compress pedl->ichCpMac to 1 bit. */
  188. Assert(vfli.ichCpMac == pedl->ichCpMin + 1);
  189. }
  190. }
  191. if (vfli.doc == docNil)
  192. {
  193. /* This is the space beyond the end mark. */
  194. PatBlt(hDC, 0, ypLine, xpMac, dyp, ropErase);
  195. goto Finished;
  196. }
  197. /* Is there a character in the "style bar"? */
  198. if (cpMin != cpMac)
  199. {
  200. #ifdef CASHMERE
  201. /* This line is not completely empty (not after the end mark); check for
  202. painting marks on the style bar. */
  203. if (cpMin == vcpFirstParaCache && vpapAbs.rhc != 0)
  204. {
  205. /* This is a running-head. */
  206. chMark = chStatRH;
  207. }
  208. else if ((**hpdocdod)[vfli.doc].hpgtb != 0)
  209. #else /* not CASHMERE */
  210. if (vpapAbs.rhc == 0 && (**hpdocdod)[vfli.doc].hpgtb != 0)
  211. #endif /* CASHMERE */
  212. {
  213. if (vdocPageCache != vfli.doc || cpMac > vcpMacPageCache || cpMac <=
  214. vcpMinPageCache)
  215. {
  216. CachePage(vfli.doc, cpMac - 1);
  217. }
  218. /* We are now guaranteed that cpMac is within the cached page. */
  219. if (cpMin <= vcpMinPageCache && (!vfli.fGraphics || vfli.ichCpMin ==
  220. 0))
  221. {
  222. /* This is the first line of new page; show page mark. */
  223. chMark = chStatPage;
  224. }
  225. }
  226. }
  227. #ifdef SMFONT
  228. #ifdef DDISP
  229. /* black out this line to test how efficiently/correctly we
  230. overwrite pixels from previously-resident lines of text */
  231. PatBlt(hDC, 0, ypLine, xpMac, dyp, BLACKNESS);
  232. { long int i; for (i=0; i < 500000; i++) ; }
  233. #endif
  234. /* Calculate dcpMac now, so we might be able to know how much to erase. */
  235. dcpMac = vfli.fSplat ? vfli.ichMac : vfli.ichReal;
  236. /* Erase any character that might be in the style bar. */
  237. dxp = xpSelBar + 1;
  238. if (!vfli.fGraphics)
  239. {
  240. dxp = xpMac; // clear the whole line
  241. }
  242. PatBlt(hDC, 0, ypLine, dxp, dyp, ropErase);
  243. /* If this is graphics then go draw any characters in the style bar. */
  244. if (vfli.fGraphics)
  245. {
  246. goto DrawMark;
  247. }
  248. /* If there are no "real" characters on this line then we can skip alot of
  249. this. */
  250. if (dcpMac == 0)
  251. {
  252. goto EndLine2;
  253. }
  254. #else /* not SMFONT */
  255. if (vfli.fGraphics || fDontDisplay)
  256. {
  257. /* Erase any character that might be in the style bar. */
  258. PatBlt(hDC, 0, ypLine, xpSelBar, dyp, ropErase);
  259. goto DrawMark;
  260. }
  261. #endif /* SMFONT */
  262. ValidateMemoryDC();
  263. if (vhMDC == NULL)
  264. {
  265. Error:
  266. /* Notify the user that an error has occured and simply erase this line.
  267. */
  268. WinFailure();
  269. PatBlt(hDC, xpSelBar, ypLine, xpMac - xpSelBar, dyp, ropErase);
  270. goto Finished;
  271. }
  272. #ifndef SMFONT
  273. /* Create a new bitmap for the memory DC if the current bitmap is not big
  274. enough. */
  275. if (xpMac > dxpbmMDC || dyp > dypbmMDC)
  276. {
  277. HBITMAP hbm;
  278. /* If there is an old bitmap, then delete it. */
  279. if (dxpbmMDC != 0 || dypbmMDC != 0)
  280. {
  281. DeleteObject(SelectObject(vhMDC, hbmNull));
  282. }
  283. /* Create the new bitmap and select it in. */
  284. if ((hbm = CreateBitmap(dxpbmMDC = xpMac, dypbmMDC = dyp, 1, 1,
  285. (LPSTR)NULL)) == NULL)
  286. {
  287. /* There should be a graceful way to recover if the bitmap is ever
  288. NULL (e.g we don't have enough memory for it). */
  289. dxpbmMDC = dypbmMDC = 0;
  290. goto Error;
  291. }
  292. SelectObject(vhMDC, hbm);
  293. }
  294. /* Erase the are of the bitmap we are going to use. */
  295. PatBlt(vhMDC, xpSelBar, 0, xpMac, dyp, vfMonochrome ? ropErase : WHITENESS);
  296. #endif /* not SMFONT */
  297. /* Initialize some of the variables we'll need. */
  298. pchp = &(**vhgchpFormat)[0];
  299. #ifdef SMFONT
  300. xp = rcOpaque.left = rcOpaque.right = vfli.xpLeft + xpSelBar - xpMin + 1;
  301. #else /* not SMFONT */
  302. dcpMac = vfli.fSplat ? vfli.ichMac : vfli.ichReal;
  303. xp = vfli.xpLeft + xpSelBar - xpMin + 1;
  304. #endif /* SMFONT */
  305. dxpExtra = fTabsKludge ? 0 : vfli.dxpExtra;
  306. #ifdef SMFONT
  307. /* If we are horizontally scrolled, then set the clip area to the area
  308. outside of the selection bar. */
  309. if (xpMin != 0)
  310. {
  311. IntersectClipRect(hDC, xpSelBar, rcOpaque.top, xpMac, rcOpaque.bottom);
  312. }
  313. #endif /* SMFONT */
  314. for (dcp = 0; dcp < dcpMac; pchp++)
  315. {
  316. /* For all runs do: */
  317. int ichFirst; /* First character in the current run */
  318. int cchRun; /* Number of characters in the current run */
  319. dcp = ichFirst = pchp->ichRun;
  320. dcp += pchp->cchRun;
  321. if (dcp > dcpMac)
  322. {
  323. dcp = dcpMac;
  324. }
  325. cchRun = dcp - ichFirst;
  326. /* Compute dxp = sum of width of characters in current run (formerly
  327. DxaFromIcpDcp). */
  328. {
  329. register int *pdxp;
  330. register int cchT = cchRun;
  331. PCH pch = vfli.rgch + ichFirst;
  332. dxp = cBreakRun = 0;
  333. pdxp = &vfli.rgdxp[ichFirst];
  334. while (cchT-- > 0)
  335. {
  336. dxp += *pdxp++;
  337. if (*pch++ == chSpace)
  338. ++cBreakRun;
  339. }
  340. #ifdef DDISP
  341. CommSzNum(" dxp=",dxp);
  342. #endif
  343. }
  344. if (dxp > 0)
  345. {
  346. int cchDone;
  347. PCH pch = &vfli.rgch[ichFirst];
  348. #ifdef KOREA //920525 KDLEE; jinwoo: 92, 9, 28
  349. #ifdef NODESC
  350. TEXTMETRIC tm;
  351. #endif
  352. #endif //KOREA
  353. LoadFont(vfli.doc, pchp, mdFontScreen);
  354. #ifdef KOREA //KDLEE 920525; jinwoo: 92, 9, 28
  355. #ifdef NODESC
  356. GetTextMetrics (vhMDC, (LPTEXTMETRIC)&tm);
  357. if (tm.tmCharSet==HANGEUL_CHARSET)
  358. yp = dyp - (vfli.dypBase/3) -((pchp->hpsPos != 0 ? (pchp->hpsPos <
  359. hpsNegMin ? ypSubSuper : -ypSubSuper) : 0)) -
  360. vfmiScreen.dypBaseline - (isSubs ? ypSubSuper : 0);
  361. else
  362. yp = (dyp - (vfli.dypBase + (pchp->hpsPos != 0 ? (pchp->hpsPos <
  363. hpsNegMin ? ypSubSuper : -ypSubSuper) : 0))) -
  364. vfmiScreen.dypBaseline - (isSubs ? ypSubSuper : 0);
  365. #else /* NODESC */
  366. yp = (dyp - (vfli.dypBase + (pchp->hpsPos != 0 ? (pchp->hpsPos <
  367. hpsNegMin ? ypSubSuper : -ypSubSuper) : 0))) -
  368. vfmiScreen.dypBaseline;
  369. #endif /* NODESC */
  370. #else /* KOREA */
  371. yp = (dyp - (vfli.dypBase + (pchp->hpsPos != 0 ? (pchp->hpsPos <
  372. hpsNegMin ? ypSubSuper : -ypSubSuper) : 0))) -
  373. vfmiScreen.dypBaseline;
  374. #endif // KOREA jinwoo: 92, 9, 28
  375. /* Note: tabs and other special characters are guaranteed to come at
  376. the start of a run. */
  377. SetTextJustification(vhMDC, dxpExtra * cBreakRun, cBreakRun);
  378. #ifdef SMFONT
  379. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  380. #endif /* SMFONT */
  381. cchDone = 0;
  382. while (cchDone < cchRun)
  383. {
  384. int cch;
  385. /* Does the wide-space zone begin in this run? */
  386. if (vfli.fAdjSpace && (vfli.ichFirstWide < ichFirst + cchRun) &&
  387. (ichFirst + cchDone <= vfli.ichFirstWide))
  388. {
  389. int cchDoneT = cchDone;
  390. /* Is this the beginning of the wide-space zone? */
  391. if (ichFirst + cchDone == vfli.ichFirstWide)
  392. {
  393. /* Reset the width of the spaces. */
  394. SetTextJustification(vhMDC, ++dxpExtra * cBreakRun, cBreakRun);
  395. #ifdef SMFONT
  396. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  397. #endif /* SMFONT */
  398. cch = cchRun - cchDone;
  399. cchDone = cchRun;
  400. }
  401. else
  402. {
  403. cchDone = cch = vfli.ichFirstWide - ichFirst;
  404. }
  405. /* This run is cut short because of a wide space, so we need
  406. to calculate a new width. */
  407. {
  408. register int *pdxp;
  409. register int cchT = cch;
  410. PCH pch = &vfli.rgch[ichFirst + cchDoneT];
  411. dxp = 0;
  412. pdxp = &vfli.rgdxp[ichFirst + cchDoneT];
  413. while (cchT-- > 0)
  414. {
  415. dxp += *pdxp++;
  416. if (*pch++ == chSpace)
  417. ++cBreakRun;
  418. }
  419. }
  420. }
  421. else
  422. {
  423. cchDone = cch = cchRun;
  424. }
  425. while (cch > 0)
  426. {
  427. switch (*pch)
  428. {
  429. CHAR ch;
  430. int dxpT;
  431. case chTab:
  432. #ifdef CASHMERE
  433. /* chLeader contains tab leader character (see
  434. FormatLine) */
  435. if ((ch = pchp->chLeader) != chSpace)
  436. {
  437. int cxpTab;
  438. CHAR rgch[32];
  439. int dxpLeader = CharWidth(ch);
  440. int xpT = xp;
  441. int iLevelT = SaveDC(vhMDC);
  442. SetBytes(&rgch[0], ch, 32);
  443. dxpT = vfli.rgdxp[ichFirst];
  444. cxpTab = ((dxpT + dxpLeader - 1) / dxpLeader + 31)
  445. >> 5;
  446. xp += dxpT;
  447. while (cxpTab-- > 0)
  448. {
  449. TextOut(vhMDC, xpT, yp, (LPSTR)rgch, 32);
  450. xpT += dxpLeader << 5;
  451. }
  452. RestoreDC(vhMDC, iLevelT);
  453. }
  454. else
  455. #endif /* CASHMERE */
  456. {
  457. #ifdef SMFONT
  458. /* Expand the opaque rectangle to include the tab.
  459. */
  460. rcOpaque.right += vfli.rgdxp[ichFirst];
  461. #endif /* SMFONT */
  462. xp += vfli.rgdxp[ichFirst];
  463. }
  464. if (fTabsKludge && ichFirst >= vfli.ichLastTab)
  465. {
  466. SetTextJustification(vhMDC, (dxpExtra =
  467. vfli.dxpExtra) * cBreakRun, cBreakRun);
  468. #ifdef SMFONT
  469. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  470. #endif /* SMFONT */
  471. fTabsKludge = FALSE;
  472. }
  473. dxp -= vfli.rgdxp[ichFirst];
  474. pch++;
  475. cch--;
  476. goto EndLoop;
  477. #ifdef CASHMERE
  478. case schPage:
  479. if (!pchp->fSpecial)
  480. {
  481. goto EndLoop;
  482. }
  483. stBuf[0] = CchExpPgn(&stBuf[1], vpgn, vsepAbs.nfcPgn,
  484. flmSandMode, ichMaxLine);
  485. goto DrawSpecial;
  486. case schFootnote:
  487. if (!pchp->fSpecial)
  488. {
  489. goto EndLoop;
  490. }
  491. stBuf[0] = CchExpFtn(&stBuf[1], cpMin + ichFirst,
  492. flmSandMode, ichMaxLine);
  493. DrawSpecial:
  494. #else /* not CASHMERE */
  495. case schPage:
  496. case schFootnote:
  497. if (!pchp->fSpecial)
  498. {
  499. goto EndLoop;
  500. }
  501. stBuf[0] = *pch == schPage && (wwdCurrentDoc.fEditHeader
  502. || wwdCurrentDoc.fEditFooter) ? CchExpPgn(&stBuf[1],
  503. vpgn, 0, flmSandMode, ichMaxLine) :
  504. CchExpUnknown(&stBuf[1], flmSandMode, ichMaxLine);
  505. #endif /* not CASHMERE */
  506. #ifdef SMFONT
  507. /* Calculate the opaque rectangle. */
  508. rcOpaque.right += vfli.rgdxp[ichFirst] +
  509. vfmiScreen.dxpOverhang;
  510. TextOut(hDC, xp, ypLine+yp, &stBuf[1], stBuf[0]);
  511. #else /* not SMFONT */
  512. TextOut(vhMDC, xp, yp, (LPSTR)&stBuf[1], stBuf[0]);
  513. #endif /* SMFONT */
  514. break;
  515. default:
  516. goto EndLoop;
  517. }
  518. dxp -= vfli.rgdxp[ichFirst];
  519. #ifdef SMFONT
  520. /* End the line if no more will fit into the window. */
  521. if ((xp += vfli.rgdxp[ichFirst++]) >= xpMac) {
  522. goto EndLine;
  523. }
  524. rcOpaque.left = (rcOpaque.right = xp) +
  525. vfmiScreen.dxpOverhang;
  526. #else /* not SMFONT */
  527. xp += vfli.rgdxp[ichFirst++];
  528. #endif /* SMFONT */
  529. pch++;
  530. cch--;
  531. }
  532. EndLoop:
  533. #ifdef SMFONT
  534. if (cch == 0)
  535. {
  536. Assert(dxp == 0);
  537. }
  538. else
  539. {
  540. /* Calculate the opaque rectangle. */
  541. rcOpaque.right += dxp + vfmiScreen.dxpOverhang;
  542. #if 0
  543. {
  544. char msg[180];
  545. wsprintf(msg,"putting out %d characters\n\r",cch);
  546. OutputDebugString(msg);
  547. }
  548. #endif
  549. /* Output cch characters starting at pch */
  550. TextOut(hDC, xp, ypLine+yp, pch, cch);
  551. /* End the line if no more will fit into the window. */
  552. if ((xp += dxp) >= xpMac)
  553. {
  554. goto EndLine;
  555. }
  556. rcOpaque.left = (rcOpaque.right = xp) +
  557. vfmiScreen.dxpOverhang;
  558. pch += cch;
  559. }
  560. #else /* not SMFONT */
  561. /* Output cch characters starting at pch */
  562. TextOut(vhMDC, xp, yp, (LPSTR)pch, cch);
  563. xp += dxp;
  564. pch += cch;
  565. #endif /* SMFONT */
  566. } /* end while (cchDone<cchRun) */
  567. } /* end if (dxp>0) */
  568. } /* end for dcp=0..dcpMac */
  569. #ifdef SMFONT
  570. EndLine:
  571. /* Restore the clip region if need be. */
  572. if (xpMin != 0)
  573. {
  574. SelectClipRgn(hDC, NULL);
  575. }
  576. EndLine2:
  577. #endif /* SMFONT */
  578. #ifdef CASHMERE
  579. if (vfVisiMode)
  580. {
  581. AddVisiSpaces(ww, &(**pwwd->hdndl)[dl], vfli.dypBase, vfli.dypAfter +
  582. vfli.dypFont);
  583. }
  584. #endif /* CASHMERE */
  585. vfTextBltValid = FALSE;
  586. if ((ww == wwCur) && (pwwd->doc != docScrap) && !vfSelHidden &&
  587. (selCur.cpLim >= cpMin))
  588. {
  589. if (selCur.cpFirst <= cpMac)
  590. {
  591. /* Show selection */
  592. int xpFirst;
  593. int xpLim;
  594. #ifdef ENABLE
  595. if (vfli.fSplatNext && selCur.cpFirst == selCur.cpLim &&
  596. selCur.cpFirst == cpMac)
  597. {
  598. vfInsEnd = TRUE;
  599. ClearInsertLine();
  600. }
  601. vfInsertOn = FALSE;
  602. #endif /* ENABLE */
  603. if (selCur.cpFirst <= cpMin && selCur.cpLim >= cpMac)
  604. {
  605. xpFirst = vfli.xpLeft;
  606. xpLim = vfli.xpReal;
  607. }
  608. else if (selCur.cpFirst < cpMac || (selCur.cpLim == cpMac &&
  609. vfInsEnd))
  610. {
  611. typeCP cpBegin = CpMax(cpMin, selCur.cpFirst);
  612. typeCP cpEnd = CpMin(cpMac, selCur.cpLim);
  613. dxp = DxpDiff((int)(cpBegin - cpMin), (int)(cpEnd - cpBegin),
  614. &xpFirst);
  615. xpLim = min(xpMin + vfli.xpReal, xpFirst + dxp);
  616. }
  617. else
  618. {
  619. goto DidntHighlight;
  620. }
  621. xpSel = xpSelBar + max(xpFirst - xpMin, 0);
  622. if (xpLim > xpFirst)
  623. {
  624. /* Set highlighting at desired screen position. */
  625. dxpSel = max(xpLim - max(xpFirst, xpMin), 0);
  626. }
  627. else if (selCur.cpFirst == selCur.cpLim && ((selCur.cpLim != cpMac)
  628. ^ vfInsEnd))
  629. {
  630. vfInsertOn = FALSE; /* Because we redisplayed insert pt line */
  631. #ifdef CASHMERE
  632. vdypCursLine = min(vfli.dypFont, vfli.dypLine - vfli.dypAfter);
  633. vypCursLine = ypLine + dyp - vfli.dypAfter;
  634. #else /* not CASHMERE */
  635. vdypCursLine = vfli.dypFont;
  636. vypCursLine = ypLine + dyp;
  637. #endif /* not CASHMERE */
  638. vxpCursLine = xpSel;
  639. /* Start blinking in a while */
  640. vfSkipNextBlink = TRUE;
  641. fInsertOn = xpFirst >= xpMin;
  642. }
  643. DidntHighlight:;
  644. }
  645. }
  646. #ifdef SMFONT
  647. /* Invert the selection */
  648. if (dxpSel != 0) {
  649. PatBlt(hDC, xpSel, ypLine, dxpSel, dyp, DSTINVERT);
  650. }
  651. #else /* not SMFONT */
  652. /* Blt the line of text onto the screen. */
  653. PatBlt(vhMDC, 0, 0, xpSelBar, dyp, vfMonochrome ? ropErase : WHITENESS);
  654. if (dxpSel == 0)
  655. {
  656. BitBlt(hDC, 0, ypLine, xpMac, dyp, vhMDC, 0, 0, SRCCOPY);
  657. }
  658. else
  659. {
  660. BitBlt(hDC, 0, ypLine, xpSel, dyp, vhMDC, 0, 0, SRCCOPY);
  661. BitBlt(hDC, xpSel, ypLine, dxpSel, dyp, vhMDC, xpSel, 0, NOTSRCCOPY);
  662. xpSel += dxpSel;
  663. BitBlt(hDC, xpSel, ypLine, xpMac - xpSel, dyp, vhMDC, xpSel, 0,
  664. SRCCOPY);
  665. }
  666. #endif /* SMFONT */
  667. /* Draw the insertion bar if necessary. */
  668. if (fInsertOn)
  669. {
  670. DrawInsertLine();
  671. }
  672. DrawMark:
  673. /* Draw the character in the style bar if necessary. */
  674. if (chMark != '\0')
  675. {
  676. #ifdef SYSENDMARK
  677. struct CHP chpT;
  678. extern struct CHP vchpNormal;
  679. blt(&vchpNormal, &chpT, cwCHP);
  680. chpT.ftc = ftcSystem;
  681. chpT.ftcXtra = 0;
  682. chpT.hps = hpsDefault;
  683. /* Draw the style character in the standard font. */
  684. LoadFont(vfli.doc, &chpT, mdFontScreen);
  685. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  686. (LPSTR)&chMark, 1);
  687. #else /* ifdef SYSENDMARK */
  688. /* Draw the style character in the standard font. */
  689. LoadFont(vfli.doc, NULL, mdFontScreen);
  690. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  691. (LPSTR)&chMark, 1);
  692. #endif /* if-else-def SYSENDMARK */
  693. }
  694. if (vfli.fGraphics)
  695. {
  696. DisplayGraphics(ww, dl, fDontDisplay);
  697. }
  698. Finished:
  699. Scribble(5,' ');
  700. }
  701. /* D X P D I F F */
  702. DxpDiff(dcpFirst, dcp, pdxpFirst)
  703. int dcpFirst;
  704. int dcp;
  705. int *pdxpFirst;
  706. {
  707. #if 1
  708. register int *pdxp = &vfli.rgdxp[0];
  709. register int cch;
  710. int dxp = vfli.xpLeft;
  711. #ifdef ENABLE /* Not used */
  712. int ichLim = dcpFirst + dcp;
  713. #endif
  714. if (dcp > vfli.ichMac - dcpFirst)
  715. { /* This should not be, but is when we have a CR */
  716. //Assert( dcpFirst < vfli.ichMac );
  717. dcp = vfli.ichMac - dcpFirst;
  718. }
  719. for (cch = 0; cch < dcpFirst; ++cch)
  720. {
  721. dxp += *pdxp++;
  722. }
  723. *pdxpFirst = dxp;
  724. dxp = 0;
  725. for (cch = 0; cch < dcp; ++cch)
  726. {
  727. dxp += *pdxp++;
  728. }
  729. return dxp;
  730. #else
  731. int dxp;
  732. if (dcp > vfli.ichMac - dcpFirst)
  733. { /* This should not be, but is when we have a CR */
  734. Assert( dcpFirst < vfli.ichMac );
  735. dcp = vfli.ichMac - dcpFirst;
  736. }
  737. /* first get space up to first character */
  738. *pdxpFirst = LOWORD(GetTextExtent(hDC,vfli.rgch,dcpFirst)) + vfli.xpLeft;
  739. /* now get space between first and first+dcp */
  740. dxp = LOWORD(GetTextExtent(hDC,vfli.rgch+dcpFirst,dcp));
  741. return dxp;
  742. #endif
  743. }
  744. UpdateDisplay(fAbortOK)
  745. int fAbortOK;
  746. {
  747. int ww;
  748. if (wwMac <= 0)
  749. {
  750. return;
  751. }
  752. #ifdef CASHMERE
  753. for (ww = 0; ww < wwMac; ww++)
  754. if ( rgwwd[ww].doc != docScrap )
  755. {
  756. UpdateWw(ww, fAbortOK);
  757. if (rgwwd[ww].fDirty || vfOutOfMemory)
  758. {
  759. return; /* update has been interrupted */
  760. }
  761. }
  762. #else /* not CASHMERE */
  763. UpdateWw(wwDocument, fAbortOK);
  764. if (wwdCurrentDoc.fDirty || vfOutOfMemory)
  765. {
  766. /* Update has been interrupted */
  767. return;
  768. }
  769. #endif /* not CASHMERE */
  770. if (wwdCurrentDoc.fRuler)
  771. {
  772. UpdateRuler();
  773. }
  774. }
  775. /* U P D A T E W W */
  776. UpdateWw(ww, fAbortOK)
  777. int ww, fAbortOK;
  778. { /* Redisplay ww as necessary */
  779. extern int vfWholePictInvalid;
  780. register struct WWD *pwwd = &rgwwd[ww];
  781. int dlMac;
  782. int dlOld, dlNew;
  783. int doc;
  784. int ichCp;
  785. struct EDL *pedlNew;
  786. register struct EDL *pedl;
  787. struct EDL (**hdndl)[]=pwwd->hdndl;
  788. int dypDiff;
  789. int ypTop;
  790. int ypFirstInval;
  791. int dr;
  792. int fLastNotShown;
  793. typeCP cp, cpMacWw;
  794. if (!pwwd->fDirty)
  795. {
  796. return;
  797. }
  798. if (!((**hpdocdod)[pwwd->doc].fDisplayable))
  799. return;
  800. if (fAbortOK && FImportantMsgPresent())
  801. return;
  802. #if 0 // how to get first and last cp's in invalid rect?
  803. #if defined(OLE)
  804. /*
  805. Load visible objects. Do it now rather than in DisplayGraphics()
  806. because here it has less chance of disrupting the state variables
  807. upon which UpdateWw depends.
  808. */
  809. ObjEnumInRange(docCur,cpMinCur,cpMacCur,ObjLoadObjectInDoc);
  810. #endif
  811. #endif
  812. dlMac = pwwd->dlMac;
  813. ypTop = pwwd->ypMin;
  814. Assert( ww >= 0 && ww < wwMax );
  815. vfli.doc = docNil; /* An aid to Fast Insert */
  816. UpdateInvalid(); /* InvalBand for what Windows considers to be invalid */
  817. ypFirstInval = pwwd->ypFirstInval;
  818. #ifndef CASHMERE
  819. Assert( ww == wwCur ); /* A MEMO-only assumption */
  820. #endif /* CASHMERE */
  821. Scribble(5, 'U');
  822. ValidateMemoryDC(); /* to do any update, we need a good memory DC */
  823. if (vhMDC == NULL)
  824. {
  825. WinFailure();
  826. return;
  827. }
  828. doc = pwwd->doc;
  829. vfli.doc = docNil;
  830. if (pwwd->fCpBad)
  831. {
  832. /* cp first displayed has not been blessed */
  833. #ifdef CASHMERE /* Must do this if ww != wwCur assertion is FALSE */
  834. int wwT = wwCur;
  835. if (ww != wwCur && wwCur >= 0)
  836. /* CtrBackTrs cache is only good for wwCur. Treat != case */
  837. {
  838. if (pwwdCur->fDirty) /* Do wwCur first, saving cache */
  839. UpdateWw(wwCur, fAbortOK);
  840. if (fAbortOK && FImportantMsgPresent())
  841. return;
  842. ChangeWw(ww, false);
  843. CtrBackDypCtr( 0, 0 ); /* Validate pwwdCur->cpFirst */
  844. ChangeWw(wwT, false);
  845. }
  846. else
  847. #endif /* CASHMERE */
  848. {
  849. if (fAbortOK && FImportantMsgPresent())
  850. return;
  851. CtrBackDypCtr( 0, 0 ); /* Validate pwwdCur->cpFirst */
  852. }
  853. }
  854. /* check for cpMin accessible in this ww */
  855. RestartUpdate:
  856. vfWholePictInvalid = fTrue; /* Tells DisplayGraphics to
  857. abandon accumulated partial pict rect */
  858. fLastNotShown = fFalse;
  859. cp = CpMax(pwwd->cpMin, pwwd->cpFirst);
  860. cpMacWw = pwwd->cpMac;
  861. ichCp = pwwd->ichCpFirst;
  862. /* Note test for dlNew==0 that guarantees that there will be at least
  863. one dl -- this was added for WRITE because we do not have
  864. the ability to enforce a minimum window size */
  865. for (dlNew = dlOld = 0; ypTop < pwwd->ypMac || (dlNew == 0) ; dlNew++)
  866. /* we have: cp, ichCP: pints to text desired on the coming line dlNew
  867. ypTop: desired position for top of dlNew -1
  868. dlOld: next line to be considered for re-use
  869. */
  870. /* check for having to extend dndl array */
  871. {
  872. if (dlNew >= (int)pwwd->dlMax)
  873. {
  874. /* extend the array with uninitialized dl's, increment max, break if no space.
  875. We assume that dlMac(Old) was <= dlMax, so the dl's will not be looked at
  876. but used only to store new lines */
  877. #define ddlIncr 5
  878. if (!FChngSizeH(hdndl, (pwwd->dlMax + ddlIncr) * cwEDL, fFalse))
  879. break;
  880. pwwd->dlMax += ddlIncr;
  881. }
  882. /* discard unusable dl's */
  883. for (; dlOld < dlMac; dlOld++)
  884. { /* Set dlOld and pedl to the next good dl */
  885. int ypTopOld, ypOld;
  886. /* Re-entrant Heap Movement */
  887. if (fAbortOK && !fLastNotShown && FImportantMsgPresent())
  888. goto RetInval;
  889. pedl = &(**hdndl)[dlOld];
  890. ypOld = pedl->yp;
  891. /* loop if: invalid, passed over in cp space, passed over in dl space,
  892. passed over in yp space,
  893. in invalid band, passed over in ich space */
  894. if (!pedl->fValid || dlOld < dlNew || pedl->cpMin < cp
  895. || (ypTopOld = (ypOld - pedl->dyp)) < ypTop
  896. || (ypOld >= ypFirstInval && ypTopOld <= pwwd->ypLastInval)
  897. || (pedl->cpMin == cp && pedl->ichCpMin < ichCp))
  898. continue;
  899. /* now we have dlOld, an acceptable if not necessarily useful dl.
  900. now compute dlNew either from scratch or by re-using dlOld. To be
  901. re-useable, dlOld must have right cp/ichCp pair, plus be totally on screen
  902. or, if it is a partial line, it must stay still or move down - not up */
  903. if (pedl->cpMin == cp && pedl->ichCpMin == ichCp &&
  904. (ypOld <= pwwd->ypMac || ypTopOld <= ypTop))
  905. {
  906. /* Re-use this dl */
  907. int yp = ypTop;
  908. if (fLastNotShown)
  909. {
  910. /* HEAP MOVEMENT */
  911. DisplayFli(ww, dlNew - 1, fLastNotShown = fFalse);
  912. pedl = &(**hdndl)[dlOld];
  913. }
  914. cp = pedl->cpMin + pedl->dcpMac;
  915. ichCp = pedl->fIchCpIncr ? pedl->ichCpMin + 1 : 0;
  916. ypTop += pedl->dyp;
  917. if (dlOld != dlNew || ypTopOld != yp)
  918. {
  919. DypScroll(ww, dlOld, dlNew - dlOld, yp);
  920. if (vfScrollInval)
  921. {
  922. /* There was a popup; invalid region might have changed */
  923. /* fLastNotShown test is for interrupting picture display */
  924. /* before we've really displayed it */
  925. (**hdndl) [dlOld].fValid = fFalse;
  926. goto Restart1;
  927. }
  928. dlMac += dlNew - dlOld;
  929. }
  930. dlOld = dlNew + 1;
  931. goto NextDlNew;
  932. }
  933. break;
  934. }
  935. /* cpMin > cp, the line is not anywhere so it will have to be formatted
  936. from scratch */
  937. if (fAbortOK && !fLastNotShown && FImportantMsgPresent())
  938. goto RetInval;
  939. FormatLine(doc, cp, ichCp, cpMacWw, flmSandMode); /* Creates vfli */
  940. if (vfOutOfMemory)
  941. goto RetInval;
  942. ichCp = vfli.ichCpMac;
  943. cp = vfli.cpMac;
  944. /* advance invalid band so that update can resume after an interruption */
  945. pwwd->ypFirstInval = (ypTop += vfli.dypLine);
  946. pedl = &(**hdndl)[dlOld];
  947. if (dlOld < dlMac && pedl->cpMin == cp && pedl->ichCpMin == ichCp)
  948. {
  949. int dlT = dlOld;
  950. /* line at dlOld is a valid, existing line that will abutt the line just about
  951. to be displayed. */
  952. if (dlOld == dlNew && pedl->yp - pedl->dyp <= ypTop)
  953. /* the line about to be overwritten will be re-used in the next loop.
  954. Hence, it is worthwhile to save this line and its dl */
  955. DypScroll(ww, dlOld++, 1, ypTop);
  956. else
  957. /* Move the next line to its abutting position. We know that it has not yet been
  958. overwritten (yp, dlOld all > than ypTop, dlNew) */
  959. DypScroll(ww, dlOld, 0, ypTop);
  960. if (vfScrollInval)
  961. {
  962. /* There was a popup; invalid region might have changed */
  963. /* fLastNotShown test is for interrupting picture display */
  964. /* before we've really displayed it */
  965. (**hdndl) [dlT].fValid = fFalse;
  966. Restart1:
  967. if (fLastNotShown)
  968. {
  969. pwwd->ypFirstInval = pwwd->ypMin;
  970. }
  971. ypFirstInval = pwwd->ypFirstInval;
  972. ypTop = pwwd->ypMin;
  973. goto RestartUpdate;
  974. }
  975. }
  976. /* true in 3rd param means put off picture redisplay till later */
  977. /* condition: graphics & not last in picture & not last in y space and
  978. not in front of a invalid or valid transition in the picture */
  979. DisplayFli(ww, dlNew, fLastNotShown =
  980. (vfli.fGraphics && vfli.ichCpMac!=0 && ypTop < pwwd->ypMac));
  981. NextDlNew:;
  982. }
  983. Break1:
  984. pwwd->dlMac = dlNew;
  985. #ifdef CASHMERE
  986. /* condition is here to avoid swapping */
  987. if (pwwd->fSplit && rgwwd[pwwd->ww].fFtn)
  988. CalcFtnLimits(pwwd);
  989. #endif /* CASHMERE */
  990. SetCurWwVScrollPos(); /* Set Scroll bar position */
  991. vfTextBltValid = false;
  992. /* reset invalid indications */
  993. pwwd->fDirty = false;
  994. pwwd->ypFirstInval = ypMaxAll;
  995. pwwd->ypLastInval = 0; /* so that max in InvalBand will work */
  996. Scribble(5, ' ');
  997. goto Validate;
  998. /* Before returning from an interrupt, invalidate lines that were overwritten
  999. within the present update. */
  1000. RetInval:
  1001. Scribble(5, ' ');
  1002. for (; dlOld < dlMac; dlOld++)
  1003. {
  1004. pedl = &(**hdndl)[dlOld];
  1005. if ((pedl->yp - pedl->dyp) < ypTop)
  1006. pedl->fValid = fFalse;
  1007. else
  1008. break;
  1009. }
  1010. Validate: ;
  1011. #ifdef ENABLE /* We will let UpdateInvalid handle this in case
  1012. further invalidation occurred during the update */
  1013. { /* Tell Windows that the part we updated is valid */
  1014. RECT rc;
  1015. rc.left = 0;
  1016. rc.top = pwwd->ypMin;
  1017. rc.right = pwwd->xpMac;
  1018. rc.bottom = imin( pwwd->ypMac, ypTop );
  1019. ValidateRect( pwwd->wwptr, (LPRECT)&rc );
  1020. }
  1021. #endif
  1022. }
  1023. /* D Y P S C R O L L */
  1024. DypScroll(ww, dlFirst, ddl, ypTo)
  1025. int ww, dlFirst, ddl, ypTo;
  1026. {
  1027. /* Scroll dl's in a window, from dlFirst to end, down ddl lines (or up -ddl).
  1028. Bitmap is moved from top of dlFirst to ypTo. The yp's of the dl's are updated.
  1029. Returns the amount scrolled. (positive means down). */
  1030. register struct WWD *pwwd = &rgwwd[ww];
  1031. int dlMac;
  1032. int dlT;
  1033. int ypFrom;
  1034. int dypChange;
  1035. int cdlBelow;
  1036. struct EDL *pedl;
  1037. struct EDL *pedlT;
  1038. /* Do not call procedures while dndl is loaded up to avoid heap movement */
  1039. struct EDL *dndl = &(**(pwwd->hdndl))[0];
  1040. Assert( ww >= 0 && ww < wwMax );
  1041. vfScrollInval = fFalse;
  1042. /* Number of dl's below (and including) the first one to be scrolled */
  1043. cdlBelow = pwwd->dlMac - dlFirst;
  1044. pwwd->dlMac = min(pwwd->dlMac + ddl, pwwd->dlMax);
  1045. cdlBelow = max(0, min(cdlBelow, pwwd->dlMac - ddl - dlFirst));
  1046. pedlT = &dndl[dlFirst];
  1047. ypFrom = pedlT->yp - pedlT->dyp;
  1048. /* Length of area to be moved */
  1049. dypChange = ypTo - ypFrom;
  1050. if (cdlBelow > 0)
  1051. {
  1052. int dlTo = dlFirst + ddl;
  1053. int ypMac = pwwd->ypMac;
  1054. pedlT = &dndl[dlTo];
  1055. if (ddl != 0)
  1056. {
  1057. blt(&dndl[dlFirst], pedlT, cwEDL * cdlBelow);
  1058. }
  1059. for (dlT = dlTo; dlT < pwwd->dlMac; ++dlT, ++pedlT)
  1060. {
  1061. if (dypChange < 0 && pedlT->yp > ypMac)
  1062. {
  1063. /* Invalidate dl's that are pulled in from the ozone below ypMac
  1064. */
  1065. pedlT->fValid = fFalse;
  1066. }
  1067. else
  1068. {
  1069. pedlT->yp += dypChange;
  1070. }
  1071. }
  1072. }
  1073. if (dypChange != 0)
  1074. {
  1075. RECT rc;
  1076. SetRect( (LPRECT)&rc, 0, min(ypFrom, ypTo),
  1077. pwwd->xpMac, pwwd->ypMac );
  1078. Assert( ww == wwCur ); /* A MEMO-only assumption */
  1079. ScrollCurWw( &rc, 0, dypChange );
  1080. }
  1081. return dypChange;
  1082. }
  1083. FImportantMsgPresent()
  1084. {
  1085. /* If the next message is important enough to interrupt a screen update, we
  1086. return TRUE; if it can wait, we return FALSE */
  1087. BOOL fToggledKey;
  1088. extern MSG vmsgLast;
  1089. #ifdef DEBUG
  1090. unsigned wHeapVal = *(pLocalHeap + 1);
  1091. Assert( wHeapVal == 0 ); /* Heap should not be frozen */
  1092. #endif
  1093. #ifdef DBCS
  1094. if( donteat )
  1095. return TRUE;
  1096. #endif
  1097. while (PeekMessage((LPMSG) &vmsgLast, NULL, NULL, NULL, PM_NOREMOVE))
  1098. {
  1099. if (((vmsgLast.wParam == VK_MENU) || (vmsgLast.wParam == VK_CONTROL)))
  1100. {
  1101. if (vmsgLast.wParam == VK_CONTROL)
  1102. {
  1103. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1104. SetShiftFlags();
  1105. }
  1106. return TRUE;
  1107. }
  1108. /* Filter uninteresting or easily handled events */
  1109. else if (fToggledKey = FCheckToggleKeyMessage(&vmsgLast) ||
  1110. (vmsgLast.message == WM_KEYUP && vmsgLast.hwnd == wwdCurrentDoc.wwptr))
  1111. {
  1112. /* This is so the Windows keyboard interface mechanism will see toggle
  1113. key and key-up transitions */
  1114. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1115. #ifdef WIN30
  1116. /* PeekMessage has been changed in Win 3.0 so that GetKeyState()
  1117. called from FCheckToggleKeyMessage() is really only valid if
  1118. you've done a PeekMessage(...,PM_REMOVE) or GetMessage() first.
  1119. That is, while the FCheckToggleKeyMessage() call might succeed
  1120. above, it will NOT have set the vfShiftKey/vfCommandKey flags
  1121. correctly -- so we do it here ..pault */
  1122. if (fToggledKey)
  1123. FCheckToggleKeyMessage(&vmsgLast);
  1124. #endif
  1125. if (vmsgLast.hwnd != wwdCurrentDoc.wwptr)
  1126. {
  1127. /* Just in case a modeless dialog's window proc cares */
  1128. TranslateMessage((LPMSG)&vmsgLast);
  1129. DispatchMessage((LPMSG)&vmsgLast);
  1130. }
  1131. #ifdef DBCS
  1132. #ifdef KOREA /* 90.12.23 by sangl */ // jinwoo: 92, 9, 28
  1133. if (vmsgLast.message == WM_CHAR || vmsgLast.message == WM_KEYDOWN
  1134. || vmsgLast.message == WM_INTERIM) {
  1135. #else /* KOREA */
  1136. if (vmsgLast.message == WM_CHAR || vmsgLast.message == WM_KEYDOWN ) {
  1137. #endif //KOREA 920525 KDLEE; jinwoo: 92, 9, 28
  1138. donteat = TRUE;
  1139. return( TRUE );
  1140. } /* else Ok, you are KEYUP message. do normal */
  1141. #endif
  1142. }
  1143. else
  1144. {
  1145. switch (vmsgLast.message)
  1146. {
  1147. case WM_MOUSEMOVE:
  1148. /* Process mouse move messages immediately; they are not really
  1149. important. NOTE: This assumes that we have not captured all mouse
  1150. events; in which case, they are important. */
  1151. DispatchMessage((LPMSG)&vmsgLast);
  1152. case WM_TIMER:
  1153. case WM_SYSTIMER:
  1154. /* Remove timer and mouse move messages from the queue. */
  1155. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1156. break;
  1157. default:
  1158. Assert( *(pLocalHeap+1) == 0 ); /* Heap should still not be frozen */
  1159. return (TRUE);
  1160. }
  1161. }
  1162. }
  1163. Assert( *(pLocalHeap + 1) == 0 ); /* Heap should still not be frozen */
  1164. return (FALSE);
  1165. }
  1166. /* C P B E G I N L I N E */
  1167. typeCP CpBeginLine(pdl, cp)
  1168. int *pdl;
  1169. typeCP cp;
  1170. { /* return the cp and dl containing cp */
  1171. int dlMin, dlLim;
  1172. typeCP cpGuess;
  1173. struct EDL *dndl;
  1174. do
  1175. {
  1176. UpdateWw(wwCur, false);
  1177. PutCpInWwVert(cp); /* Ensure cp on screen */
  1178. } while (pwwdCur->fDirty && !vfOutOfMemory);
  1179. dndl = &(**(pwwdCur->hdndl))[0];
  1180. dlMin = 0;
  1181. dlLim = pwwdCur->dlMac;
  1182. while (dlMin + 1 < dlLim)
  1183. { /* Binary search the ww */
  1184. int dlGuess = (dlMin + dlLim) >> 1;
  1185. struct EDL *pedl = &dndl[dlGuess];
  1186. if ((cpGuess = pedl->cpMin) <= cp && (cpGuess != cp || pedl->ichCpMin == 0))
  1187. { /* guess is low or right */
  1188. dlMin = dlGuess;
  1189. if (cp == cpGuess && pedl->cpMin + pedl->dcpMac != cp)
  1190. break; /* Got it right */
  1191. }
  1192. else /* Guess is high */
  1193. dlLim = dlGuess;
  1194. }
  1195. *pdl = dlMin;
  1196. return dndl[dlMin].cpMin;
  1197. }
  1198. /* T O G G L E S E L */
  1199. ToggleSel(cpFirst, cpLim, fOn)
  1200. typeCP cpFirst, cpLim; /* selection bounds */
  1201. int fOn;
  1202. { /* Flip selection highlighting on and off */
  1203. extern int vfPMS;
  1204. struct EDL *pedl;
  1205. int dlT;
  1206. int xpMin;
  1207. int dxpRoom;
  1208. int xpFirst;
  1209. int xpLim;
  1210. int fInsertPoint = (cpFirst == cpLim);
  1211. if (vfSelHidden || cpFirst > cpLim || cpLim < /*cp0*/ cpMinCur || vfDead)
  1212. return;
  1213. if ( vfPictSel && vfPMS &&
  1214. (CachePara( docCur, cpFirst ), vpapAbs.fGraphics) &&
  1215. (vcpLimParaCache == cpLim) )
  1216. { /* Don't show inversion if we're moving or sizing a picture */
  1217. return;
  1218. }
  1219. dxpRoom = pwwdCur->xpMac - xpSelBar;
  1220. xpMin = pwwdCur->xpMin;
  1221. for (dlT = 0; dlT < pwwdCur->dlMac; dlT++)
  1222. {
  1223. typeCP cpMin, cpMac; /* line bounds */
  1224. pedl = &(**(pwwdCur->hdndl))[dlT];
  1225. if (!pedl->fValid)
  1226. continue;
  1227. cpMin = pedl->cpMin;
  1228. if (cpMin > cpLim || cpMin > cpMacCur || (cpMin == cpLim && cpLim != cpFirst))
  1229. break;
  1230. cpMac = cpMin + pedl->dcpMac;
  1231. if (cpFirst <= cpMin && cpLim >= cpMac)
  1232. {
  1233. /* entire line is highlighted */
  1234. xpFirst = pedl->xpLeft;
  1235. if (pedl->fGraphics && cpLim == cpMac && cpMin == cpMac)
  1236. /* Special kludge for graphics paras */
  1237. xpLim = xpFirst;
  1238. else
  1239. xpLim = pedl->xpMac;
  1240. }
  1241. else if (fInsertPoint && cpFirst == cpMac && vfInsEnd)
  1242. { /* Special kludge for an insert point at the end of a line */
  1243. xpLim = xpFirst = pedl->xpMac;
  1244. }
  1245. else if (cpFirst < cpMac)
  1246. {
  1247. /* Bite the bullet */
  1248. int dxp;
  1249. typeCP cpBegin = CpMax(cpMin, cpFirst);
  1250. typeCP cpEnd = CpMin(cpMac, cpLim);
  1251. FormatLine(docCur, cpMin, pedl->ichCpMin, cpMacCur, flmSandMode);
  1252. dxp = DxpDiff((int) (cpBegin - cpMin),
  1253. (int) (cpEnd - cpBegin), &xpFirst);
  1254. xpLim = xpFirst + dxp;
  1255. /* reload pedl because procedures were called */
  1256. pedl = &(**(pwwdCur->hdndl))[dlT];
  1257. }
  1258. else
  1259. continue;
  1260. /* now we have: pedl valid, xpFirst, xpLast describe highlight */
  1261. /* xpFirst = max(xpFirst, xpMin); */
  1262. xpLim = min(xpLim, xpMin + pedl->xpMac);
  1263. if (xpLim > xpFirst)
  1264. {
  1265. if (xpLim > xpMin)
  1266. {
  1267. RECT rc;
  1268. rc.top = pedl->yp - pedl->dyp;
  1269. rc.left = xpSelBar + max(xpFirst - xpMin, 0);
  1270. rc.bottom = pedl->yp;
  1271. rc.right = xpSelBar + xpLim - xpMin;
  1272. InvertRect( wwdCurrentDoc.hDC, (LPRECT)&rc);
  1273. }
  1274. }
  1275. /* ToggleSel modified 7/28/85 -- added explicit check for fInsertPoint, since
  1276. the xpLim == xpFirst test sometimes succeeded bogusly when a selection
  1277. was extended backwards. BL */
  1278. else if (fInsertPoint && (xpLim == xpFirst)) /* Insertion point */
  1279. {
  1280. /* vfli should usually be cached already, so will be fast. */
  1281. int yp = pedl->yp;
  1282. FormatLine(docCur, cpMin, pedl->ichCpMin, cpMacCur, flmSandMode);
  1283. if (fOn ^ vfInsertOn)
  1284. {
  1285. if (!vfInsertOn)
  1286. {
  1287. vxpCursLine = xpSelBar + xpFirst - xpMin;
  1288. vypCursLine = yp - vfli.dypAfter;
  1289. vdypCursLine = min(vfli.dypFont, vfli.dypLine - vfli.dypAfter);
  1290. /* Start blinking in a while */
  1291. vfSkipNextBlink = TRUE;
  1292. }
  1293. DrawInsertLine();
  1294. }
  1295. return;
  1296. }
  1297. }
  1298. }
  1299. /* T R A S H W W */
  1300. TrashWw(ww)
  1301. { /* Invalidate all dl's in ww */
  1302. Assert( ww >= 0 && ww < wwMax );
  1303. InvalBand(&rgwwd[ww], 0, ypMaxAll);
  1304. }
  1305. /* I N V A L B A N D */
  1306. /* invalidate the band ypFirst, ypLast inclusive */
  1307. InvalBand(pwwd, ypFirst, ypLast)
  1308. struct WWD *pwwd; int ypFirst, ypLast;
  1309. {
  1310. /* this covers some peculiar rects received from update event after a
  1311. window resize by 1 pixel. CS */
  1312. if (ypLast < 0 || ypFirst == ypLast) return;
  1313. pwwd->fDirty = true;
  1314. pwwd->ypFirstInval = min(pwwd->ypFirstInval, ypFirst);
  1315. pwwd->ypLastInval = max(ypLast, pwwd->ypLastInval);
  1316. }
  1317. /* T R A S H A L L W W S */
  1318. TrashAllWws()
  1319. { /* trash them all */
  1320. int ww;
  1321. #ifdef CASHMERE
  1322. for (ww = 0; ww < wwMac; ++ww)
  1323. TrashWw(ww);
  1324. #else
  1325. TrashWw( wwDocument );
  1326. #endif
  1327. vfli.doc = docNil; /* Mark vfli invalid */
  1328. }
  1329. /* T U R N O F F S E L */
  1330. TurnOffSel()
  1331. { /* Remove sel highlighting from screen */
  1332. /* HideSel has no effect */
  1333. if (!vfSelHidden)
  1334. {
  1335. ToggleSel(selCur.cpFirst, selCur.cpLim, false);
  1336. vfSelHidden = true;
  1337. }
  1338. }
  1339. /* D R A W I N S E R T L I N E */
  1340. DrawInsertLine()
  1341. { /* Draw (in Xor mode) a vertical bar at screen position v*CursLine */
  1342. /* Toggles both the display and the vfInsertOn flag */
  1343. /* Adjustments in cursor draw must be reflected in DisplayFli, above */
  1344. /* Last-minute correction for a bug: assure that the insert line
  1345. does not extend above ypMin */
  1346. if (!vfInsertOn && vdypCursLine > vypCursLine - wwdCurrentDoc.ypMin)
  1347. vdypCursLine = vypCursLine - wwdCurrentDoc.ypMin;
  1348. /* Tell GDI to invert the caret line */
  1349. PatBlt( wwdCurrentDoc.hDC, vxpCursLine, vypCursLine - vdypCursLine,
  1350. 2, vdypCursLine , DSTINVERT );
  1351. vfInsertOn = 1 - vfInsertOn;
  1352. }
  1353. /* C L E A R I N S E R T L I N E */
  1354. ClearInsertLine()
  1355. {
  1356. if ( vfInsertOn) DrawInsertLine();
  1357. }
  1358.