Leaked source code of windows server 2003
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.

531 lines
15 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. #define NOCLIPBOARD
  5. #define NOGDICAPMASKS
  6. #define NOCTLMGR
  7. #define NOVIRTUALKEYCODES
  8. #define NOWINMESSAGES
  9. #define NOWINSTYLES
  10. #define NOSYSMETRICS
  11. #define NOMENUS
  12. #define NOSOUND
  13. #define NOCOMM
  14. #define NOPEN
  15. #define NOWNDCLASS
  16. #define NOICON
  17. #define NORASTEROPS
  18. #define NOSHOWWINDOW
  19. #define NOATOM
  20. #define NOKEYSTATE
  21. #define NOSYSCOMMANDS
  22. #define NOBITMAP
  23. #define NOBRUSH
  24. #define NOCOLOR
  25. #define NODRAWTEXT
  26. #define NOMB
  27. #define NOPOINT
  28. #define NOMSG
  29. #include <windows.h>
  30. #include "mw.h"
  31. #include "docdefs.h"
  32. #include "dispdefs.h"
  33. #include "fmtdefs.h"
  34. #include "cmddefs.h"
  35. #include "wwdefs.h"
  36. #include "propdefs.h"
  37. /* Globals used here only */
  38. struct TR { /* Text Row info for CtrBackDyp Cache */
  39. typeCP cp;
  40. int dcpDepend; /* dcpDepend for PREVIOUS edl */
  41. int ichCp;
  42. int dyp;
  43. };
  44. struct TR rgtrCache[ itrMaxCache ];
  45. int wwCache=wwNil;
  46. extern struct PAP vpapAbs;
  47. extern typeCP vcpFirstParaCache;
  48. extern struct WWD *pwwdCur;
  49. extern struct SEL selCur;
  50. extern int docCur;
  51. extern typeCP cpCacheHint;
  52. extern typeCP cpMinCur;
  53. extern typeCP cpMacCur;
  54. extern struct FLI vfli;
  55. extern int wwCur;
  56. extern int ctrCache;
  57. extern int itrFirstCache;
  58. extern int itrLimCache;
  59. extern int vfOutOfMemory;
  60. /* P U T C P I N W W V E R T*/
  61. PutCpInWwVert(cp)
  62. typeCP cp;
  63. {
  64. /* vertical case */
  65. typeCP cpMac;
  66. struct EDL (**hdndl) [] = pwwdCur->hdndl;
  67. int dlMac=pwwdCur->dlMac;
  68. struct EDL *pedl = &(**hdndl) [dlMac - 1];
  69. struct EDL *pedlFirst = &(**hdndl) [0];
  70. if ((pedl->yp > pwwdCur->ypMac) && (pedl > pedlFirst))
  71. /* Partial line at the bottom of the window -- this doesn't count
  72. unless it's all we've got */
  73. { pedl--; dlMac--; }
  74. if (cp < pwwdCur->cpFirst ||
  75. cp > (cpMac = pedl->cpMin + pedl->dcpMac) ||
  76. (cp == cpMac && !pedl->fIchCpIncr) ||
  77. /* Covers insertion points before pictures reached via curs keys */
  78. (CachePara( docCur, cp ),
  79. (vpapAbs.fGraphics &&
  80. (selCur.cpFirst == selCur.cpLim) &&
  81. (pedlFirst->cpMin == selCur.cpFirst) &&
  82. (pedlFirst->ichCpMin > 0))))
  83. {
  84. DirtyCache(pwwdCur->cpFirst = cp);
  85. pwwdCur->ichCpFirst = 0;
  86. CtrBackDypCtr( 9999, dlMac >> 1 );
  87. }
  88. }
  89. SetCurWwVScrollPos( )
  90. {
  91. typeCP cp;
  92. int dr;
  93. struct EDL (**hdndl)[] = pwwdCur->hdndl;
  94. /* calculate desired elevator position dr */
  95. if ((cp = pwwdCur->cpMac - pwwdCur->cpMin) == (typeCP) 0)
  96. dr = 0;
  97. else
  98. {
  99. typeCP CpWinGraphic();
  100. typeCP cpWinFirst = ((**hdndl) [0].fGraphics && !pwwdCur->fDirty) ?
  101. CpWinGraphic( pwwdCur ) : pwwdCur->cpFirst;
  102. dr = min(drMax - 1,
  103. (int)(((cpWinFirst - pwwdCur->cpMin) * (drMax - 1) + (cp >> 1)) / cp));
  104. }
  105. /* Contemplating this 'if' statement should elevate one to a higher plane
  106. of existence. */
  107. if (dr != pwwdCur->drElevator)
  108. /* reset the value of the vertical scroll bar */
  109. SetScrollPos( pwwdCur->hVScrBar,
  110. pwwdCur->sbVbar,
  111. pwwdCur->drElevator = dr,
  112. TRUE);
  113. }
  114. /* A D J W W V E R T */
  115. /* Scroll a window down vertically so that UpdateWw can re-use the text
  116. that is still visible. Otherwise, UpdateWw would write over the very
  117. lines it will need later on near the bottom of the window.
  118. */
  119. AdjWwVert(cdl, dyp)
  120. int cdl;
  121. {
  122. #if defined(JAPAN) & defined(DBCS_IME)
  123. extern void IMEManage( );
  124. #endif
  125. struct EDL *pedl;
  126. int dl;
  127. if (cdl == 0) return;
  128. cdl = umin( cdl, pwwdCur->dlMac ); /* ! don't let it run off the end */
  129. Assert( dyp > 0 );
  130. ClearInsertLine();
  131. DypScroll(wwCur, 0, cdl, pwwdCur->ypMin + dyp);
  132. /* invalidate the first cdl dl's */
  133. pedl = &(**(pwwdCur->hdndl))[0];
  134. for (dl = 0; dl < cdl; dl++)
  135. (pedl++)->fValid = FALSE;
  136. pwwdCur->fDirty = fTrue;
  137. #if defined(JAPAN) & defined(DBCS_IME)
  138. IMEManage( FALSE );
  139. #endif
  140. }
  141. ScrollDownCtr(ddr)
  142. int ddr;
  143. { /* Scroll down in the document by ddr text lines (but < 1 screenful) */
  144. struct EDL *pedl;
  145. UpdateWw(wwCur, FALSE); /* Dl's must be correct */
  146. ddr = min(ddr, max(1, pwwdCur->dlMac - 1));
  147. pedl = &(**(pwwdCur->hdndl))[ddr - 1]; /* pedl is first line above new screen */
  148. while (ddr > 0 && pedl->cpMin + pedl->dcpMac > cpMacCur)
  149. { /* Don't scroll the endmark off the screen */
  150. --pedl;
  151. --ddr;
  152. }
  153. /* Change the cpFirst of the window and dirty it */
  154. if (ddr > 0)
  155. {
  156. struct TR tr;
  157. int dcpDepend;
  158. if (wwCur != wwCache)
  159. { /* If window has changed, invalidate cache here
  160. so cp's cached below will be used */
  161. TrashCacheS();
  162. wwCache = wwCur;
  163. }
  164. HideSel(); /* Don't scroll selection if machine can't handle it */
  165. ClearInsertLine();
  166. pwwdCur->cpFirst = pedl->cpMin + pedl->dcpMac;
  167. pwwdCur->ichCpFirst = pedl->fIchCpIncr ? pedl->ichCpMin + 1 : 0;
  168. pwwdCur->dcpDepend = pedl->dcpDepend; /* Remember hot spot */
  169. /* Make tr cache entries for the disappearing lines */
  170. pedl = &(**(pwwdCur->hdndl))[0];
  171. if (ctrCache == 0) /* We don't have top line yet */
  172. {
  173. tr.cp = pedl->cpMin;
  174. tr.ichCp = pedl->ichCpMin;
  175. tr.dyp = pedl->dyp;
  176. tr.dcpDepend = pwwdCur->dcpDepend;
  177. AppendCachePtr( &tr );
  178. }
  179. while ( ddr-- )
  180. {
  181. tr.cp = pedl->cpMin + pedl->dcpMac;
  182. tr.ichCp = pedl->fIchCpIncr ? pedl->ichCpMin + 1 : 0;
  183. tr.dcpDepend = pedl->dcpDepend;
  184. tr.dyp = (++pedl)->dyp;
  185. AppendCachePtr( &tr );
  186. }
  187. pwwdCur->fDirty = true;
  188. SetCurWwVScrollPos();
  189. CheckMode();
  190. }
  191. else
  192. {
  193. _beep();
  194. }
  195. }
  196. ScrollUpDypWw()
  197. { /* Scroll up in the document by one screenfull less 1 line */
  198. int dypKeep=8;
  199. struct EDL *pedl = &(**pwwdCur->hdndl) [0];
  200. if (pedl->fValid)
  201. {
  202. dypKeep = pedl->dyp;
  203. }
  204. if (CtrBackDypCtr( pwwdCur->ypMac - pwwdCur->ypMin - dypKeep,9999 ) == 0)
  205. {
  206. _beep();
  207. }
  208. else
  209. CheckMode();
  210. }
  211. ScrollUpCtr( ctr )
  212. int ctr;
  213. { /* Scroll Up ctr text rows in the doc (scroll window down) */
  214. if (CtrBackDypCtr( 9999, ctr ) == 0)
  215. {
  216. _beep();
  217. }
  218. else
  219. CheckMode();
  220. }
  221. int CtrBackDypCtr( dypLim, ctrLim )
  222. int dypLim;
  223. int ctrLim;
  224. { /* Set pwwdCur->cpFirst to the cpFirst of the text line
  225. dypLim pixels or ctrLim text rows before the value of
  226. pwwdCur->cpFirst, whichever limit is reached first.
  227. Adjust the position of the vert scroll bar according to the new cpFirst.
  228. Return the number of text rows (tr) we went back. */
  229. int fAdj = ( (pwwdCur->cpFirst == (**(pwwdCur->hdndl))[0].cpMin) ||
  230. !(**(pwwdCur->hdndl))[0].fValid );
  231. typeCP cpFirst = pwwdCur->cpFirst;
  232. int ichCpFirst = pwwdCur->ichCpFirst;
  233. int ctrGrant = 0; /* ctr we've backed over so far */
  234. int dypGrant = 0; /* dyp we've backed over so far */
  235. int ichFake = 0;
  236. pwwdCur->fCpBad = false; /* Reset hot spot warning */
  237. pwwdCur->fDirty = true;
  238. /* Cache is only valid for one ww -- invalidate if ww has changed */
  239. if (wwCur != wwCache)
  240. {
  241. TrashCacheS();
  242. wwCache = wwCur;
  243. }
  244. if (ctrCache == 0)
  245. /* Don't have cache entry for first line in Ww -- force formatting
  246. THROUGH first line of Ww instead of TO it. */
  247. ++ichFake;
  248. for ( ;; )
  249. {
  250. /* If there is no info in the cache, must replenish it. */
  251. if (ctrCache <= 1) /* <=: also replenish if 1st line of Ww is only entry */
  252. {
  253. typeCP cpStart; /* cp to start formatting from */
  254. int dcpDepend; /* Dependency of line containing cpStart */
  255. typeCP cp;
  256. int ichCp;
  257. int itrTempCacheLim = 0;
  258. struct TR rgtrTempCache[ itrMaxCache ];
  259. int fTempCacheOverflow = false;
  260. if ((cpFirst <= cpMinCur) && (ichCpFirst == 0))
  261. { /* Reached top of document */
  262. if (fAdj)
  263. AdjWwVert( ctrGrant, dypGrant );
  264. pwwdCur->cpFirst = cpMinCur;
  265. pwwdCur->ichCpFirst = 0;
  266. pwwdCur->dcpDepend = 0;
  267. goto SetScroll;
  268. }
  269. /* Want to go back BEFORE the earliest point we have in the cache */
  270. if (ichFake > 0)
  271. /* Force formatting THROUGH { cpFirst, ichCpFirst }
  272. instead of TO */
  273. --ichFake;
  274. else if (ichCpFirst > 0)
  275. --ichCpFirst;
  276. else
  277. --cpFirst;
  278. cpStart = CpHintCache( cpFirst );
  279. if ( ( CachePara( docCur, cpFirst ), vcpFirstParaCache ) >= cpStart )
  280. {
  281. cpStart = vcpFirstParaCache;
  282. dcpDepend = 0; /* At para start; we know dependency is 0 */
  283. }
  284. else
  285. dcpDepend = cpMaxTl; /* real value unknown; use max */
  286. /* Add TR info for lines from { cpStart, 0 } THROUGH
  287. { cpFirst, ichCpFirst } to temporary cache */
  288. for ( cp = cpStart, ichCp = 0;
  289. (cp < cpFirst) || ((cp == cpFirst) && (ichCp <= ichCpFirst)); )
  290. {
  291. struct TR *ptr;
  292. if (itrTempCacheLim == itrMaxCache)
  293. { /* Overflowed the temp cache */
  294. fTempCacheOverflow = fTrue;
  295. itrTempCacheLim = 0;
  296. }
  297. /* Add one tr to the cache */
  298. FormatLine( docCur, cp, ichCp, cpMacCur, flmSandMode );
  299. if (vfOutOfMemory)
  300. return ctrGrant;
  301. ptr = &rgtrTempCache[ itrTempCacheLim++ ];
  302. ptr->cp = cp;
  303. ptr->ichCp = ichCp;
  304. ptr->dyp = vfli.dypLine;
  305. ptr->dcpDepend = dcpDepend; /* Save dcpDepend for prev line */
  306. dcpDepend = vfli.dcpDepend;
  307. /* Continue with next line */
  308. cp = vfli.cpMac;
  309. ichCp = vfli.ichCpMac;
  310. } /* end for */
  311. /* Add our temporary cache in front of the real one */
  312. PrependCacheRgtr( rgtrTempCache, itrTempCacheLim );
  313. if (fTempCacheOverflow)
  314. /* We wrapped around the end of the temp cache; include the
  315. rest of the circle */
  316. PrependCacheRgtr( &rgtrTempCache[ itrTempCacheLim ],
  317. itrMaxCache - itrTempCacheLim );
  318. } /* end for */
  319. /* Walk backward in the cache, eliminating entries,
  320. until: (1) We have run through enough yp's or tr's (return) OR
  321. (2) We have exhausted the cache (loop back to refill it)
  322. NOTE: Case 2 catches the case when we hit the beginning of the doc */
  323. Assert( ctrCache >= 1 );
  324. Assert( itrLimCache > 0 );
  325. for ( ;; )
  326. {
  327. struct TR *ptr = &rgtrCache[ itrLimCache - 1 ];
  328. if (ctrCache == 1)
  329. { /* Only one thing left in cache: the 1st line of the Ww */
  330. cpFirst = ptr->cp;
  331. ichCpFirst = ptr->ichCp;
  332. break; /* Exhausted cache; loop back to refill it */
  333. }
  334. if ( (dypGrant >= dypLim) || (ctrGrant >= ctrLim) )
  335. { /* Passed through enough yp's or tr's -- we're done */
  336. if (fAdj)
  337. AdjWwVert( ctrGrant, dypGrant );
  338. pwwdCur->cpFirst = ptr->cp;
  339. pwwdCur->ichCpFirst = ptr->ichCp;
  340. pwwdCur->dcpDepend = ptr->dcpDepend;
  341. goto SetScroll;
  342. }
  343. /* Remove end entry from the cache */
  344. if (--itrLimCache <= 0)
  345. itrLimCache = itrMaxCache;
  346. ctrCache--;
  347. /* Update ctrGrant, dypGrant -- we've granted 1 line of scrollback */
  348. ctrGrant++;
  349. dypGrant += rgtrCache [itrLimCache - 1].dyp;
  350. } /* end for */
  351. Assert( ctrCache == 1 );
  352. } /* end for */
  353. SetScroll: /* All done; set vert scroll bar according to new cpFirstWw */
  354. SetCurWwVScrollPos();
  355. return ctrGrant;
  356. }
  357. /* A P P E N D C A C H E P T R */
  358. AppendCachePtr( ptr )
  359. struct TR *ptr;
  360. { /* Say we are scrolling up a line, append *ptr to tr cache */
  361. if (++ctrCache > itrMaxCache)
  362. { /* Have to push one off the top */
  363. if (++itrFirstCache == itrMaxCache)
  364. itrFirstCache = 0;
  365. --ctrCache;
  366. }
  367. /* Now add one onto the end */
  368. if (itrLimCache++ == itrMaxCache)
  369. itrLimCache = 1;
  370. rgtrCache[ itrLimCache - 1 ] = *ptr;
  371. }
  372. /* P R E P E N D C A C H E R G T R */
  373. PrependCacheRgtr( rgtr, ctr )
  374. struct TR rgtr[];
  375. int ctr;
  376. { /* PREPEND one or more lines JUST BEFORE the ones in the cache */
  377. /* The tr cache is a ring buffer. rgtrCache[ itrLimCache - 1 ] is the
  378. tr entry describing the cpFirst of wwCur; rgtrCache[ itrFirstCache ]
  379. is the tr for the earliest line we know of. All between are
  380. contiguous. ctrCache is the number of tr's we have cached. */
  381. struct TR *ptr = &rgtr[ ctr ];
  382. ctrCache += (ctr = min(ctr, itrMaxCache - ctrCache));
  383. /* Compensate for state introduced by TrashCache -- itrLimCache == 0 */
  384. if (itrLimCache == 0)
  385. itrLimCache = itrMaxCache;
  386. while (ctr-- != 0)
  387. { /* Now add each tr */
  388. if (itrFirstCache-- == 0)
  389. itrFirstCache = itrMaxCache - 1;
  390. rgtrCache[ itrFirstCache ] = *(--ptr);
  391. }
  392. }
  393. /* T R A S H C A C H E s */
  394. TrashCacheS()
  395. { /* Invalidate scrolling cache */
  396. ctrCache = 0;
  397. cpCacheHint = cp0;
  398. itrFirstCache = itrLimCache = 0;
  399. }
  400. /* C P H I N T C A C H E */
  401. typeCP CpHintCache(cp)
  402. typeCP cp;
  403. { /* Give the latest cp <= arg cp that begins a line */
  404. return (cpCacheHint <= cp) ? cpCacheHint : cpMinCur;
  405. }
  406. DirtyCache(cp)
  407. typeCP cp;
  408. { /* Invalidate cache beyond cp */
  409. while (ctrCache-- > 1)
  410. {
  411. typeCP cpT = rgtrCache[itrLimCache - 1].cp;
  412. if (--itrLimCache == 0)
  413. itrLimCache = itrMaxCache;
  414. if (cpT < cp)
  415. { /* Found our hint; dirty one extra line for word wrap */
  416. cpCacheHint = rgtrCache [itrLimCache - 1].cp;
  417. itrLimCache = itrFirstCache;
  418. ctrCache = 0;
  419. return;
  420. }
  421. }
  422. TrashCacheS();
  423. }
  424.