aboutsummaryrefslogtreecommitdiff
path: root/sys/tty/ttygsize.x
blob: e4ccfa1a5ecac419de5bab59f01ae0388946bfd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<ttyset.h>
include	<ttset.h>
include	<fset.h>

define	TIMEOUT  2000		# timeout interval, msec, for size query


# TTYGSIZE -- Get the width and height of the terminal screen in characters.
# For a conventional terminal these values are given as constants in the
# termcap entry for the device.  If the terminal has a screen which can vary
# in size at runtime (e.g., a window on a workstation), then the screen size
# is queried at runtime.

procedure ttygsize (in, out, tty, width, height)

int	in, out			# input and output streams
pointer	tty			# terminal descriptor
int	width			# ncols on screen (out)
int	height			# nlines on screen (out)

pointer	sp, patbuf, buf, qs, wh, ip, op
int	index, len_qs, len_wh, w_index, h_index, sv_iomode, nchars, junk

int	patmake(), patindex(), gstrcpy(), ctoi()
int	ttygets(), ttyread(), ttystati(), ttstati(), fstati()
define	noquery_ 91
errchk	ttyread

begin
	call smark (sp)
	call salloc (patbuf, SZ_LINE, TY_CHAR)
	call salloc (buf, SZ_LINE, TY_CHAR)
	call salloc (qs, SZ_FNAME, TY_CHAR)
	call salloc (wh, SZ_FNAME, TY_CHAR)

	width = 0
	height = 0
	index = 0

	# Just use the termcap values if in stty playback or record mode.
	if (ttstati(in,TT_LOGIN) == YES || ttstati(in,TT_PLAYBACK) == YES)
	    goto noquery_

	len_qs = ttygets (tty, "qs", Memc[qs], SZ_FNAME)
	len_wh = ttygets (tty, "wh", Memc[wh], SZ_FNAME)

	# Process the string DS (decode size string) to map the %W %H fields
	# into the pattern strings "%[0-9]*", noting the index positions of
	# the W and H fields.

	if (len_wh > 0) {
	    op = buf
	    for (ip=wh;  Memc[ip] != EOS;  ip=ip+1) {
		if ((Memc[ip] == '%') && ip > wh && Memc[ip-1] != '\\' &&
		    (Memc[ip+1] == 'W' || Memc[ip+1] == 'H')) {

		    index = index + 1
		    op = op + gstrcpy ("%[0-9]*", Memc[op], ARB)
		    ip = ip + 1

		    if (Memc[ip] == 'W')
			w_index = index
		    else
			h_index = index
		} else {
		    Memc[op] = Memc[ip]
		    op = op + 1
		}
	    }
	    Memc[op] = EOS
	    junk = patmake (Memc[buf], Memc[patbuf], SZ_LINE)
	}

	# Query the terminal for the screen size, read back and decode the
	# encoded screen size string.

	if (len_qs > 0 && len_wh > 0) {
	    sv_iomode = fstati (in, F_IOMODE)
	    if (sv_iomode != IO_RAW)
		call fseti (in, F_IOMODE, IO_RAW)

	    call ttywrite (out, tty, Memc[qs], len_qs, 0)
	    call flush (out)

	    nchars = ttyread (in, tty, Memc[buf],SZ_LINE,Memc[patbuf], TIMEOUT)
	    if (nchars > 0) {
		if (ctoi (Memc[buf],patindex(Memc[patbuf],w_index),width) <= 0)
		    width = 0
		if (ctoi (Memc[buf],patindex(Memc[patbuf],h_index),height) <= 0)
		    height = 0
	    }

	    if (sv_iomode != IO_RAW)
		call fseti (in, F_IOMODE, sv_iomode)

	    if (width == 0 && nchars == 0) {
		call eprintf ("timeout - terminal type set wrong? ")
		call eprintf ("(`stty termtype' to reset)\n")
	    }
	}

noquery_
	# If we still do not know the screen width or height, use the values
	# given in the user environment, else in the termcap entry for the
	# device.

	if (width <= 0)
	    width = ttystati (tty, TTY_NCOLS)
	if (height <= 0)
	    height = ttystati (tty, TTY_NLINES)

	call sfree (sp)
end