File: gui.c

package info (click to toggle)
elvis 2.1i-3
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 4,120 kB
  • ctags: 5,838
  • sloc: ansic: 53,854; sh: 811; makefile: 263
file content (204 lines) | stat: -rw-r--r-- 5,692 bytes parent folder | download | duplicates (2)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/* gui.c */
/* Copyright 1995 by Steve Kirkendall */

char id_gui[] = "$Id: gui.c,v 2.13 1997/12/24 03:12:52 steve Exp $";

#include "elvis.h"

/* This is a pointer to the chosen GUI. */
GUI *gui;

/* This function calls the GUI's moveto() function.  This function performs a
 * tiny amount of optimization, however: if the cursor is already in the
 * correct position, it does nothing.
 */
void guimoveto(win, column, row)
	WINDOW	win;	/* window whose cursor is to be moved */
	int	column;	/* column where cursor should be placed */
	int	row;	/* row where cursor should be placed */
{
	/* perform the moveto */
	(*gui->moveto)(win->gw, column, row);
	win->cursx = column;
	win->cursy = row;
}

/* This function calls the GUI's draw() function, and then updates elvis'
 * own idea of where the cursor is.  The guimove() function depends on your
 * calling guidraw() instead of (*gui->draw)().
 */
void guidraw(win, font, text, len)
	WINDOW	win;	/* window where text is to be drawn */
	_char_	font;	/* font to use for drawing */
	CHAR	*text;	/* text to be drawn */
	int	len;	/* number of characters in text */
{
	(*gui->draw)(win->gw, font, text, len);
	win->cursx += len;
}

/* This function calls the GUI's scroll() function, but only if the number of
 * lines to be deleted/inserted is smaller than the number of lines remaining.
 * And only if the GUI has a scroll() function, of course.
 *
 * Returns True if the scrolling happened as requested, else False.
 */
BOOLEAN guiscroll(win, qty, notlast)
	WINDOW	win;	/* window to be scrolled */
	int	qty;	/* rows to insert (may be negative to delete) */
	BOOLEAN	notlast;/* if True, scrolling shouldn't affect last row */
{
	/* if there is no gui->scroll() function, or if we're trying to
	 * insert/delete too many rows, then fail.
	 */
	if (gui->scroll == NULL || abs(qty) >= o_lines(win) - win->cursy)
	{
		return False;
	}

	/* else give the GUI a try */
	return (*gui->scroll)(win->gw, qty, notlast);
}

/* This function calls the GUI's shift() function, but only if the number of
 * characters to the right of the cursor is larger than the requested shift
 * amount.  And only if the GUI has a shift() function, of course.
 *
 * Returns True if the shifting happened as requested, else False.
 */
BOOLEAN guishift(win, qty, rows)
	WINDOW	win;	/* window to be shifted */
	int	qty;	/* columns to insert (may be negative to delete) */
	int	rows;	/* number of rows affected */
{
	/* if there is no gui->shift() function, or if we're trying to
	 * insert/delete too many characters, then fail.
	 */
	if (!gui->shift || abs(qty) >= o_columns(win) - win->cursx)
	{
		return False;
	}

	/* else give the GUI a try */
	return (*gui->shift)(win->gw, qty, rows);
}

/* This function calls the GUI's cltroeol() function.  If it doesn't exist,
 * or returns False, then this function writes enough space characters to
 * simulate a clrtoeol()
 */
void guiclrtoeol(win)
	WINDOW	win;	/* window whose row is to be cleared */
{
	static CHAR	blanks[10] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
	int		width;

	/* if already at EOL, we're done */
	width = o_columns(win) - win->cursx;
	if (width <= 0)
	{
		return;
	}

	/* try to make the GUI do it */
	if (gui->clrtoeol == NULL || !(*gui->clrtoeol)(win->gw))
	{
		/* No, we need to do it the hard way */
		(*gui->moveto)(win->gw, win->cursx, win->cursy);
		while (width > 10)
		{
			(*gui->draw)(win->gw, 'n', blanks, 10);
			width -= 10;
		}
		(*gui->draw)(win->gw, 'n', blanks, width);
		(*gui->moveto)(win->gw, win->cursx, win->cursy);
	}
}


/* This function calls the GUI's reset function (if it has one) and also
 * resets the portable GUI wrapper functions' variables.
 *
 * Why do this?  Because the wrapper functions, and some GUI drawing functions,
 * perform some internal optimizations by assuming that nothing else affects
 * the screen when we aren't looking; so we ^L is going to force the whole
 * screen to be redrawn, that assumption is unsafe.
 */
void guireset()
{
	WINDOW	w;

	/* if the GUI has a reset function call it */
	if (gui->reset)
	{
		(*gui->reset)();
	}

	/* reset the wrapper functions' variables */
	for (w = windows; w; w = w->next)
	{
		w->cursx = w->cursy = -1;
	}
}


/* This function calls the GUI's poll() function.  If it has no poll() function
 * then this function always returns False to indicate that the current work
 * should continue.  This function is also sensitive to the pollfrequency
 * option, to reduce the number of calls to poll() since poll() may be slow.
 *
 * Returns False if the current work should continue, or True if the user
 * has requested that it be cut short.
 */
BOOLEAN guipoll(reset)
	BOOLEAN	reset;	/* reset the pollctr variable? */
{
	static long	pollctr = 0;

	/* if just supposed to reset, then do that and then quit */
	if (reset)
	{
		pollctr = 0;
		if (gui && gui->poll)
			return (*gui->poll)(reset);
		else
			return False;
	}

	/* if there is no poll() function, or pollfrequency indicates that
	 * poll() shouldn't be called yet, then return False so the current
	 * operation will continue.
	 */
	if (!gui || !gui->poll || ++pollctr < o_pollfrequency)
	{
		return False;
	}

	/* reset the pollctr variable */
	pollctr = 0;

	/* call the GUI's poll() function, and return its value */
	reset = (*gui->poll)(reset);
	if (reset)
	{
		msg(MSG_ERROR, "aborted");
	}
	return reset;
}

/* ring the bell, if there is one.  Limit it to one ding per eventdraw() */
void guibeep(win)
	WINDOW	win;	/* window to ding, or NULL to indicate an eventdraw() */
{
	static BOOLEAN	dingable = True;

	if (!win)
	{
		dingable = True;
	}
	else if (gui && gui->beep && dingable)
	{
		(*gui->beep)(win->gw);
		dingable = False;
	}
}