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;
}
}
|