ecuwinutil.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*+-------------------------------------------------------------------------
  2. ecuwinutil.c - curses window utilities
  3. wht@wht.net
  4. Defined functions:
  5. clear_area(win, y, x, len)
  6. clear_area_char(win, y, x, len, fillchar)
  7. winbox(win)
  8. window_create(title, title_x, tly, tlx, lines, cols)
  9. window_setup(win, title, title_x)
  10. windows_end(botleft_flag)
  11. windows_end_signal()
  12. windows_start()
  13. winget_single(win, nondelim_list, delim_list)
  14. wingets(win, y, x, buf, bufsize, delim, edit, pwgpos)
  15. It's hard to get ivory in Africa, but in Alabama the
  16. Tuscaloosa. -- Groucho
  17. --------------------------------------------------------------------------*/
  18. /*+:EDITS:*/
  19. /*:04-26-2000-11:15-wht@bob-RELEASE 4.42 */
  20. /*:05-12-1997-17:38-wht@kepler-xclnt intl port still screwed winget_single */
  21. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  22. /*:09-11-1996-20:00-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  23. /*:09-07-1996-16:18-wht@kepler-CFG_UseACS coined for use outside of config */
  24. /*:09-05-1996-17:33-wht@kepler-try retiring use of typeahead(-1) */
  25. /*:08-22-1996-14:13-wht@fep-decommitted AT chars + fix SVR4 */
  26. /*:12-06-1995-13:30-wht@n4hgf-termecu w/errno -1 consideration */
  27. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  28. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  29. /*:03-12-1995-01:29-wht@kepler-Linux winbox was inaccurate */
  30. /*:01-15-1995-01:52-wht@n4hgf-clean up creeping port rot */
  31. /*:01-12-1995-15:19-wht@n4hgf-apply Andrew Chernov 8-bit clean+FreeBSD patch */
  32. /*:05-17-1994-20:49-wht@n4hgf-winget_single ichar now unsigned char */
  33. /*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  34. /*:11-12-1993-11:00-wht@n4hgf-Linux changes by bob@vancouver.zadall.com */
  35. /*:09-15-1993-11:31-wht@n4hgf-endwin on non-SCO per bob@vancouver.zadall.com */
  36. /*:08-17-1993-14:04-wht@n4hgf-add OLD_WINGETS for compatibility */
  37. /*:08-13-1993-04:04-wht@n4hgf-add highlight_delete function to wingets */
  38. /*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  39. /*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  40. /*:02-09-1992-16:08-root@n4hgf-ruling characters only on SCO (tcap curses) */
  41. /*:08-25-1991-14:39-wht@n4hgf-SVR4 port thanks to aega84!lh */
  42. /*:08-01-1991-03:52-wht@n4hgf-when editing string, set cursor to end */
  43. /*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
  44. /*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  45. #include "ecucurses.h"
  46. #include <errno.h>
  47. #include <ctype.h>
  48. #include "ecukey.h"
  49. #include "ecuxkey.h"
  50. #include "termecu.h"
  51. #include "pc_scr.h"
  52. #if !defined(UINT16)
  53. #define UINT16 unsigned short
  54. #endif
  55. #if !defined(uchar)
  56. #define uchar unsigned char
  57. #endif
  58. #if !defined(UINT)
  59. #define UINT unsigned int
  60. #endif
  61. #if !defined(UINT32)
  62. #define UINT32 unsigned long
  63. #endif
  64. extern int tty_is_multiscreen;
  65. WINCH sTL;
  66. WINCH sTR;
  67. WINCH sBL;
  68. WINCH sBR;
  69. WINCH sLT;
  70. WINCH sRT;
  71. WINCH sVR;
  72. WINCH sHR;
  73. int windows_active = 0;
  74. int ttymode_before_window_start;
  75. /*+-------------------------------------------------------------------------
  76. clear_area_char(win,y,x,len,fillchar)
  77. --------------------------------------------------------------------------*/
  78. void
  79. clear_area_char(win, y, x, len, fillchar)
  80. WINDOW *win;
  81. int y;
  82. int x;
  83. int len;
  84. char fillchar;
  85. {
  86. wmove(win, y, x);
  87. #if 0
  88. wprintw(win, "%02x %d,%d,%d", fillchar, y, x, len);
  89. #endif
  90. while (len-- > 0)
  91. waddch(win, fillchar);
  92. wmove(win, y, x);
  93. } /* end of clear_area_char */
  94. /*+-------------------------------------------------------------------------
  95. clear_area(win,y,x,len)
  96. --------------------------------------------------------------------------*/
  97. void
  98. clear_area(win, y, x, len)
  99. WINDOW *win;
  100. int y;
  101. int x;
  102. int len;
  103. {
  104. clear_area_char(win, y, x, len, ' ');
  105. } /* end of clear_area_char */
  106. /*+-------------------------------------------------------------------------
  107. windows_start()
  108. --------------------------------------------------------------------------*/
  109. void
  110. windows_start()
  111. {
  112. extern int tty_not_char_special;
  113. static int initscr_already_performed = 0;
  114. if (tty_not_char_special)
  115. {
  116. fprintf(stderr, "curses features unavailable when stdin not tty\r\n");
  117. errno = -1;
  118. termecu(TERMECU_CURSES_ERROR);
  119. }
  120. ttymode_before_window_start = get_ttymode();
  121. ttymode(0);
  122. if (!initscr_already_performed && !initscr())
  123. {
  124. fprintf(stderr, "curses init failure ... check terminal type\r\n");
  125. errno = -1;
  126. termecu(TERMECU_CURSES_ERROR);
  127. }
  128. initscr_already_performed = 1;
  129. scrollok(stdscr, 0);
  130. savetty();
  131. raw();
  132. noecho();
  133. nonl();
  134. clear();
  135. windows_active = 1;
  136. #if defined(CFG_UseACS)
  137. sTL = ACS_ULCORNER;
  138. sTR = ACS_URCORNER;
  139. sBL = ACS_LLCORNER;
  140. sBR = ACS_LRCORNER;
  141. sLT = ACS_LTEE;
  142. sRT = ACS_RTEE;
  143. sVR = ACS_VLINE;
  144. sHR = ACS_HLINE;
  145. if ((sTL < 127) && strchr("+-|", (uchar) sTL))
  146. sTL = '.';
  147. if ((sTR < 127) && strchr("+-|", (uchar) sTR))
  148. sTR = '.';
  149. if ((sBR < 127) && strchr("+-|", (uchar) sBR))
  150. sBL = '`';
  151. if ((sBR < 127) && strchr("+-|", (uchar) sBR))
  152. sBR = '\'';
  153. #else
  154. sTL = vanilla_TL;
  155. sTR = vanilla_TR;
  156. sBL = vanilla_BL;
  157. sBR = vanilla_BR;
  158. sLT = vanilla_LT;
  159. sRT = vanilla_RT;
  160. sVR = vanilla_VR;
  161. sHR = vanilla_HR;
  162. #endif /* defined(CFG_UseACS) */
  163. wclear(stdscr);
  164. touchwin(stdscr);
  165. wrefresh(stdscr);
  166. } /* end of windows_start */
  167. /*+-------------------------------------------------------------------------
  168. windows_end(botleft_flag)
  169. --------------------------------------------------------------------------*/
  170. void
  171. windows_end(botleft_flag)
  172. int botleft_flag;
  173. {
  174. if (!windows_active)
  175. return;
  176. #if !defined(M_UNIX) && !defined(M_XENIX) && !defined(SCO32v5)
  177. endwin();
  178. #else
  179. refresh();
  180. #endif
  181. if (botleft_flag)
  182. tcap_cursor(LINES - 1, 0);
  183. ttymode(ttymode_before_window_start);
  184. windows_active = 0;
  185. } /* end of windows_end */
  186. /*+-------------------------------------------------------------------------
  187. windows_end_signal() -- called by termecu()
  188. --------------------------------------------------------------------------*/
  189. void
  190. windows_end_signal()
  191. {
  192. windows_end(0);
  193. } /* end of windows_end_signal */
  194. /*+-------------------------------------------------------------------------
  195. winbox(win)
  196. --------------------------------------------------------------------------*/
  197. void
  198. winbox(win)
  199. WINDOW *win;
  200. {
  201. #ifdef __FreeBSD__ /* ache */
  202. box(win, sVR, sHR);
  203. #else
  204. #if defined(linux) || defined(SVR4) /* wht */
  205. int x, y;
  206. box(win, sVR, sHR);
  207. getmaxyx(win, y, x);
  208. wmove(win, 0, 0);
  209. waddch(win, sTL);
  210. wmove(win, y - 1, 0);
  211. waddch(win, sBL);
  212. wmove(win, y - 1, x - 1);
  213. waddch(win, sBR);
  214. wmove(win, 0, x - 1);
  215. waddch(win, sTR);
  216. #else
  217. /*
  218. * default is not very portable, but has survived well ... too bad
  219. * getmaxyx() is not standard
  220. */
  221. box(win, sVR, sHR);
  222. wmove(win, 0, 0);
  223. waddch(win, sTL);
  224. wmove(win, win->_maxy - 1, 0);
  225. waddch(win, sBL);
  226. wmove(win, win->_maxy - 1, win->_maxx - 1);
  227. waddch(win, sBR);
  228. wmove(win, 0, win->_maxx - 1);
  229. waddch(win, sTR);
  230. #endif
  231. #endif
  232. } /* end of winbox */
  233. /*+-------------------------------------------------------------------------
  234. window_setup(win,title,title_x)
  235. --------------------------------------------------------------------------*/
  236. void
  237. window_setup(win, title, title_x)
  238. WINDOW *win;
  239. char *title;
  240. int title_x;
  241. {
  242. int stand = (title_x < 0);
  243. if (stand)
  244. title_x = -title_x;
  245. touchwin(win);
  246. scrollok(win, 0); /* do not scroll */
  247. winbox(win);
  248. wmove(win, 0, title_x);
  249. if (stand)
  250. wstandout(win);
  251. waddch(win, '[');
  252. wprintw(win, " %s ", title);
  253. waddch(win, ']');
  254. if (stand)
  255. wstandend(win);
  256. } /* end of window_setup */
  257. /*+-------------------------------------------------------------------------
  258. window_create(title,title_x,tly,tlx,lines,cols)
  259. if title_x negative, make title "stand" out
  260. --------------------------------------------------------------------------*/
  261. WINDOW *
  262. window_create(title, title_x, tly, tlx, lines, cols)
  263. char *title;
  264. int title_x;
  265. int tly;
  266. int tlx;
  267. int lines;
  268. int cols;
  269. {
  270. WINDOW *nwin = newwin(lines, cols, tly, tlx);
  271. errno = -1;
  272. if (nwin)
  273. window_setup(nwin, title, title_x);
  274. else
  275. {
  276. fprintf(stderr, "\r\ncurses error: cannot create new window\r\n");
  277. termecu(TERMECU_CURSES_ERROR);
  278. }
  279. return (nwin);
  280. } /* end of window_create */
  281. /*+-------------------------------------------------------------------------
  282. wingets(win,y,x,buf,bufsize,delim,edit,pwgpos)
  283. This procedure reads a string from win and returns the number
  284. of characters read.
  285. If edit is non-zero and pwgpos is not null, the inital string
  286. position is set by dereferencing the pointer.
  287. The terminating delim is returned in 'delim'.
  288. If pwgpos is not null, the ending string position is returned in
  289. the integer pointed to.
  290. -1 is returned if an ESCape is typed by the keyboard user,
  291. otherwise the count of characters in the string.
  292. The entire line must be contained on one line (no line wrap supported).
  293. --------------------------------------------------------------------------*/
  294. int
  295. wingets(win, y, x, buf, bufsize, delim, edit, pwgpos)
  296. WINDOW *win;
  297. int y;
  298. int x;
  299. char *buf;
  300. int bufsize; /* includes room for null..field is 1 less */
  301. UINT *delim;
  302. int edit;
  303. int *pwgpos;
  304. {
  305. int count = 0;
  306. int pos = 0;
  307. int insert_mode = 0;
  308. #ifndef OLD_WINGETS
  309. int highlight_delete = 0;
  310. #endif
  311. int rtn_val = 0;
  312. bufsize--;
  313. if (edit && strlen(buf))
  314. {
  315. #ifndef OLD_WINGETS
  316. highlight_delete = 1;
  317. #endif
  318. clear_area_char(win, y, x, bufsize, ' ');
  319. wstandout(win);
  320. waddstr(win, buf);
  321. wstandend(win);
  322. count = pos = strlen(buf);
  323. if (pwgpos)
  324. {
  325. pos = *pwgpos;
  326. if ((pos < 0) || (pos > count))
  327. pos = count;
  328. }
  329. }
  330. else
  331. {
  332. clear_area_char(win, y, x, bufsize, '_');
  333. *buf = 0;
  334. }
  335. wmove(win, y, x + pos);
  336. while (1)
  337. {
  338. wrefresh(win);
  339. *delim = ttygetc(1);
  340. if (*delim > 0xFF || !isprint(*delim))
  341. {
  342. #ifndef OLD_WINGETS
  343. if (highlight_delete)
  344. {
  345. clear_area_char(win, y, x, bufsize, '_');
  346. waddstr(win, buf);
  347. wmove(win, y, x + pos);
  348. highlight_delete = 0;
  349. }
  350. #endif
  351. switch (*delim)
  352. {
  353. case CRET:
  354. *delim = NL;
  355. case NL:
  356. wrefresh(win);
  357. rtn_val = count;
  358. goto FUNC_RETURN;
  359. case BS:
  360. case DEL:
  361. if (count)
  362. {
  363. if (count == pos)
  364. {
  365. *(buf + --count) = 0;
  366. wmove(win, y, x + count);
  367. waddch(win, '_');
  368. wmove(win, y, x + count);
  369. pos--;
  370. }
  371. else
  372. {
  373. if (!pos)
  374. continue;
  375. mem_cpy(buf + pos - 1, buf + pos, count - pos);
  376. *(buf + --count) = 0;
  377. wmove(win, y, x + --pos);
  378. waddstr(win, buf + pos);
  379. waddch(win, '_');
  380. wmove(win, y, x + pos);
  381. }
  382. }
  383. continue;
  384. case XFcurlf:
  385. if (pos)
  386. wmove(win, y, x + --pos);
  387. continue;
  388. case XFcurrt:
  389. if (pos < count)
  390. wmove(win, y, x + ++pos);
  391. continue;
  392. case XFins:
  393. insert_mode = !insert_mode;
  394. continue;
  395. case ESC:
  396. rtn_val = -1;
  397. goto FUNC_RETURN;
  398. case CTL_U:
  399. clear_area_char(win, y, x, bufsize, '_');
  400. count = 0;
  401. pos = 0;
  402. *buf = 0;
  403. continue;
  404. default:
  405. *(buf + count) = 0;
  406. rtn_val = count;
  407. goto FUNC_RETURN;
  408. } /* end of switch(*delim) */
  409. /* NOTREACHED */
  410. } /* end of if read delimiter */
  411. #ifndef OLD_WINGETS
  412. if (highlight_delete)
  413. {
  414. clear_area_char(win, y, x, bufsize, '_');
  415. count = 0;
  416. pos = 0;
  417. highlight_delete = 0;
  418. }
  419. #endif
  420. if (count == bufsize)
  421. {
  422. ring_bell();
  423. continue;
  424. }
  425. if (insert_mode && (pos != count))
  426. {
  427. waddch(win, *delim);
  428. waddstr(win, buf + pos);
  429. mem_cpy(buf + pos + 1, buf + pos, count - pos);
  430. *(buf + pos++) = *delim;
  431. *(buf + ++count) = 0;
  432. wmove(win, y, x + pos);
  433. }
  434. else
  435. {
  436. waddch(win, *delim);
  437. *(buf + pos) = *delim;
  438. if (pos == count)
  439. *(buf + ++count) = 0;
  440. pos++;
  441. }
  442. } /* end of while can get character */
  443. FUNC_RETURN:
  444. if (pwgpos)
  445. *pwgpos = pos;
  446. return (rtn_val);
  447. } /* end of wingets */
  448. /*+-------------------------------------------------------------------------
  449. winget_single(win,nondelim_list,delim_list)
  450. This procedure assumes cursor is positioned, repeats reading a non-echoing
  451. character from the keyboard until it matches a character in nondelim_list
  452. or delim_list. delim_list is expected to contain printable characters
  453. and no upper-case characters.
  454. If no match occurs, the bell is rung and the keyboard is read again.
  455. If the input character matches a character in delim_list, the index (0-n)
  456. of the character in delim_list is returned. If a match occurs, an
  457. upper-case version of the matching character is placed in the window.
  458. If the input character matches a character in nondelim_list, the character
  459. is returned or'ed with 0x1000
  460. --------------------------------------------------------------------------*/
  461. int
  462. winget_single(win, nondelim_list, delim_list)
  463. WINDOW *win;
  464. UINT *nondelim_list;
  465. UINT *delim_list;
  466. {
  467. int itmp;
  468. UINT ichar;
  469. wrefresh(win);
  470. while (1)
  471. {
  472. ichar = ttygetc(1);
  473. for (itmp = 0; delim_list[itmp]; itmp++)
  474. {
  475. if (ichar == delim_list[itmp])
  476. return (ichar | 0x1000);
  477. }
  478. ichar = to_lower(ichar);
  479. for (itmp = 0; nondelim_list[itmp]; itmp++)
  480. {
  481. if (ichar == nondelim_list[itmp])
  482. {
  483. if (ichar <= 0xFF && isprint(ichar))
  484. waddch(win, to_upper(ichar));
  485. wrefresh(win);
  486. return (itmp);
  487. }
  488. }
  489. ring_bell();
  490. }
  491. } /* end of winget_single */
  492. /* end of ecuwinutil.c */
  493. /* vi: set tabstop=4 shiftwidth=4: */