1/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.screen.c,v 1.14 2006/03/14 01:22:57 mitr Exp $*/ 2/* 3 * ed.screen.c: Editor/termcap-curses interface 4 */ 5/*- 6 * Copyright (c) 1980, 1991 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33#include "sh.h" 34 35 36#include "ed.h" 37#include "tc.h" 38#include "ed.defns.h" 39 40 41/* #define DEBUG_LITERAL */ 42 43/* 44 * IMPORTANT NOTE: these routines are allowed to look at the current screen 45 * and the current possition assuming that it is correct. If this is not 46 * true, then the update will be WRONG! This is (should be) a valid 47 * assumption... 48 */ 49 50 51 52extern int nt_getsize(int*,int*,int*); 53extern int nt_ClearEOL( void) ; 54extern void NT_ClearEOD( void) ; 55extern void NT_ClearScreen(void) ; 56extern void NT_VisibleBell(void); 57extern void NT_WrapHorizontal(void); 58 59static int GetSize(int *lins, int *cols); 60 61int DisplayWindowHSize; 62 void 63terminit(void) 64{ 65 return; 66} 67 68 69 70int T_ActualWindowSize; 71 72static void ReBufferDisplay (void); 73 74 75/*ARGSUSED*/ 76 void 77TellTC(void) 78{ 79 80 xprintf(CGETS(7, 1, "\n\tYou're using a Windows console.\n")); 81} 82 83 84 static void 85ReBufferDisplay(void) 86{ 87 register int i; 88 Char **b; 89 Char **bufp; 90 int lins,cols; 91 92 nt_getsize(&lins,&cols,&DisplayWindowHSize); 93 94 b = Display; 95 Display = NULL; 96 if (b != NULL) { 97 for (bufp = b; *bufp != NULL; bufp++) 98 xfree((ptr_t) * bufp); 99 xfree((ptr_t) b); 100 } 101 b = Vdisplay; 102 Vdisplay = NULL; 103 if (b != NULL) { 104 for (bufp = b; *bufp != NULL; bufp++) 105 xfree((ptr_t) * bufp); 106 xfree((ptr_t) b); 107 } 108 TermH = cols; 109 110 TermV = (INBUFSIZE * 4) / TermH + 1;/*FIXBUF*/ 111 b = (Char **) xmalloc((size_t) (sizeof(*b) * (TermV + 1))); 112 for (i = 0; i < TermV; i++) 113 b[i] = (Char *) xmalloc((size_t) (sizeof(*b[i]) * (TermH + 1))); 114 b[TermV] = NULL; 115 Display = b; 116 b = (Char **) xmalloc((size_t) (sizeof(*b) * (TermV + 1))); 117 for (i = 0; i < TermV; i++) 118 b[i] = (Char *) xmalloc((size_t) (sizeof(*b[i]) * (TermH + 1))); 119 b[TermV] = NULL; 120 Vdisplay = b; 121} 122 123 void 124SetTC(char *what, char *how) 125{ 126 int li,win,co; 127 128 nt_getsize(&li,&co,&win); 129 if (!lstrcmp(what,"li")) { 130 li = atoi(how); 131 132 }else if(!lstrcmp(what,"co")) { //set window, not buffer size 133 win = atoi(how); 134 } 135 else 136 stderror(ERR_SYSTEM, "SetTC","Sorry, this function is not supported"); 137 138 ChangeSize(li,win); 139 return; 140} 141 142 143/* 144 * Print the termcap string out with variable substitution 145 */ 146 void 147EchoTC(Char **v) 148{ 149 Char **globbed; 150 char cv[BUFSIZE];/*FIXBUF*/ 151 int verbose = 0, silent = 0; 152 static char *fmts = "%s\n", *fmtd = "%d\n"; 153 int li,co; 154 155 156 setname("echotc"); 157 158 v = glob_all_or_error(v); 159 globbed = v; 160 cleanup_push(globbed, blk_cleanup); 161 162 if (!v || !*v || *v[0] == '\0') 163 goto end; 164 if (v[0][0] == '-') { 165 switch (v[0][1]) { 166 case 'v': 167 verbose = 1; 168 break; 169 case 's': 170 silent = 1; 171 break; 172 default: 173 stderror(ERR_NAME | ERR_TCUSAGE); 174 break; 175 } 176 v++; 177 } 178 if (!*v || *v[0] == '\0') 179 goto end; 180 (void) StringCbCopy(cv,sizeof(cv), short2str(*v)); 181 182 GetSize(&li,&co); 183 184 if(!lstrcmp(cv,"rows") || !lstrcmp(cv,"lines") ) { 185 xprintf(fmtd,T_Lines); 186 goto end; 187 } 188 else if(!lstrcmp(cv,"cols") ) { 189 xprintf(fmtd,T_ActualWindowSize); 190 goto end; 191 } 192 else if(!lstrcmp(cv,"buffer") ) { 193 xprintf(fmtd,T_Cols); 194 goto end; 195 } 196 else 197 stderror(ERR_SYSTEM, "EchoTC","Sorry, this function is not supported"); 198 199end: 200 cleanup_until(globbed); 201} 202 203int GotTermCaps = 0; 204 205 206 void 207ResetArrowKeys(void) 208{ 209} 210 211 void 212DefaultArrowKeys(void) 213{ 214} 215 216 217 int 218SetArrowKeys(const CStr *name, XmapVal *fun, int type) 219{ 220 UNREFERENCED_PARAMETER(name); 221 UNREFERENCED_PARAMETER(fun); 222 UNREFERENCED_PARAMETER(type); 223 return -1; 224} 225 226 int 227IsArrowKey(Char *name) 228{ 229 UNREFERENCED_PARAMETER(name); 230 return 0; 231} 232 233 int 234ClearArrowKeys(const CStr *name) 235{ 236 UNREFERENCED_PARAMETER(name); 237 return -1; 238} 239 240 void 241PrintArrowKeys(const CStr *name) 242{ 243 UNREFERENCED_PARAMETER(name); 244 return; 245} 246 247 248 void 249BindArrowKeys(void) 250{ 251 return; 252} 253 254#define GoodStr(ignore) 1 255 void 256SetAttributes(Char atr) 257{ 258 atr &= ATTRIBUTES; 259} 260 261/* PWP 6-27-88 -- if the tty driver thinks that we can tab, we ask termcap */ 262 int 263CanWeTab(void) 264{ 265 return 1; 266} 267 268/* move to line <where> (first line == 0) as efficiently as possible; */ 269 void 270MoveToLine(int where) 271{ 272 int del; 273 274 if (where == CursorV) 275 return; 276 277 if (where > TermV) { 278#ifdef DEBUG_SCREEN 279 xprintf("MoveToLine: where is ridiculous: %d\r\n", where); 280 flush(); 281#endif /* DEBUG_SCREEN */ 282 return; 283 } 284 285 del = where - CursorV; 286 287 NT_MoveToLineOrChar(del, 1); 288 289 CursorV = where; /* now where is here */ 290} 291 292/* move to character position (where) as efficiently as possible */ 293 void 294MoveToChar(int where) 295{ 296 if (where == CursorH) 297 return; 298 299 if (where >= TermH) { 300#ifdef DEBUG_SCREEN 301 xprintf("MoveToChar: where is riduculous: %d\r\n", where); 302 flush(); 303#endif /* DEBUG_SCREEN */ 304 return; 305 } 306 307 if (!where) { /* if where is first column */ 308 //(void) putraw('\r'); /* do a CR */ 309 NT_MoveToLineOrChar(where, 0); 310 flush(); 311 CursorH = 0; 312 return; 313 } 314 315 NT_MoveToLineOrChar(where, 0); 316 CursorH = where; /* now where is here */ 317} 318 319 void 320so_write(register Char *cp, register int n) 321{ 322 if (n <= 0) 323 return; /* catch bugs */ 324 325 if (n > TermH) { 326 return; 327 } 328 329 do { 330 if (*cp & LITERAL) { 331 Char *d; 332 333 for (d = litptr + (*cp++ & ~LITERAL) * LIT_FACTOR; *d; 334 d++) 335 (void) putraw(*d); 336 } 337 else 338 (void) putraw(*cp++); 339 CursorH++; 340 } while (--n); 341 342 if (CursorH >= TermH) { /* wrap? */ 343 CursorH = 0; 344 CursorV++; 345 NT_WrapHorizontal(); 346 347 } 348 else if(CursorH >= DisplayWindowHSize) { 349 flush(); 350 NT_MoveToLineOrChar(CursorH,0); 351 } 352} 353 354 355 void 356DeleteChars(int num) /* deletes <num> characters */ 357{ 358 if (num <= 0) 359 return; 360 361 if (!T_CanDel) { 362#ifdef DEBUG_EDIT 363 xprintf(CGETS(7, 16, "ERROR: cannot delete\r\n")); 364#endif /* DEBUG_EDIT */ 365 flush(); 366 return; 367 } 368 369 if (num > TermH) { 370#ifdef DEBUG_SCREEN 371 xprintf(CGETS(7, 17, "DeletChars: num is riduculous: %d\r\n"), num); 372 flush(); 373#endif /* DEBUG_SCREEN */ 374 return; 375 } 376 377} 378 379/* Puts terminal in insert character mode, or inserts num characters in the 380 line */ 381 void 382Insert_write(register Char *cp, register int num) 383{ 384 UNREFERENCED_PARAMETER(cp); 385 386 if (num <= 0) 387 return; 388 if (!T_CanIns) { 389#ifdef DEBUG_EDIT 390 xprintf(CGETS(7, 18, "ERROR: cannot insert\r\n")); 391#endif /* DEBUG_EDIT */ 392 flush(); 393 return; 394 } 395 396 if (num > TermH) { 397#ifdef DEBUG_SCREEN 398 xprintf(CGETS(7, 19, "StartInsert: num is riduculous: %d\r\n"), num); 399 flush(); 400#endif /* DEBUG_SCREEN */ 401 return; 402 } 403 404 405} 406 407/* clear to end of line. There are num characters to clear */ 408 void 409ClearEOL(int num) 410{ 411 412 if (num <= 0) 413 return; 414 415 nt_ClearEOL(); 416 417} 418 419 void 420ClearScreen(void) 421{ /* clear the whole screen and home */ 422 423 NT_ClearScreen(); 424 425} 426 427 void 428SoundBeep(void) 429{ /* produce a sound */ 430 beep_cmd (); 431 if (adrof(STRnobeep)) 432 return; 433 434 if (adrof(STRvisiblebell)) 435 NT_VisibleBell(); /* visible bell */ 436 else 437 MessageBeep(MB_ICONQUESTION); 438} 439 440 void 441ClearToBottom(void) 442{ /* clear to the bottom of the screen */ 443 NT_ClearEOD(); 444 445} 446 447 void 448GetTermCaps(void) 449{ 450 int lins,cols; 451 452 nt_getsize(&lins,&cols,&DisplayWindowHSize); 453 454 GotTermCaps = 1; 455 456 T_Cols = cols; 457 T_Lines = lins; 458 T_ActualWindowSize = DisplayWindowHSize; 459 T_Margin = MARGIN_AUTO; 460 T_CanCEOL = 1; 461 T_CanDel = 0; 462 T_CanIns = 0; 463 T_CanUP = 1; 464 465 ReBufferDisplay(); 466 ClearDisp(); 467 468 return; 469} 470/* GetSize(): 471 * Return the new window size in lines and cols, and 472 * true if the size was changed. 473 */ 474 int 475GetSize(int *lins, int *cols) 476{ 477 478 int ret = 0; 479 480 *lins = T_Lines; 481 482 *cols = T_Cols; 483 484 nt_getsize(lins,cols,&DisplayWindowHSize); 485 486 // compare the actual visible window size,but return the console buffer size 487 // this is seriously demented. 488 ret = (T_Lines != *lins || T_ActualWindowSize != DisplayWindowHSize); 489 490 T_Lines = *lins; 491 T_Cols = *cols; 492 T_ActualWindowSize = DisplayWindowHSize; 493 494 return ret; 495} 496 void 497ChangeSize(int lins, int cols) 498{ 499 500 int rc = 0; 501 // here we're setting the window size, not the buffer size. 502 // 503 nt_set_size(lins,cols); 504 505 rc = GetSize(&lins,&cols); 506 507 508 ReBufferDisplay(); /* re-make display buffers */ 509 ClearDisp(); 510} 511 void 512PutPlusOne(Char c, int width) 513{ 514 extern int OldvcV; 515 516 while (width > 1 && CursorH + width > DisplayWindowHSize) 517 PutPlusOne(' ', 1); 518 if ((c & LITERAL) != 0) { 519 Char *d; 520 for (d = litptr + (c & ~LITERAL) * LIT_FACTOR; *d; d++) 521 (void) putwraw(*d); 522 } else { 523 (void) putwraw(c); 524 } 525 526 Display[CursorV][CursorH++] = (Char) c; 527 while (--width > 0) 528 Display[CursorV][CursorH++] = CHAR_DBWIDTH; 529 530 if (CursorH >= TermH) { /* if we must overflow */ 531 CursorH = 0; 532 CursorV++; 533 OldvcV++; 534 NT_WrapHorizontal(); 535 } 536 else if(CursorH >= DisplayWindowHSize) { 537 NT_MoveToLineOrChar(CursorH,0); 538 } 539} 540