ncurses2-acs_and_scroll.adb 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. ------------------------------------------------------------------------------
  2. -- --
  3. -- GNAT ncurses Binding Samples --
  4. -- --
  5. -- ncurses --
  6. -- --
  7. -- B O D Y --
  8. -- --
  9. ------------------------------------------------------------------------------
  10. -- Copyright (c) 2000-2006,2008 Free Software Foundation, Inc. --
  11. -- --
  12. -- Permission is hereby granted, free of charge, to any person obtaining a --
  13. -- copy of this software and associated documentation files (the --
  14. -- "Software"), to deal in the Software without restriction, including --
  15. -- without limitation the rights to use, copy, modify, merge, publish, --
  16. -- distribute, distribute with modifications, sublicense, and/or sell --
  17. -- copies of the Software, and to permit persons to whom the Software is --
  18. -- furnished to do so, subject to the following conditions: --
  19. -- --
  20. -- The above copyright notice and this permission notice shall be included --
  21. -- in all copies or substantial portions of the Software. --
  22. -- --
  23. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS --
  24. -- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF --
  25. -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. --
  26. -- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, --
  27. -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR --
  28. -- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR --
  29. -- THE USE OR OTHER DEALINGS IN THE SOFTWARE. --
  30. -- --
  31. -- Except as contained in this notice, the name(s) of the above copyright --
  32. -- holders shall not be used in advertising or otherwise to promote the --
  33. -- sale, use or other dealings in this Software without prior written --
  34. -- authorization. --
  35. ------------------------------------------------------------------------------
  36. -- Author: Eugene V. Melaragno <aldomel@ix.netcom.com> 2000
  37. -- Version Control
  38. -- $Revision: 1.8 $
  39. -- $Date: 2008/07/26 18:47:42 $
  40. -- Binding Version 01.00
  41. ------------------------------------------------------------------------------
  42. -- Windows and scrolling tester.
  43. -- Demonstrate windows
  44. with Ada.Strings.Fixed;
  45. with Ada.Strings;
  46. with ncurses2.util; use ncurses2.util;
  47. with ncurses2.genericPuts;
  48. with Terminal_Interface.Curses; use Terminal_Interface.Curses;
  49. with Terminal_Interface.Curses.Mouse; use Terminal_Interface.Curses.Mouse;
  50. with Terminal_Interface.Curses.PutWin; use Terminal_Interface.Curses.PutWin;
  51. with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
  52. with Ada.Streams; use Ada.Streams;
  53. procedure ncurses2.acs_and_scroll is
  54. Macro_Quit : constant Key_Code := Character'Pos ('Q') mod 16#20#;
  55. Macro_Escape : constant Key_Code := Character'Pos ('[') mod 16#20#;
  56. Quit : constant Key_Code := CTRL ('Q');
  57. Escape : constant Key_Code := CTRL ('[');
  58. Botlines : constant Line_Position := 4;
  59. type pair is record
  60. y : Line_Position;
  61. x : Column_Position;
  62. end record;
  63. type Frame;
  64. type FrameA is access Frame;
  65. f : File_Type;
  66. dumpfile : constant String := "screendump";
  67. procedure Outerbox (ul, lr : pair; onoff : Boolean);
  68. function HaveKeyPad (w : Window) return Boolean;
  69. function HaveScroll (w : Window) return Boolean;
  70. procedure newwin_legend (curpw : Window);
  71. procedure transient (curpw : Window; msg : String);
  72. procedure newwin_report (win : Window := Standard_Window);
  73. procedure selectcell (uli : Line_Position;
  74. ulj : Column_Position;
  75. lri : Line_Position;
  76. lrj : Column_Position;
  77. p : out pair;
  78. b : out Boolean);
  79. function getwindow return Window;
  80. procedure newwin_move (win : Window;
  81. dy : Line_Position;
  82. dx : Column_Position);
  83. function delete_framed (fp : FrameA; showit : Boolean) return FrameA;
  84. use Ada.Streams.Stream_IO;
  85. -- A linked list
  86. -- I wish there was a standard library linked list. Oh well.
  87. type Frame is record
  88. next, last : FrameA;
  89. do_scroll : Boolean;
  90. do_keypad : Boolean;
  91. wind : Window;
  92. end record;
  93. current : FrameA;
  94. c : Key_Code;
  95. procedure Outerbox (ul, lr : pair; onoff : Boolean) is
  96. begin
  97. if onoff then
  98. -- Note the fix of an obscure bug
  99. -- try making a 1x1 box then enlarging it, the is a blank
  100. -- upper left corner!
  101. Add (Line => ul.y - 1, Column => ul.x - 1,
  102. Ch => ACS_Map (ACS_Upper_Left_Corner));
  103. Add (Line => ul.y - 1, Column => lr.x + 1,
  104. Ch => ACS_Map (ACS_Upper_Right_Corner));
  105. Add (Line => lr.y + 1, Column => lr.x + 1,
  106. Ch => ACS_Map (ACS_Lower_Right_Corner));
  107. Add (Line => lr.y + 1, Column => ul.x - 1,
  108. Ch => ACS_Map (ACS_Lower_Left_Corner));
  109. Move_Cursor (Line => ul.y - 1, Column => ul.x);
  110. Horizontal_Line (Line_Symbol => ACS_Map (ACS_Horizontal_Line),
  111. Line_Size => Integer (lr.x - ul.x) + 1);
  112. Move_Cursor (Line => ul.y, Column => ul.x - 1);
  113. Vertical_Line (Line_Symbol => ACS_Map (ACS_Vertical_Line),
  114. Line_Size => Integer (lr.y - ul.y) + 1);
  115. Move_Cursor (Line => lr.y + 1, Column => ul.x);
  116. Horizontal_Line (Line_Symbol => ACS_Map (ACS_Horizontal_Line),
  117. Line_Size => Integer (lr.x - ul.x) + 1);
  118. Move_Cursor (Line => ul.y, Column => lr.x + 1);
  119. Vertical_Line (Line_Symbol => ACS_Map (ACS_Vertical_Line),
  120. Line_Size => Integer (lr.y - ul.y) + 1);
  121. else
  122. Add (Line => ul.y - 1, Column => ul.x - 1, Ch => ' ');
  123. Add (Line => ul.y - 1, Column => lr.x + 1, Ch => ' ');
  124. Add (Line => lr.y + 1, Column => lr.x + 1, Ch => ' ');
  125. Add (Line => lr.y + 1, Column => ul.x - 1, Ch => ' ');
  126. Move_Cursor (Line => ul.y - 1, Column => ul.x);
  127. Horizontal_Line (Line_Symbol => Blank2,
  128. Line_Size => Integer (lr.x - ul.x) + 1);
  129. Move_Cursor (Line => ul.y, Column => ul.x - 1);
  130. Vertical_Line (Line_Symbol => Blank2,
  131. Line_Size => Integer (lr.y - ul.y) + 1);
  132. Move_Cursor (Line => lr.y + 1, Column => ul.x);
  133. Horizontal_Line (Line_Symbol => Blank2,
  134. Line_Size => Integer (lr.x - ul.x) + 1);
  135. Move_Cursor (Line => ul.y, Column => lr.x + 1);
  136. Vertical_Line (Line_Symbol => Blank2,
  137. Line_Size => Integer (lr.y - ul.y) + 1);
  138. end if;
  139. end Outerbox;
  140. function HaveKeyPad (w : Window) return Boolean is
  141. begin
  142. return Get_KeyPad_Mode (w);
  143. exception
  144. when Curses_Exception => return False;
  145. end HaveKeyPad;
  146. function HaveScroll (w : Window) return Boolean is
  147. begin
  148. return Scrolling_Allowed (w);
  149. exception
  150. when Curses_Exception => return False;
  151. end HaveScroll;
  152. procedure newwin_legend (curpw : Window) is
  153. package p is new genericPuts (200);
  154. use p;
  155. use p.BS;
  156. type string_a is access String;
  157. type rrr is record
  158. msg : string_a;
  159. code : Integer range 0 .. 3;
  160. end record;
  161. legend : constant array (Positive range <>) of rrr :=
  162. (
  163. (
  164. new String'("^C = create window"), 0
  165. ),
  166. (
  167. new String'("^N = next window"), 0
  168. ),
  169. (
  170. new String'("^P = previous window"), 0
  171. ),
  172. (
  173. new String'("^F = scroll forward"), 0
  174. ),
  175. (
  176. new String'("^B = scroll backward"), 0
  177. ),
  178. (
  179. new String'("^K = keypad(%s)"), 1
  180. ),
  181. (
  182. new String'("^S = scrollok(%s)"), 2
  183. ),
  184. (
  185. new String'("^W = save window to file"), 0
  186. ),
  187. (
  188. new String'("^R = restore window"), 0
  189. ),
  190. (
  191. new String'("^X = resize"), 0
  192. ),
  193. (
  194. new String'("^Q%s = exit"), 3
  195. )
  196. );
  197. buf : Bounded_String;
  198. do_keypad : constant Boolean := HaveKeyPad (curpw);
  199. do_scroll : constant Boolean := HaveScroll (curpw);
  200. pos : Natural;
  201. mypair : pair;
  202. use Ada.Strings.Fixed;
  203. begin
  204. Move_Cursor (Line => Lines - 4, Column => 0);
  205. for n in legend'Range loop
  206. pos := Ada.Strings.Fixed.Index (Source => legend (n).msg.all,
  207. Pattern => "%s");
  208. -- buf := (others => ' ');
  209. buf := To_Bounded_String (legend (n).msg.all);
  210. case legend (n).code is
  211. when 0 => null;
  212. when 1 =>
  213. if do_keypad then
  214. Replace_Slice (buf, pos, pos + 1, "yes");
  215. else
  216. Replace_Slice (buf, pos, pos + 1, "no");
  217. end if;
  218. when 2 =>
  219. if do_scroll then
  220. Replace_Slice (buf, pos, pos + 1, "yes");
  221. else
  222. Replace_Slice (buf, pos, pos + 1, "no");
  223. end if;
  224. when 3 =>
  225. if do_keypad then
  226. Replace_Slice (buf, pos, pos + 1, "/ESC");
  227. else
  228. Replace_Slice (buf, pos, pos + 1, "");
  229. end if;
  230. end case;
  231. Get_Cursor_Position (Line => mypair.y, Column => mypair.x);
  232. if Columns < mypair.x + 3 + Column_Position (Length (buf)) then
  233. Add (Ch => newl);
  234. elsif n /= 1 then -- n /= legen'First
  235. Add (Str => ", ");
  236. end if;
  237. myAdd (Str => buf);
  238. end loop;
  239. Clear_To_End_Of_Line;
  240. end newwin_legend;
  241. procedure transient (curpw : Window; msg : String) is
  242. begin
  243. newwin_legend (curpw);
  244. if msg /= "" then
  245. Add (Line => Lines - 1, Column => 0, Str => msg);
  246. Refresh;
  247. Nap_Milli_Seconds (1000);
  248. end if;
  249. Move_Cursor (Line => Lines - 1, Column => 0);
  250. if HaveKeyPad (curpw) then
  251. Add (Str => "Non-arrow");
  252. else
  253. Add (Str => "All other");
  254. end if;
  255. Add (str => " characters are echoed, window should ");
  256. if not HaveScroll (curpw) then
  257. Add (Str => "not ");
  258. end if;
  259. Add (str => "scroll");
  260. Clear_To_End_Of_Line;
  261. end transient;
  262. procedure newwin_report (win : Window := Standard_Window) is
  263. y : Line_Position;
  264. x : Column_Position;
  265. use Int_IO;
  266. tmp2a : String (1 .. 2);
  267. tmp2b : String (1 .. 2);
  268. begin
  269. if win /= Standard_Window then
  270. transient (win, "");
  271. end if;
  272. Get_Cursor_Position (win, y, x);
  273. Move_Cursor (Line => Lines - 1, Column => Columns - 17);
  274. Put (tmp2a, Integer (y));
  275. Put (tmp2b, Integer (x));
  276. Add (Str => "Y = " & tmp2a & " X = " & tmp2b);
  277. if win /= Standard_Window then
  278. Refresh;
  279. else
  280. Move_Cursor (win, y, x);
  281. end if;
  282. end newwin_report;
  283. procedure selectcell (uli : Line_Position;
  284. ulj : Column_Position;
  285. lri : Line_Position;
  286. lrj : Column_Position;
  287. p : out pair;
  288. b : out Boolean) is
  289. c : Key_Code;
  290. res : pair;
  291. i : Line_Position := 0;
  292. j : Column_Position := 0;
  293. si : constant Line_Position := lri - uli + 1;
  294. sj : constant Column_Position := lrj - ulj + 1;
  295. begin
  296. res.y := uli;
  297. res.x := ulj;
  298. loop
  299. Move_Cursor (Line => uli + i, Column => ulj + j);
  300. newwin_report;
  301. c := Getchar;
  302. case c is
  303. when
  304. Macro_Quit |
  305. Macro_Escape =>
  306. -- on the same line macro calls interfere due to the # comment
  307. -- this is needed because keypad off affects all windows.
  308. -- try removing the ESCAPE and see what happens.
  309. b := False;
  310. return;
  311. when KEY_UP =>
  312. i := i + si - 1;
  313. -- same as i := i - 1 because of Modulus arithetic,
  314. -- on Line_Position, which is a Natural
  315. -- the C version uses this form too, interestingly.
  316. when KEY_DOWN =>
  317. i := i + 1;
  318. when KEY_LEFT =>
  319. j := j + sj - 1;
  320. when KEY_RIGHT =>
  321. j := j + 1;
  322. when Key_Mouse =>
  323. declare
  324. event : Mouse_Event;
  325. y : Line_Position;
  326. x : Column_Position;
  327. Button : Mouse_Button;
  328. State : Button_State;
  329. begin
  330. event := Get_Mouse;
  331. Get_Event (Event => event,
  332. Y => y,
  333. X => x,
  334. Button => Button,
  335. State => State);
  336. if y > uli and x > ulj then
  337. i := y - uli;
  338. j := x - ulj;
  339. -- same as when others =>
  340. res.y := uli + i;
  341. res.x := ulj + j;
  342. p := res;
  343. b := True;
  344. return;
  345. else
  346. Beep;
  347. end if;
  348. end;
  349. when others =>
  350. res.y := uli + i;
  351. res.x := ulj + j;
  352. p := res;
  353. b := True;
  354. return;
  355. end case;
  356. i := i mod si;
  357. j := j mod sj;
  358. end loop;
  359. end selectcell;
  360. function getwindow return Window is
  361. rwindow : Window;
  362. ul, lr : pair;
  363. result : Boolean;
  364. begin
  365. Move_Cursor (Line => 0, Column => 0);
  366. Clear_To_End_Of_Line;
  367. Add (Str => "Use arrows to move cursor, anything else to mark corner 1");
  368. Refresh;
  369. selectcell (2, 1, Lines - Botlines - 2, Columns - 2, ul, result);
  370. if not result then
  371. return Null_Window;
  372. end if;
  373. Add (Line => ul.y - 1, Column => ul.x - 1,
  374. Ch => ACS_Map (ACS_Upper_Left_Corner));
  375. Move_Cursor (Line => 0, Column => 0);
  376. Clear_To_End_Of_Line;
  377. Add (Str => "Use arrows to move cursor, anything else to mark corner 2");
  378. Refresh;
  379. selectcell (ul.y, ul.x, Lines - Botlines - 2, Columns - 2, lr, result);
  380. if not result then
  381. return Null_Window;
  382. end if;
  383. rwindow := Sub_Window (Number_Of_Lines => lr.y - ul.y + 1,
  384. Number_Of_Columns => lr.x - ul.x + 1,
  385. First_Line_Position => ul.y,
  386. First_Column_Position => ul.x);
  387. Outerbox (ul, lr, True);
  388. Refresh;
  389. Refresh (rwindow);
  390. Move_Cursor (Line => 0, Column => 0);
  391. Clear_To_End_Of_Line;
  392. return rwindow;
  393. end getwindow;
  394. procedure newwin_move (win : Window;
  395. dy : Line_Position;
  396. dx : Column_Position) is
  397. cur_y, max_y : Line_Position;
  398. cur_x, max_x : Column_Position;
  399. begin
  400. Get_Cursor_Position (win, cur_y, cur_x);
  401. Get_Size (win, max_y, max_x);
  402. cur_x := Column_Position'Min (Column_Position'Max (cur_x + dx, 0),
  403. max_x - 1);
  404. cur_y := Line_Position'Min (Line_Position'Max (cur_y + dy, 0),
  405. max_y - 1);
  406. Move_Cursor (win, Line => cur_y, Column => cur_x);
  407. end newwin_move;
  408. function delete_framed (fp : FrameA; showit : Boolean) return FrameA is
  409. np : FrameA;
  410. begin
  411. fp.last.next := fp.next;
  412. fp.next.last := fp.last;
  413. if showit then
  414. Erase (fp.wind);
  415. Refresh (fp.wind);
  416. end if;
  417. Delete (fp.wind);
  418. if fp = fp.next then
  419. np := null;
  420. else
  421. np := fp.next;
  422. end if;
  423. -- TODO free(fp);
  424. return np;
  425. end delete_framed;
  426. Mask : Event_Mask := No_Events;
  427. Mask2 : Event_Mask;
  428. usescr : Window;
  429. begin
  430. if Has_Mouse then
  431. Register_Reportable_Event (
  432. Button => Left,
  433. State => Clicked,
  434. Mask => Mask);
  435. Mask2 := Start_Mouse (Mask);
  436. end if;
  437. c := CTRL ('C');
  438. Set_Raw_Mode (SwitchOn => True);
  439. loop
  440. transient (Standard_Window, "");
  441. case c is
  442. when Character'Pos ('c') mod 16#20# => -- Ctrl('c')
  443. declare
  444. neww : constant FrameA := new Frame'(null, null,
  445. False, False,
  446. Null_Window);
  447. begin
  448. neww.wind := getwindow;
  449. if neww.wind = Null_Window then
  450. exit;
  451. -- was goto breakout; ha ha ha
  452. else
  453. if current = null then
  454. neww.next := neww;
  455. neww.last := neww;
  456. else
  457. neww.next := current.next;
  458. neww.last := current;
  459. neww.last.next := neww;
  460. neww.next.last := neww;
  461. end if;
  462. current := neww;
  463. Set_KeyPad_Mode (current.wind, True);
  464. current.do_keypad := HaveKeyPad (current.wind);
  465. current.do_scroll := HaveScroll (current.wind);
  466. end if;
  467. end;
  468. when Character'Pos ('N') mod 16#20# => -- Ctrl('N')
  469. if current /= null then
  470. current := current.next;
  471. end if;
  472. when Character'Pos ('P') mod 16#20# => -- Ctrl('P')
  473. if current /= null then
  474. current := current.last;
  475. end if;
  476. when Character'Pos ('F') mod 16#20# => -- Ctrl('F')
  477. if current /= null and then HaveScroll (current.wind) then
  478. Scroll (current.wind, 1);
  479. end if;
  480. when Character'Pos ('B') mod 16#20# => -- Ctrl('B')
  481. if current /= null and then HaveScroll (current.wind) then
  482. -- The C version of Scroll may return ERR which is ignored
  483. -- we need to avoid the exception
  484. -- with the 'and HaveScroll(current.wind)'
  485. Scroll (current.wind, -1);
  486. end if;
  487. when Character'Pos ('K') mod 16#20# => -- Ctrl('K')
  488. if current /= null then
  489. current.do_keypad := not current.do_keypad;
  490. Set_KeyPad_Mode (current.wind, current.do_keypad);
  491. end if;
  492. when Character'Pos ('S') mod 16#20# => -- Ctrl('S')
  493. if current /= null then
  494. current.do_scroll := not current.do_scroll;
  495. Allow_Scrolling (current.wind, current.do_scroll);
  496. end if;
  497. when Character'Pos ('W') mod 16#20# => -- Ctrl('W')
  498. if current /= current.next then
  499. Create (f, Name => dumpfile); -- TODO error checking
  500. if not Is_Open (f) then
  501. raise Curses_Exception;
  502. end if;
  503. Put_Window (current.wind, f);
  504. Close (f);
  505. current := delete_framed (current, True);
  506. end if;
  507. when Character'Pos ('R') mod 16#20# => -- Ctrl('R')
  508. declare
  509. neww : FrameA := new Frame'(null, null, False, False,
  510. Null_Window);
  511. begin
  512. Open (f, Mode => In_File, Name => dumpfile);
  513. neww := new Frame'(null, null, False, False, Null_Window);
  514. neww.next := current.next;
  515. neww.last := current;
  516. neww.last.next := neww;
  517. neww.next.last := neww;
  518. neww.wind := Get_Window (f);
  519. Close (f);
  520. Refresh (neww.wind);
  521. end;
  522. when Character'Pos ('X') mod 16#20# => -- Ctrl('X')
  523. if current /= null then
  524. declare
  525. tmp, ul, lr : pair;
  526. mx : Column_Position;
  527. my : Line_Position;
  528. tmpbool : Boolean;
  529. begin
  530. Move_Cursor (Line => 0, Column => 0);
  531. Clear_To_End_Of_Line;
  532. Add (Str => "Use arrows to move cursor, anything else " &
  533. "to mark new corner");
  534. Refresh;
  535. Get_Window_Position (current.wind, ul.y, ul.x);
  536. selectcell (ul.y, ul.x, Lines - Botlines - 2, Columns - 2,
  537. tmp, tmpbool);
  538. if not tmpbool then
  539. -- the C version had a goto. I refuse gotos.
  540. Beep;
  541. else
  542. Get_Size (current.wind, lr.y, lr.x);
  543. lr.y := lr.y + ul.y - 1;
  544. lr.x := lr.x + ul.x - 1;
  545. Outerbox (ul, lr, False);
  546. Refresh_Without_Update;
  547. Get_Size (current.wind, my, mx);
  548. if my > tmp.y - ul.y then
  549. Get_Cursor_Position (current.wind, lr.y, lr.x);
  550. Move_Cursor (current.wind, tmp.y - ul.y + 1, 0);
  551. Clear_To_End_Of_Screen (current.wind);
  552. Move_Cursor (current.wind, lr.y, lr.x);
  553. end if;
  554. if mx > tmp.x - ul.x then
  555. for i in 0 .. my - 1 loop
  556. Move_Cursor (current.wind, i, tmp.x - ul.x + 1);
  557. Clear_To_End_Of_Line (current.wind);
  558. end loop;
  559. end if;
  560. Refresh_Without_Update (current.wind);
  561. lr := tmp;
  562. -- The C version passes invalid args to resize
  563. -- which returns an ERR. For Ada we avoid the exception.
  564. if lr.y /= ul.y and lr.x /= ul.x then
  565. Resize (current.wind, lr.y - ul.y + 0,
  566. lr.x - ul.x + 0);
  567. end if;
  568. Get_Window_Position (current.wind, ul.y, ul.x);
  569. Get_Size (current.wind, lr.y, lr.x);
  570. lr.y := lr.y + ul.y - 1;
  571. lr.x := lr.x + ul.x - 1;
  572. Outerbox (ul, lr, True);
  573. Refresh_Without_Update;
  574. Refresh_Without_Update (current.wind);
  575. Move_Cursor (Line => 0, Column => 0);
  576. Clear_To_End_Of_Line;
  577. Update_Screen;
  578. end if;
  579. end;
  580. end if;
  581. when Key_F10 =>
  582. declare tmp : pair; tmpbool : Boolean;
  583. begin
  584. -- undocumented --- use this to test area clears
  585. selectcell (0, 0, Lines - 1, Columns - 1, tmp, tmpbool);
  586. Clear_To_End_Of_Screen;
  587. Refresh;
  588. end;
  589. when Key_Cursor_Up =>
  590. newwin_move (current.wind, -1, 0);
  591. when Key_Cursor_Down =>
  592. newwin_move (current.wind, 1, 0);
  593. when Key_Cursor_Left =>
  594. newwin_move (current.wind, 0, -1);
  595. when Key_Cursor_Right =>
  596. newwin_move (current.wind, 0, 1);
  597. when Key_Backspace | Key_Delete_Char =>
  598. declare
  599. y : Line_Position;
  600. x : Column_Position;
  601. tmp : Line_Position;
  602. begin
  603. Get_Cursor_Position (current.wind, y, x);
  604. -- x := x - 1;
  605. -- I got tricked by the -1 = Max_Natural - 1 result
  606. -- y := y - 1;
  607. if not (x = 0 and y = 0) then
  608. if x = 0 then
  609. y := y - 1;
  610. Get_Size (current.wind, tmp, x);
  611. end if;
  612. x := x - 1;
  613. Delete_Character (current.wind, y, x);
  614. end if;
  615. end;
  616. when others =>
  617. -- TODO c = '\r' ?
  618. if current /= null then
  619. declare
  620. begin
  621. Add (current.wind, Ch => Code_To_Char (c));
  622. exception
  623. when Curses_Exception => null;
  624. -- this happens if we are at the
  625. -- lower right of a window and add a character.
  626. end;
  627. else
  628. Beep;
  629. end if;
  630. end case;
  631. newwin_report (current.wind);
  632. if current /= null then
  633. usescr := current.wind;
  634. else
  635. usescr := Standard_Window;
  636. end if;
  637. Refresh (usescr);
  638. c := Getchar (usescr);
  639. exit when c = Quit or (c = Escape and HaveKeyPad (usescr));
  640. -- TODO when does c = ERR happen?
  641. end loop;
  642. -- TODO while current /= null loop
  643. -- current := delete_framed(current, False);
  644. -- end loop;
  645. Allow_Scrolling (Mode => True);
  646. End_Mouse (Mask2);
  647. Set_Raw_Mode (SwitchOn => True);
  648. Erase;
  649. End_Windows;
  650. end ncurses2.acs_and_scroll;