ocrt.pp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. Unit oCrt;
  2. {---------------------------------------------------------------------------
  3. CncWare
  4. (c) Copyright 1999
  5. ---------------------------------------------------------------------------
  6. Filename..: ocrt.pp
  7. Programmer: Ken J. Wright, [email protected]
  8. Date......: 03/01/99
  9. Purpose - crt unit replacement plus OOP windows using ncurses.
  10. NOTE: All of the crt procedures & functions have been replaced with ncurses
  11. driven versions. This makes the ncurses library a little easier to use in a
  12. Pascal program and benefits from terminal independence.
  13. -------------------------------<< REVISIONS >>--------------------------------
  14. Ver | Date | Prog| Description
  15. -------+----------+-----+-----------------------------------------------------
  16. 1.00 | 03/01/99 | kjw | Initial Release.
  17. | 03/22/99 | kjw | Added nDelWindow(), delwin() does not nil pointer.
  18. 1.01 | 11/22/99 | kjw | Added the following: nEcho, ClrEol, ClrBot, InsLine,
  19. | DelLine, Delay, nClrEol, nClrBot, nInsLine, nDelLine,
  20. | nRefresh, nScroll, nDrawBox, nNewWindow, nWinColor,
  21. | nWriteScr, nFrame & some functions for returning
  22. | line drawing character values.
  23. 1.02 | 11/26/99 | kjw | Added nKeypressed().
  24. 1.03 | 12/01/99 | kjw | Added global boolean nIsActive.
  25. 1.04 | 12/03/99 | kjw | 1) Added procedures nHline, nVLine, & nWriteAC.
  26. | 2) Changed all the line draw character functions
  27. | (i.e., nHL, nVL) to return the longint value from
  28. | ncurses rather than the character value (which was
  29. | not very useful!). Now these can be passed to
  30. | nWriteAC() to correctly write the line drawing
  31. | characters.
  32. | 3) Added more of the ACS characters.
  33. 1.05 | 12/08/99 | kjw | 1) StartCurses() is now done as part of the unit
  34. | initialization block. EndCurses() is done via an
  35. | exit procedure.
  36. | 2) nIsActive is now a function (safer!).
  37. | 3) Added panel unit for windowing.
  38. | 4) Added tnWindow object.
  39. 1.10 | 12/12/99 | kjw | Added nSEdit().
  40. 1.11 | 12/12/99 | kjw | Added Special property to tEC object. Now any normal
  41. | character can trigger sedit to exit.
  42. ------------------------------------------------------------------------------
  43. 2.00 | 12/13/99 | kjw | nCrt renamed to oCrt. A new nCrt has been created
  44. | which is a drop-in replacement for the FPC crt unit.
  45. | oCrt contains all of nCrt plus the OOP extensions.
  46. | All of the common code is in ncrt.inc.
  47. 2.01 | 12/15/99 | kjw | 1) A tnWindow object now becomes the target for
  48. | stdout following Init & Show. A Hide will put the
  49. | target back to stdscr.
  50. | 2) Added nSetActiveWin() to manually pick a target
  51. | window for stdout.
  52. 2.02 | 12/15/99 | kjw | 1) PutFrame applied keypad to stdscr instead of sub.
  53. | 2) See ncrt.inc
  54. 2.03 | 12/16/99 | kjw | 1) See ncrt.inc
  55. | 2) Added shift/f-key constants.
  56. 2.04 | 01/04/00 | kjw | See ncrt.inc
  57. 2.05 | 01/06/00 | kjw | 1) See ncrt.inc.
  58. | 2) Added boolean internal_fwrite. FWrite was failing
  59. | when trying to write outside of the active window.
  60. | 3) nSEdit was not handling tec.firsttime correctly
  61. | when a tec.special was processed.
  62. 2.06 | 01/11/00 | kjw | See ncrt.inc.
  63. ------------------------------------------------------------------------------
  64. }
  65. Interface
  66. Uses linux,ncurses,panel;
  67. Const
  68. { border styles for text boxes }
  69. btNone : integer = 0;
  70. btSingle : integer = 1;
  71. btDouble : integer = 2;
  72. nKeyEnter = 13; { Enter key }
  73. nKeyEsc = 27; { Home key }
  74. nKeyHome = 71; { Home key }
  75. nKeyUp = 72; { Up Arrow }
  76. nKeyPgUp = 73; { PgUp Key }
  77. nKeyLeft = 75; { Left Arrow }
  78. nKeyRight = 77; { Right Arrow }
  79. nKeyEnd = 79; { End Key }
  80. nKeyDown = 80; { Down Arrow }
  81. nKeyPgDn = 81; { PgDn Key }
  82. nKeyF1 = 59; { f1 key }
  83. nKeyF2 = 60; { f2 key }
  84. nKeyF3 = 61; { f3 key }
  85. nKeyF4 = 62; { f4 key }
  86. nKeyF5 = 63; { f5 key }
  87. nKeyF6 = 64; { f6 key }
  88. nKeyF7 = 65; { f7 key }
  89. nKeyF8 = 66; { f8 key }
  90. nKeyF9 = 67; { f9 key }
  91. nKeyF10 = 68; { f10 key }
  92. nKeyF11 = 84; { shift/f1 key }
  93. nKeyF12 = 85; { shift/f2 key }
  94. nKeyF13 = 86; { shift/f3 key }
  95. nKeyF14 = 87; { shift/f4 key }
  96. nKeyF15 = 88; { shift/f5 key }
  97. nKeyF16 = 89; { shift/f6 key }
  98. nKeyF17 = 90; { shift/f7 key }
  99. nKeyF18 = 91; { shift/f8 key }
  100. nKeyF19 = 92; { shift/f9 key }
  101. nKeyF20 = 93; { shift/f10 key }
  102. Type
  103. { for scrolling a window }
  104. tnUpDown = (up,down);
  105. { for window & header positioning }
  106. tnJustify = (none,left,center,right,top,bottom);
  107. { used for nSEdit }
  108. {------------------------------------------------------------------
  109. FirstTime = true : passed string is initialized to ''.
  110. IsHidden = true : causes a string of '*' to display in place of
  111. the actual characters typed.
  112. InsMode : toggle for insert/overwrite mode.
  113. ExitMode = true : sedit exits after every keystroke.
  114. = false: sedit only exits when #27,#13, or any extended
  115. key *except* for Home,End,RArrow,LArrow.
  116. ------------------------------------------------------------------}
  117. tEC = Object
  118. FirstTime,
  119. IsHidden,
  120. InsMode,
  121. ExitMode : boolean;
  122. special : string;
  123. Constructor Init(ft,ih,im,em : boolean; s : string);
  124. Destructor Done;
  125. End;
  126. pwin = ^Window;
  127. pnWindow = ^tnWindow;
  128. tnWindow = Object
  129. Private
  130. wn : pwindow; { pointer to win or sub to read/write to }
  131. win : pwindow; { pointer to main window record }
  132. sub : pwindow; { sub window if a bordered window }
  133. pan : ppanel; { pointer to panel record }
  134. subp : ppanel; { sub panel if a bordered window }
  135. visible : boolean; { is the window visible? }
  136. hasframe : boolean;
  137. wincolor, { window color }
  138. framecolor, { frame color }
  139. hdrcolor : integer; { header color }
  140. header : string[80]; { header string }
  141. Public
  142. ec : tEC; { edit control settings }
  143. Constructor Init(x,y,x1,y1,wcolor : integer;
  144. border : boolean;
  145. fcolor : integer);
  146. Destructor Done;
  147. Procedure Show; { display the window }
  148. Procedure Hide; { hide the window }
  149. Procedure ClrScr;
  150. Procedure ClrEol;
  151. Procedure ClrBot;
  152. Procedure InsLine;
  153. Procedure DelLine;
  154. Procedure GotoXY(x,y : integer);
  155. Function WhereX : integer;
  156. Function WhereY : integer;
  157. Function ReadKey : char;
  158. Function Readln : string;
  159. Procedure Write(s : string);
  160. Procedure Writeln(s : string);
  161. Procedure WriteAC(x,y,att,c : longint);
  162. Procedure FWrite(x,y,att,z : integer; s : string);
  163. Procedure DrawBox(LineStyle,x1,y1,x2,y2,att : Integer);
  164. Function GetHeader : string;
  165. Procedure PutHeader(hdr : string; hcolor : integer; hpos : tnJustify);
  166. Procedure SetColor(att : integer);
  167. Procedure PutFrame(att : integer);
  168. Procedure Move(x,y : integer);
  169. Procedure Scroll(ln : integer; dir : tnUpDown);
  170. Procedure Align(hpos,vpos : tnJustify);
  171. Function Rows : integer;
  172. Function Cols : integer;
  173. Function SEdit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
  174. End;
  175. Var
  176. nscreen : pwin;
  177. nEC : tEC;
  178. Procedure nSetActiveWin(win : pwindow);
  179. Procedure nDoNow(donow : boolean);
  180. Function nKeypressed(timeout : word) : boolean;
  181. Procedure nEcho(b : boolean);
  182. Procedure nWindow(var win : pWindow; x,y,x1,y1 : integer);
  183. Procedure nNewWindow(var win : pWindow; x,y,x1,y1 : integer);
  184. Procedure nDelWindow(var win : pWindow);
  185. Procedure nWinColor(win : pWindow; att : integer);
  186. Procedure nClrScr(win : pWindow; att : integer);
  187. Procedure nClrEol(win : pWindow);
  188. Procedure nClrBot(win : pWindow);
  189. Procedure nInsLine(win : pWindow);
  190. Procedure nDelLine(win : pWindow);
  191. Procedure nGotoXY(win : pWindow; x,y : integer);
  192. Function nWhereX(win : pWindow) : integer;
  193. Function nWhereY(win : pWindow) : integer;
  194. Function nReadkey(win : pWindow) : char;
  195. Function nReadln(win : pWindow) : string;
  196. Procedure nWrite(win : pWindow; s : string);
  197. Procedure nWriteln(win : pWindow; s : string);
  198. Procedure nWriteScr(win : pWindow; x,y,att : integer; s : string);
  199. Procedure nRefresh(win : pWindow);
  200. Procedure nScroll(win : pWindow; lines : integer; dir : tnUpDown);
  201. Procedure nDrawBox(win : pWindow; LineStyle,x1,y1,x2,y2,att : Integer);
  202. Procedure nFrame(win : pWindow);
  203. Function nRows(win : pWindow) : integer;
  204. Function nCols(win : pWindow) : integer;
  205. Function nHL : longint; { horizontal line }
  206. Function nVL : longint; { vertical line }
  207. Function nUL : longint; { upper left corner }
  208. Function nLL : longint; { lower loft corner }
  209. Function nUR : longint; { upper right corner }
  210. Function nLR : longint; { lower right corner }
  211. Function nLT : longint; { left tee }
  212. Function nRT : longint; { right tee }
  213. Function nTT : longint; { top tee }
  214. Function nBT : longint; { bottom tee }
  215. Function nPL : longint; { plus, + }
  216. Function nLA : longint; { left arrow }
  217. Function nRA : longint; { right arrow }
  218. Function nUA : longint; { up arror }
  219. Function nDA : longint; { down arrow }
  220. Function nDI : longint; { diamond }
  221. Function nCB : longint; { checkerboard }
  222. Function nDG : longint; { degree }
  223. Function nPM : longint; { plus/minus }
  224. Function nBL : longint; { bullet }
  225. Procedure nHLine(win : pwindow; col,row,attr,x : integer);
  226. Procedure nVLine(win : pwindow; col,row,attr,y : integer);
  227. Procedure nWriteAC(win : pwindow; x,y : integer; att,acs_char : longint);
  228. Function IsBold(att : integer) : boolean;
  229. Function SetColorPair(att : integer) : integer;
  230. Procedure FWrite(col,row,attrib : integer; clear : integer; s : string);
  231. Function nSEdit(win : pwindow; x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
  232. {$i ncrt.inc}
  233. Const
  234. internal_fwrite : Boolean = false;
  235. { internal wrapper }
  236. Procedure intFWrite(win : pwindow; col,row,attrib,clear : integer; s : string);
  237. Var
  238. tmp : pwindow;
  239. Begin
  240. tmp := ActiveWn;
  241. ActiveWn := win;
  242. internal_fwrite := true;
  243. FWrite(col,row,attrib,clear,s);
  244. internal_fwrite := false;
  245. ActiveWn := tmp;
  246. End;
  247. {---------------------------------------------------------------------
  248. tnWindow.Init
  249. Create a new window.
  250. x = upper left corner x, screen relative
  251. y = upper left corner y, screen relative
  252. x1 = lower right corner x, screen relative
  253. y1 = lower right corner y, screen relative
  254. wcolor = window/text color
  255. border = include a frame?
  256. fcolor = frame color
  257. ---------------------------------------------------------------------}
  258. Constructor tnWindow.Init(x,y,x1,y1,wcolor : integer;
  259. border : boolean;
  260. fcolor : integer);
  261. Begin
  262. visible := false;
  263. hasframe := false;
  264. wincolor := wcolor;
  265. framecolor := fcolor;
  266. hdrcolor := wcolor;
  267. header := '';
  268. win := nil;
  269. sub := nil;
  270. pan := nil;
  271. subp := nil;
  272. visible := false;
  273. win := newwin(y1-y+1,x1-x+1,y-1,x-1);
  274. pan := new_panel(win);
  275. hide_panel(pan);
  276. If border Then
  277. PutFrame(fcolor)
  278. Else Begin
  279. wn := win;
  280. wbkgd(win,COLOR_PAIR(SetColorPair(wcolor)));
  281. If isbold(wcolor) then wattr_on(win,A_BOLD);
  282. scrollok(win,bool(true));
  283. intrflush(stdscr,bool(false));
  284. keypad(stdscr,bool(true));
  285. End;
  286. ec.Init(false,false,false,false,'');
  287. ActiveWn := wn;
  288. End;
  289. { deallocate the window }
  290. Destructor tnWindow.Done;
  291. Begin
  292. If subp <> nil Then del_panel(subp);
  293. If pan <> nil Then del_panel(pan);
  294. If sub <> nil Then delwin(sub);
  295. If win <> nil Then delwin(win);
  296. ec.Done;
  297. End;
  298. { display the window and move to the top }
  299. Procedure tnWindow.Show;
  300. Begin
  301. ActiveWn := wn;
  302. visible := true;
  303. show_panel(pan);
  304. If subp <> nil Then show_panel(subp);
  305. update_panels;
  306. doupdate;
  307. End;
  308. { hide the window }
  309. Procedure tnWindow.Hide;
  310. Begin
  311. ActiveWn := stdscr;
  312. visible := false;
  313. If subp <> nil Then hide_panel(subp);
  314. hide_panel(pan);
  315. update_panels;
  316. doupdate;
  317. End;
  318. Procedure tnWindow.ClrScr;
  319. Begin
  320. tmp_b := dorefresh;
  321. dorefresh := visible;
  322. nClrScr(wn,wincolor);
  323. dorefresh := tmp_b;
  324. End;
  325. Procedure tnWindow.ClrEol;
  326. Begin
  327. tmp_b := dorefresh;
  328. dorefresh := visible;
  329. nClrEol(wn);
  330. dorefresh := tmp_b;
  331. End;
  332. Procedure tnWindow.ClrBot;
  333. Begin
  334. tmp_b := dorefresh;
  335. dorefresh := visible;
  336. nClrBot(wn);
  337. dorefresh := tmp_b;
  338. End;
  339. Procedure tnWindow.InsLine;
  340. Begin
  341. tmp_b := dorefresh;
  342. dorefresh := visible;
  343. nInsLine(wn);
  344. dorefresh := tmp_b;
  345. End;
  346. Procedure tnWindow.DelLine;
  347. Begin
  348. tmp_b := dorefresh;
  349. dorefresh := visible;
  350. nDelLine(wn);
  351. dorefresh := tmp_b;
  352. End;
  353. { return the window border header string }
  354. Function tnWindow.GetHeader : string;
  355. Begin
  356. GetHeader := header;
  357. End;
  358. {----------------------------------------------------------------------
  359. put/replace a header string at the top of a bordered window
  360. hdr = header string (top line of window, only if hasframe = true)
  361. hcolor = header line color
  362. hpos = justfication of header string, left, center, or right
  363. ----------------------------------------------------------------------}
  364. Procedure tnWindow.PutHeader(hdr : string; hcolor : integer; hpos : tnJustify);
  365. Var
  366. cp,
  367. hx,
  368. len : integer;
  369. att,
  370. mx,my : longint;
  371. Begin
  372. If Hasframe Then Begin
  373. If hdr <> '' Then Begin
  374. header := hdr;
  375. hdrcolor := hcolor;
  376. getmaxyx(win,my,mx);
  377. nHline(win,2,1,framecolor,mx-1);
  378. len := mx-2;
  379. hdr := Copy(hdr,1,len);
  380. len := Length(hdr);
  381. Case hpos of
  382. left : hx := 1;
  383. center : hx := (mx - len) div 2;
  384. right : hx := (mx - len) - 1;
  385. End;
  386. mvwaddstr(win,0,hx,StrPCopy(ps,hdr));
  387. cp := SetColorPair(hcolor);
  388. If IsBold(hcolor) Then
  389. att := A_BOLD
  390. Else
  391. att := A_NORMAL;
  392. mvwchgat(win,0,hx,len,att,cp,0);
  393. End;
  394. End;
  395. End;
  396. { set the the color of the writable window }
  397. Procedure tnWindow.SetColor(att : integer);
  398. Begin
  399. wbkgd(wn,COLOR_PAIR(SetColorPair(att)));
  400. If isbold(att) then wattr_set(wn,A_BOLD);
  401. wincolor := att;
  402. If visible Then wrefresh(wn);
  403. End;
  404. { frame an un-framed window, or update the frame color of a framed window }
  405. Procedure tnWindow.PutFrame(att : integer);
  406. Var
  407. x,y,
  408. mx,my,
  409. atts : longint;
  410. Begin
  411. wbkgd(win,COLOR_PAIR(SetColorPair(att)));
  412. atts := wattr_get(win);
  413. If isbold(att) then wattr_on(win,atts or A_BOLD);
  414. box(win,ACS_VLINE,ACS_HLINE);
  415. framecolor := att;
  416. If framecolor = -1 Then framecolor := wincolor;
  417. hasframe := true;
  418. If sub = nil Then Begin
  419. getbegyx(win,y,x);
  420. getmaxyx(win,my,mx);
  421. sub := newwin(my-2,mx-2,y+1,x+1);
  422. If sub <> nil Then Begin
  423. subp := new_panel(sub);
  424. hide_panel(subp);
  425. wbkgd(sub,COLOR_PAIR(SetColorPair(wincolor)));
  426. If isbold(wincolor) then wattr_on(sub,A_BOLD);
  427. scrollok(sub,bool(true));
  428. intrflush(sub,bool(false));
  429. keypad(sub,bool(true));
  430. wn := sub;
  431. End;
  432. End;
  433. touchwin(sub);
  434. If visible Then Begin
  435. wrefresh(win);
  436. wrefresh(sub);
  437. End;
  438. End;
  439. { move the window }
  440. Procedure tnWindow.Move(x,y : integer);
  441. Begin
  442. move_panel(pan,y-1,x-1);
  443. If subp <> nil Then move_panel(subp,y,x);
  444. If visible Then Begin
  445. update_panels;
  446. doupdate;
  447. End;
  448. End;
  449. Procedure tnWindow.Align(hpos,vpos : tnJustify);
  450. Var
  451. x,y,
  452. bx,by : longint;
  453. Begin
  454. getmaxyx(win,y,x);
  455. getbegyx(win,by,bx);
  456. Case hpos of
  457. none : x := bx+1;
  458. left : x := 1;
  459. right : x := MaxCols - x;
  460. center : x := (MaxCols - x) div 2;
  461. End;
  462. Case vpos of
  463. none : y := by+1;
  464. top : y := 1;
  465. bottom : y := MaxRows - y;
  466. center : y := (MaxRows - y) div 2;
  467. End;
  468. move(x,y);
  469. End;
  470. Procedure tnWindow.Scroll(ln : integer; dir : tnUpDown);
  471. Begin
  472. nScroll(wn,ln,dir);
  473. End;
  474. Procedure tnWindow.GotoXY(x,y : integer);
  475. Begin
  476. tmp_b := dorefresh;
  477. dorefresh := visible;
  478. nGotoXY(wn,x,y);
  479. dorefresh := tmp_b;
  480. End;
  481. Function tnWindow.WhereX : integer;
  482. Begin
  483. WhereX := nWhereX(wn);
  484. End;
  485. Function tnWindow.WhereY : integer;
  486. Begin
  487. WhereY := nWhereY(wn);
  488. End;
  489. Function tnWindow.ReadKey : char;
  490. Begin
  491. ReadKey := nReadKey(wn);
  492. End;
  493. Function tnWindow.Readln : string;
  494. Begin
  495. Readln := nReadln(wn);
  496. End;
  497. Procedure tnWindow.Write(s : string);
  498. Begin
  499. tmp_b := dorefresh;
  500. dorefresh := visible;
  501. nWrite(wn,s);
  502. dorefresh := tmp_b;
  503. End;
  504. Procedure tnWindow.Writeln(s : string);
  505. Begin
  506. tmp_b := dorefresh;
  507. dorefresh := visible;
  508. nWriteln(wn,s);
  509. dorefresh := tmp_b;
  510. End;
  511. Procedure tnWindow.WriteAC(x,y,att,c : longint);
  512. Begin
  513. tmp_b := dorefresh;
  514. dorefresh := visible;
  515. nWriteAC(wn,x,y,att,c);
  516. dorefresh := tmp_b;
  517. End;
  518. Procedure tnWindow.FWrite(x,y,att,z : integer; s : string);
  519. Var tmp : pwindow;
  520. Begin
  521. tmp_b := dorefresh;
  522. dorefresh := visible;
  523. tmp := ActiveWn;
  524. ActiveWn := wn;
  525. intFWrite(wn,x,y,att,z,s);
  526. ActiveWn := tmp;
  527. dorefresh := tmp_b;
  528. End;
  529. Procedure tnWindow.DrawBox(LineStyle,x1,y1,x2,y2,att : Integer);
  530. Begin
  531. tmp_b := dorefresh;
  532. dorefresh := visible;
  533. nDrawBox(wn,LineStyle,x1,y1,x2,y2,att);
  534. dorefresh := tmp_b;
  535. End;
  536. Function tnWindow.Rows : integer;
  537. Begin
  538. Rows := nRows(wn);
  539. End;
  540. Function tnWindow.Cols : integer;
  541. Begin
  542. Cols := nCols(wn);
  543. End;
  544. Function tnWindow.SEdit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
  545. var
  546. tmp_ec : tec;
  547. Begin
  548. tmp_ec.Init(nEC.FirstTime,nEC.IsHidden,nEC.InsMode,nEC.ExitMode,
  549. nEC.Special);
  550. nEC.Init(ec.FirstTime,ec.IsHidden,ec.InsMode,ec.ExitMode,
  551. ec.Special);
  552. SEdit := nSEdit(wn,x,y,att,z,CursPos,es,ch);
  553. ec.Init(nEC.FirstTime,nEC.IsHidden,nEC.InsMode,ec.ExitMode,
  554. ec.Special);
  555. nEC.Init(tmp_ec.FirstTime,tmp_ec.IsHidden,tmp_ec.InsMode,tmp_ec.ExitMode,
  556. tmp_ec.Special);
  557. tmp_ec.Done;
  558. End;
  559. {--------------------------- tEC -------------------------------}
  560. Constructor tEC.Init(ft,ih,im,em : boolean; s : string);
  561. Begin
  562. FirstTime := ft;
  563. IsHidden := ih;
  564. InsMode := im;
  565. ExitMode := em;
  566. Special := s;
  567. End;
  568. Destructor tEC.Done;
  569. Begin
  570. End;
  571. {==========================================================================}
  572. { set the active window for write(ln), read(ln) }
  573. Procedure nSetActiveWin(win : pwindow);
  574. Begin
  575. ActiveWn := win;
  576. End;
  577. {----------------------------------------------------------------
  578. Set the refresh toggle.
  579. If true, then all changes to a window are immediate. If false,
  580. then changes appear following the next call to nRefresh.
  581. ----------------------------------------------------------------}
  582. Procedure nDoNow(donow : boolean);
  583. Begin
  584. dorefresh := donow;
  585. End;
  586. {-----------------------------------------------------
  587. Set the echo flag.
  588. This determines whether or not, characters are
  589. echoed to the display when entered via the keyboard.
  590. -----------------------------------------------------}
  591. Procedure nEcho(b : boolean);
  592. Begin
  593. Case b of
  594. true : echo;
  595. false: noecho;
  596. End;
  597. isEcho := b;
  598. End;
  599. { create a new subwindow of stdscr }
  600. Procedure nWindow(var win : pWindow; x,y,x1,y1 : integer);
  601. Begin
  602. nDelWindow(win);
  603. win := subwin(stdscr,y1-y+1,x1-x+1,y-1,x-1);
  604. If win = nil then Exit;
  605. intrflush(win,bool(false));
  606. keypad(win,bool(true));
  607. scrollok(win,bool(true));
  608. ActiveWn := win;
  609. End;
  610. { create a new window }
  611. Procedure nNewWindow(var win : pWindow; x,y,x1,y1 : integer);
  612. Begin
  613. nDelWindow(win);
  614. win := newwin(y1-y+1,x1-x+1,y-1,x-1);
  615. If win = nil then Exit;
  616. intrflush(win,bool(false));
  617. keypad(win,bool(true));
  618. scrollok(win,bool(true));
  619. ActiveWn := win;
  620. End;
  621. { repaint a window }
  622. Procedure nRefresh(win : pWindow);
  623. Begin
  624. touchwin(win);
  625. wrefresh(win);
  626. End;
  627. {----------------------------------------------
  628. Wait for a key to be pressed, with a timeout.
  629. If a key is pressed, then nKeypressed returns
  630. immediately as true, otherwise it return as
  631. false after the timeout period.
  632. ----------------------------------------------}
  633. function nKeypressed(timeout : word) : boolean;
  634. var
  635. fds : FDSet;
  636. maxFD : longint;
  637. Begin
  638. FD_Zero(fds);
  639. maxFD := 1;
  640. { turn on stdin bit }
  641. If not FD_IsSet(STDIN,fds) Then FD_Set(STDIN,fds);
  642. { wait for some input }
  643. If Select(maxFD,@fds,nil,nil,timeout) > 0 Then
  644. nKeypressed := TRUE
  645. Else
  646. nKeypressed := FALSE;
  647. End;
  648. {---------------------------------
  649. read input string from a window
  650. ---------------------------------}
  651. Function nReadln(win : pWindow) : string;
  652. Begin
  653. wgetstr(win,ps);
  654. nReadln := StrPas(ps);
  655. End;
  656. { write a string to a window without refreshing screen }
  657. Procedure nWriteScr(win : pWindow; x,y,att : integer; s : string);
  658. Var
  659. tmp : pwindow;
  660. Begin
  661. tmp := ActiveWn;
  662. tmp_b := doRefresh;
  663. ActiveWn := win;
  664. doRefresh := false;
  665. intFWrite(win,x,y,att,0,s);
  666. ActiveWn := tmp;
  667. doRefresh := tmp_b;
  668. End;
  669. {----------------------------------------------------------
  670. Scroll a window, up or down, a specified number of lines.
  671. lines = number of lines to scroll.
  672. dir = direction, up or down.
  673. ----------------------------------------------------------}
  674. Procedure nScroll(win : pWindow; lines : integer; dir : tnUpDown);
  675. Begin
  676. ScrollOk(win,bool(True));
  677. Case dir of
  678. up : lines := abs(lines);
  679. down : lines := abs(lines) * (-1);
  680. End;
  681. wscrl(win,lines);
  682. If doRefresh Then wRefresh(win);
  683. End;
  684. { draw a colored box, with or without a border }
  685. Procedure nDrawBox(win : pWindow; LineStyle,x1,y1,x2,y2,att : Integer);
  686. Var
  687. sub : pWindow;
  688. x,y : longint;
  689. Begin
  690. getbegyx(win,y,x);
  691. sub := subwin(win,y2-y1+1,x2-x1+1,y+y1-1,x+x1-1);
  692. If sub = nil Then exit;
  693. wbkgd(sub,CursesAtts(att));
  694. werase(sub);
  695. case LineStyle of
  696. 1,2 : box(sub, ACS_VLINE, ACS_HLINE);
  697. End;
  698. If doRefresh Then wrefresh(sub);
  699. nDelWindow(sub);
  700. End;
  701. {---------------------------
  702. add a border to a window,
  703. waits for a refresh
  704. ---------------------------}
  705. Procedure nFrame(win : pWindow);
  706. Begin
  707. box(win, ACS_VLINE, ACS_HLINE);
  708. End;
  709. {-----------------------------------------------------------
  710. write a string to a window at the current cursor position
  711. followed by a newline
  712. -----------------------------------------------------------}
  713. Procedure nWriteln(win : pWindow; s : string);
  714. Begin
  715. waddstr(win,StrPCopy(ps,s+#10));
  716. If doRefresh Then wrefresh(win);
  717. End;
  718. { return then number of rows in a window }
  719. Function nRows(win : pWindow) : integer;
  720. Var
  721. x,y : longint;
  722. Begin
  723. getmaxyx(win,y,x);
  724. nRows := y;
  725. End;
  726. { return then number of columns in a window }
  727. Function nCols(win : pWindow) : integer;
  728. Var
  729. x,y : longint;
  730. Begin
  731. getmaxyx(win,y,x);
  732. nCols := x;
  733. End;
  734. {-------------------------------------------------------
  735. Line drawing characters have to be handled specially.
  736. Use nWriteAC() to write these characters. They cannot
  737. be simply included as characters in a string.
  738. -------------------------------------------------------}
  739. { returns horizontal line character }
  740. Function nHL : longint;
  741. Begin
  742. nHL := ACS_HLINE;
  743. End;
  744. { returns vertical line character }
  745. Function nVL : longint;
  746. Begin
  747. nVL := ACS_VLINE;
  748. End;
  749. { returns upper left corner character }
  750. Function nUL : longint;
  751. Begin
  752. nUL := ACS_ULCORNER;
  753. End;
  754. { returns lower left corner character }
  755. Function nLL : longint;
  756. Begin
  757. nLL := ACS_LLCORNER;
  758. End;
  759. { returns upper right corner character }
  760. Function nUR : longint;
  761. Begin
  762. nUR := ACS_URCORNER;
  763. End;
  764. { returns lower right corner character }
  765. Function nLR : longint;
  766. Begin
  767. nLR := ACS_LRCORNER;
  768. End;
  769. { returns left tee character }
  770. Function nLT : longint;
  771. Begin
  772. nLT := ACS_LTEE;
  773. End;
  774. { returns right tee character }
  775. Function nRT : longint;
  776. Begin
  777. nRT := ACS_RTEE;
  778. End;
  779. { returns top tee character }
  780. Function nTT : longint;
  781. Begin
  782. nTT := ACS_TTEE;
  783. End;
  784. { returns bottom tee character }
  785. Function nBT : longint;
  786. Begin
  787. nBT := ACS_BTEE;
  788. End;
  789. { returns plus/cross character }
  790. Function nPL : longint;
  791. Begin
  792. nPL := ACS_PLUS;
  793. End;
  794. { returns left arrow character }
  795. Function nLA : longint;
  796. Begin
  797. nLA := ACS_LARROW;
  798. End;
  799. { returns right arrow character }
  800. Function nRA : longint;
  801. Begin
  802. nRA := ACS_RARROW;
  803. End;
  804. { returns up arrow character }
  805. Function nUA : longint;
  806. Begin
  807. nUA := ACS_UARROW;
  808. End;
  809. { returns down arrow character }
  810. Function nDA : longint;
  811. Begin
  812. nDA := ACS_DARROW;
  813. End;
  814. { returns diamond character }
  815. Function nDI : longint;
  816. Begin
  817. nDI := ACS_DIAMOND;
  818. End;
  819. { returns checkerboard character }
  820. Function nCB : longint;
  821. Begin
  822. nCB := ACS_CKBOARD;
  823. End;
  824. { returns degree character }
  825. Function nDG : longint;
  826. Begin
  827. nDG := ACS_DEGREE;
  828. End;
  829. { returns plus/minus character }
  830. Function nPM : longint;
  831. Begin
  832. nPM := ACS_PLMINUS;
  833. End;
  834. { returns bullet character }
  835. Function nBL : longint;
  836. Begin
  837. nBL := ACS_BULLET;
  838. End;
  839. { draw a horizontal line with color and a start & end position }
  840. Procedure nHLine(win : pwindow; col,row,attr,x : integer);
  841. var
  842. sub : pwindow;
  843. bx,by : longint;
  844. Begin
  845. getbegyx(win,by,bx);
  846. sub := subwin(win,1,x-col+1,by+row-1,bx+col-1);
  847. If sub = nil Then Exit;
  848. x := getmaxx(sub);
  849. wbkgd(sub,CursesAtts(attr));
  850. mvwhline(sub,0,0,ACS_HLINE,x);
  851. If doRefresh Then wrefresh(sub);
  852. delwin(sub);
  853. End;
  854. { draw a vertical line with color and a start & end position }
  855. Procedure nVLine(win : pwindow; col,row,attr,y : integer);
  856. var sub : pwindow;
  857. Begin
  858. sub := subwin(win,y-row+1,1,row-1,col-1);
  859. If sub = nil Then Exit;
  860. wbkgd(sub,CursesAtts(attr));
  861. mvwvline(sub,0,0,ACS_VLINE,y);
  862. If doRefresh Then wrefresh(sub);
  863. delwin(sub);
  864. End;
  865. {----------------------------------------------------------------
  866. Write a character from the alternate character set. A normal
  867. value from the alternate character set is larger than $400000.
  868. If the value passed here is 128..255, then we assume it to be
  869. the ordinal value from the IBM extended character set, and try
  870. to map it to curses correctly. If it does not map, then we just
  871. make it an alternate character and hope the output is what the
  872. programmer expected. Note: this will work on the Linux console
  873. just fine, but for other terminals the passed value must match
  874. the termcap definition for the alternate character.
  875. Note: The cursor returns to it's original position.
  876. ----------------------------------------------------------------}
  877. Procedure nWriteAC(win : pwindow; x,y : integer; att,acs_char : longint);
  878. var
  879. xx,yy,
  880. cp : longint;
  881. Begin
  882. If acs_char in [0..255] Then Begin
  883. Case acs_char of
  884. 176 : acs_char := ACS_CKBOARD;
  885. 179 : acs_char := ACS_VLINE;
  886. 180 : acs_char := ACS_RTEE;
  887. 191 : acs_char := ACS_URCORNER;
  888. 192 : acs_char := ACS_LLCORNER;
  889. 193 : acs_char := ACS_BTEE;
  890. 194 : acs_char := ACS_TTEE;
  891. 195 : acs_char := ACS_LTEE;
  892. 196 : acs_char := ACS_HLINE;
  893. 197 : acs_char := ACS_PLUS;
  894. 218 : acs_char := ACS_ULCORNER;
  895. 217 : acs_char := ACS_LRCORNER;
  896. 241 : acs_char := ACS_PLMINUS;
  897. 248 : acs_char := ACS_DEGREE;
  898. 249 : acs_char := ACS_BULLET;
  899. else acs_char := acs_char or A_ALTCHARSET;
  900. End;
  901. End;
  902. { save the current cursor position }
  903. getyx(win,yy,xx);
  904. cp := SetColorPair(att);
  905. { write character with current attributes }
  906. mvwaddch(win,y-1,x-1,acs_char);
  907. { update with new attributes }
  908. If IsBold(att) Then
  909. att := A_BOLD or A_ALTCHARSET
  910. Else
  911. att := A_NORMAL or A_ALTCHARSET;
  912. mvwchgat(win,y-1,x-1,1,att,cp,0);
  913. { return cursor to saved position }
  914. wmove(win,yy,xx);
  915. If doRefresh Then wrefresh(win);
  916. End;
  917. {-------------------------------------------------------------------
  918. write a string to stdscr with color, without moving the cursor
  919. Col = x start position
  920. Row = y start position
  921. Attrib = color (0..127), note color = (background*16)+foreground
  922. Clear = clear line up to x position
  923. s = string to write
  924. -------------------------------------------------------------------}
  925. Procedure FWrite(col,row,attrib : integer; clear : integer; s : string);
  926. Const
  927. ClearLine = { Following line is 80 Spaces }
  928. ' ';
  929. Var
  930. cs : string;
  931. tmp,
  932. sub : pWindow;
  933. x,y,
  934. xx,yy : longint;
  935. Begin
  936. if Clear > 0 Then Begin
  937. If Clear > 80 Then Clear := 80;
  938. cs := Copy(ClearLine,1,(Clear-Col)-Length(s)+1);
  939. End Else
  940. cs := '';
  941. s := s+cs;
  942. If s = '' Then Exit;
  943. tmp := ActiveWn;
  944. getyx(ActiveWn,yy,xx);
  945. If Not internal_fwrite Then ActiveWn := stdscr;
  946. getbegyx(ActiveWn,y,x);
  947. sub := subwin(ActiveWn,1,Length(s),y+row-1,x+col-1);
  948. ActiveWn := tmp;
  949. If sub = nil Then Exit;
  950. wbkgd(sub,COLOR_PAIR(SetColorPair(Attrib)));
  951. If isbold(Attrib) then
  952. wattr_on(sub,A_BOLD);
  953. mvwaddstr(sub,0,0,StrPCopy(ps,s));
  954. If doRefresh Then wrefresh(sub);
  955. delwin(sub);
  956. wmove(ActiveWn,yy,xx);
  957. End;
  958. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  959. { String Editor }
  960. Function nSEdit(win : pwindow; x,y,att,z,CursPos:integer;
  961. es:string;var ch : char) : string;
  962. Var
  963. ZMode,
  964. SEditExit : boolean;
  965. Index : integer;
  966. hes : string;
  967. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  968. Procedure NewString;
  969. BEGIN
  970. nSEdit := es;
  971. hes := es;
  972. FillChar(hes[1],Length(hes),'*');
  973. END;
  974. Procedure WriteString;
  975. Var
  976. xx,yy : integer;
  977. Begin
  978. xx := nWhereX(win);
  979. yy := nWhereY(win);
  980. If nEC.IsHidden Then
  981. intFWrite(win,x,y,att,z,hes)
  982. Else
  983. intFWrite(win,x,y,att,z,es);
  984. nGotoXY(win,xx,yy);
  985. End;
  986. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  987. Procedure EInsMode;
  988. Begin
  989. nEC.InsMode := (not nEC.InsMode)
  990. End;
  991. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  992. Procedure WriteChar;
  993. Begin
  994. If nWhereX(win) >= Length(es)+x Then Repeat
  995. es := es + ' ';
  996. Until Length(es)+X-1 = nWhereX(win);
  997. If Length(es)+X-1 = nWhereX(win) Then Index := Length(es);
  998. es[Index] := ch;
  999. If nEC.IsHidden Then Ch := '*';
  1000. intFWrite(win,nWhereX(win),nWhereY(win),Att,0,Ch);
  1001. If (Index < Z-X+1) or not ZMode Then Begin
  1002. Index := Index+1;
  1003. nGotoXY(win,X+Index-1,Y);
  1004. End;
  1005. Ch := #255;{ Set Ch to No Execute Character }
  1006. NewString;
  1007. End;
  1008. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1009. Procedure EInsert; { Insert }
  1010. Begin
  1011. If Length(es) < Z-X+1 Then Begin
  1012. Insert(' ',es,Index);
  1013. NewString;
  1014. WriteString;
  1015. End;
  1016. End;
  1017. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1018. Procedure EDelete; { Delete }
  1019. Begin
  1020. Delete(es,Index,1);
  1021. NewString;
  1022. WriteString;
  1023. End;
  1024. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1025. Procedure ECtrlEnd; { <CTRL> End }
  1026. Begin
  1027. Delete(es,Index,Length(es));
  1028. NewString;
  1029. WriteString;
  1030. End;
  1031. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1032. Procedure EHome; { Home }
  1033. Begin
  1034. Index := 1;
  1035. nGotoXY(win,x,y);
  1036. End;
  1037. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1038. Procedure ELeftArrow; { Left Arrow }
  1039. Begin
  1040. Index := Index - 1;
  1041. If Index < 1 Then
  1042. Index := 1
  1043. Else
  1044. nGotoXY(win,nWhereX(win)-1,nWhereY(win));
  1045. End;
  1046. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1047. Procedure ERightArrow; { Right Arrow }
  1048. Begin
  1049. If Index < z-x+1 Then Begin
  1050. nGotoXY(win,nWhereX(win)+1,nWhereY(win));
  1051. Index := Index + 1;
  1052. End;
  1053. End;
  1054. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1055. Procedure EEnd; { End }
  1056. Begin
  1057. Index := Length(es)+1;
  1058. If Index >= z-x+1 Then Index := Length(es);
  1059. If Index < 1 Then Index := 1;
  1060. nGotoXY(win,x+(Index-1),y);
  1061. End;
  1062. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1063. Procedure EBackSpace; { Backspace }
  1064. Begin
  1065. Index := Index - 1;
  1066. If Index < 1 Then Begin
  1067. Index := 1;
  1068. Exit;
  1069. End Else
  1070. If nWhereX(win) > x Then nGotoXY(win,nWhereX(win) - 1,nWhereY(win));
  1071. Delete(es,Index,1);
  1072. NewString;
  1073. WriteString;
  1074. nGotoXY(win,x+(Index-1),y);
  1075. End;
  1076. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1077. Procedure ETurboBackSpace; { Ctrl/Backspace }
  1078. Begin
  1079. If Index = 1 Then Exit;
  1080. Delete(es,1,Index-1);
  1081. NewString;
  1082. Index := 1;
  1083. If nWhereX(win) > x Then nGotoXY(win,1,nWhereY(win));
  1084. WriteString;
  1085. nGotoXY(win,x,y);
  1086. END;
  1087. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1088. Procedure ECtrlLeftArrow;{ Ctrl Left Arrow }
  1089. Begin
  1090. If nEC.IsHidden Then Begin
  1091. EHome;
  1092. Exit;
  1093. End;
  1094. If es[Index-1] = ' ' Then Index := Index-1;
  1095. If es[Index] <> ' ' Then Begin
  1096. While (Index > 1) And (es[Index] <> ' ') Do
  1097. Index := Index-1;
  1098. End Else
  1099. If es[Index] = ' ' Then Begin
  1100. While (Index > 1) And (es[Index] = ' ') Do
  1101. Index := Index-1;
  1102. While (Index > 1) And (es[Index] <> ' ') Do
  1103. Index := Index-1;
  1104. End;
  1105. If Index = 1 Then
  1106. nGotoXY(win,x,y)
  1107. Else Begin
  1108. nGotoXY(win,x+Index,y);
  1109. Index := Index+1;
  1110. End;
  1111. End;
  1112. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1113. Procedure ECtrlRightArrow;{ Ctrl Right Arrow }
  1114. Begin
  1115. If nEC.IsHidden Then Begin
  1116. EEnd;
  1117. Exit;
  1118. End;
  1119. While (Index < Length(es)) And (es[Index] <> ' ') Do
  1120. Begin
  1121. Index := Index+1;
  1122. End;
  1123. While (Index < Length(es)) And (es[Index] = ' ') Do
  1124. Begin
  1125. Index := Index+1;
  1126. End;
  1127. nGotoXY(win,x+Index-1,y);
  1128. End;
  1129. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1130. Procedure CheckForWriteChar;
  1131. Begin
  1132. If Not (Ch In [#8,#9,#27,#127,#255]) Then Begin
  1133. If (ch in [#10,#13]) {and not ControlKey} Then exit;
  1134. If nEC.FirstTime Then Begin
  1135. es := '';
  1136. WriteString;
  1137. nGotoXY(win,X,Y);
  1138. Index := 1;
  1139. WriteChar;
  1140. nEC.FirstTime := False;
  1141. End Else Begin
  1142. If nEC.InsMode Then Begin
  1143. EInsert;
  1144. WriteChar;
  1145. End Else WriteChar;
  1146. End;
  1147. End;
  1148. End;
  1149. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1150. Procedure ProcessSpecialKey;
  1151. begin
  1152. Case ch of
  1153. #16..#25,
  1154. #30..#38,
  1155. #44..#50,
  1156. #59..#68,
  1157. #84..#90,
  1158. #92..#113,
  1159. #118,
  1160. #132,
  1161. #72,
  1162. #73,
  1163. #80,
  1164. #81 : Begin SEditExit:=True;Exit;End;
  1165. #71 : EHome;
  1166. #75 : ELeftArrow;
  1167. #77 : ERightArrow;
  1168. #79 : EEnd;
  1169. #82 : EInsMode;
  1170. #83 : EDelete;
  1171. #15,
  1172. #115 : ECtrlLeftArrow;
  1173. #116 : ECtrlRightArrow;
  1174. #117 : ECtrlEnd;
  1175. End;
  1176. End;
  1177. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  1178. Procedure ProcessNormalKey;
  1179. Var
  1180. i : integer;
  1181. begin
  1182. For i := 1 to Length(nEC.Special) Do Begin
  1183. If ch = nEC.Special[i] Then Begin
  1184. SEditExit:=True;
  1185. Exit;
  1186. End;
  1187. End;
  1188. case ch of
  1189. #8 : Begin nEC.FirstTime := False;EBackSpace;End;
  1190. #9 : ECtrlRightArrow;
  1191. #127 : Begin nEC.FirstTime := False;ETurboBackSpace;End;
  1192. end;
  1193. CheckForWriteChar;
  1194. end;
  1195. {============================================================================}
  1196. Begin
  1197. SEditExit := nEC.ExitMode;
  1198. ZMode := z <> 0;
  1199. If CursPos > Length(es)+x Then
  1200. Index := Length(es)+1 { End Of String }
  1201. Else Index := CursPos+1-x; { Inside Of String }
  1202. If Not ZMode then z := x+length(es);
  1203. Newstring;
  1204. WriteString;
  1205. nGotoXY(win,CursPos,y);
  1206. Repeat
  1207. If Not ZMode then z := x+length(es);
  1208. ch := ReadKey;
  1209. If ch = #0 Then Begin
  1210. ch := ReadKey;
  1211. ProcessSpecialKey;
  1212. End Else
  1213. ProcessNormalKey;
  1214. Until (ch In [#10,#13,#27]) or SEditExit;
  1215. If ch = #10 Then ch := #13;
  1216. nEC.FirstTime := False;
  1217. NewString;
  1218. End;{ of nSEdit }
  1219. Begin
  1220. nEC.Init(false,false,false,false,'');
  1221. { load the color pairs array with color pair indices (0..63) }
  1222. For bg := 0 to 7 Do For fg := 0 to 7 do cp[bg,fg] := (bg*8)+fg;
  1223. { initialize ncurses }
  1224. If StartCurses(ActiveWn) Then
  1225. nscreen := ActiveWn
  1226. Else
  1227. Halt;
  1228. SubWn := nil;
  1229. TextMode(LastMode);
  1230. { Redirect the standard output }
  1231. assigncrt(Output);
  1232. Rewrite(Output);
  1233. TextRec(Output).Handle:=StdOutputHandle;
  1234. { Redirect the standard input }
  1235. assigncrt(Input);
  1236. Reset(Input);
  1237. TextRec(Input).Handle:=StdInputHandle;
  1238. { set the unit exit procedure }
  1239. ExitSave := ExitProc;
  1240. ExitProc := @nExit;
  1241. End. { of Unit nCrt }
  1242. ��� �