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