Syscons bug fix: tab now right (thanks bruce!)

Mouse arrow support almost finished.
This commit is contained in:
sos 1995-02-01 21:56:32 +00:00
parent ee40c57479
commit 1df425c1ad
3 changed files with 939 additions and 861 deletions

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: syscons.c,v 1.96 1995/01/28 22:16:03 sos Exp $
* $Id: syscons.c,v 1.97 1995/01/30 21:36:28 sos Exp $
*/
#include "sc.h"
@ -97,7 +97,8 @@
#define CURSOR_ENABLED 0x00200
#define CURSOR_SHOWN 0x00400
#define MOUSE_ENABLED 0x00800
#define UPDATE_NEEDED 0x01000
#define UPDATE_MOUSE 0x01000
#define UPDATE_SCREEN 0x02000
/* configuration flags */
#define VISUAL_BELL 0x00001
@ -166,12 +167,14 @@ typedef struct scr_stat {
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
u_short *cursor_pos; /* cursor buffer position */
u_short cursor_saveunder; /* saved chars under cursor */
char cursor_start; /* cursor start line # */
char cursor_end; /* cursor end line # */
u_short *mouse_pos; /* mouse buffer position */
u_short mouse_xpos; /* mouse x coordinate */
u_short mouse_ypos; /* mouse y coordinate */
u_short mouse_saveunder[4]; /* saved chars under cursor */
u_short *mouse_oldpos; /* mouse old buffer position */
u_short mouse_saveunder[4]; /* saved chars under mouse */
short mouse_xpos; /* mouse x coordinate */
short mouse_ypos; /* mouse y coordinate */
u_char mouse_cursor[128]; /* mouse cursor bitmap store */
u_short bell_duration;
u_short bell_pitch;
@ -181,10 +184,11 @@ typedef struct scr_stat {
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
u_short *history;
u_short *history_head;
u_short *history_pos;
int history_size;
u_short *history; /* circular history buffer */
u_short *history_head; /* current head position */
u_short *history_pos; /* position shown on screen */
u_short *history_save; /* save area index */
int history_size; /* size of history buffer */
} scr_stat;
typedef struct default_attr {
@ -225,7 +229,7 @@ static u_char kbd_reply = 0;
static int delayed_next_scr;
static int configuration = 0; /* current setup */
static long scrn_blank_time = 0; /* screen saver timeout value */
static int scrn_blanked = 0; /* screen saver active flag */
static int scrn_blanked = FALSE; /* screen saver active flag */
static int scrn_saver = 0; /* screen saver routine */
static long scrn_time_stamp;
static u_char scr_map[256];
@ -271,8 +275,7 @@ static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
static inline void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
static inline void undraw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp, int show);
static void ansi_put(scr_stat *scp, u_char *buf, int len);
static u_char *get_fstr(u_int c, u_int *len);
static void update_leds(int which);
@ -287,7 +290,6 @@ static void set_vgaregs(char *modetable);
static void set_font_mode();
static void set_normal_mode();
static void copy_font(int operation, int font_type, char* font_image);
static void undraw_mouse_image(scr_stat *scp);
static void draw_mouse_image(scr_stat *scp);
static void save_palette(void);
static void load_palette(void);
@ -599,7 +601,7 @@ scintr(int unit)
scrn_time_stamp = time.tv_sec;
if (scrn_blanked) {
SCRN_SAVER(FALSE);
cur_console->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
cur_console->status |= UPDATE_SCREEN;
}
c = scgetc(1);
@ -756,65 +758,65 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case FONT_16:
fontsize = 16; break;
}
switch (mouse->operation) {
case MOUSE_SHOW:
if (!(scp->status & MOUSE_ENABLED)) {
draw_mouse_image(scp);
scp->status |= MOUSE_ENABLED;
scp->mouse_oldpos =
Crtat + (scp->mouse_pos - scp->scr_buf);
scp->status |= (UPDATE_MOUSE | MOUSE_ENABLED);
}
else
return EINVAL;
break;
case MOUSE_HIDE:
if (scp->status & MOUSE_ENABLED) {
undraw_mouse_image(scp);
scp->status &= ~MOUSE_ENABLED;
scp->status |= UPDATE_MOUSE;
}
else
return EINVAL;
break;
case MOUSE_MOVEABS:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos = mouse->x;
scp->mouse_ypos = mouse->y;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
break;
goto set_mouse_pos;
case MOUSE_MOVEREL:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos += mouse->x;
scp->mouse_ypos += mouse->y;
set_mouse_pos:
if (scp->mouse_xpos < 0)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
if (scp->mouse_xpos >= scp->xsize*8)
scp->mouse_xpos = (scp->xsize*8)-1;
if (scp->mouse_ypos >= scp->ysize*fontsize)
scp->mouse_ypos = (scp->ysize*fontsize)-1;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
scp->status |= UPDATE_MOUSE;
break;
case MOUSE_GETPOS:
mouse->x = scp->mouse_xpos;
mouse->y = scp->mouse_ypos;
break;
return 0;
default:
return EINVAL;
}
/* make screensaver happy */
if (scp == cur_console) {
scrn_time_stamp = time.tv_sec;
if (scrn_blanked)
scp->status |= UPDATE_SCREEN;
SCRN_SAVER(FALSE);
}
return 0;
}
@ -1297,7 +1299,7 @@ scstart(struct tty *tp)
len = q_to_b(rbp, buf, PCBURST);
ansi_put(scp, buf, len);
}
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
s = spltty();
tp->t_state &= ~TS_BUSY;
if (rbp->c_cc <= tp->t_lowat) {
@ -1533,28 +1535,33 @@ scrn_timer()
static int cursor_blinkrate;
scr_stat *scp = cur_console;
if (scp->status & UNKNOWN_MODE) {
/* should we just return ? */
if ((scp->status & UNKNOWN_MODE) || blink_in_progress) {
timeout((timeout_func_t)scrn_timer, 0, hz/10);
return;
}
/* update physical screen */
if (scp->status & UPDATE_NEEDED) {
bcopyw(scp->scr_buf, Crtat,
scp->xsize*scp->ysize*sizeof(u_short));
if (!(configuration&BLINK_CURSOR) && scp->status&CURSOR_ENABLED)
draw_cursor(scp);
scp->status &= ~UPDATE_NEEDED;
if (!scrn_blanked) {
/* update entire screen image */
if (scp->status & UPDATE_SCREEN) {
bcopyw(scp->scr_buf, Crtat, scp->xsize*scp->ysize*sizeof(u_short));
scp->status &= ~CURSOR_SHOWN;
}
if ((configuration & BLINK_CURSOR) && (scp->status & CURSOR_ENABLED)) {
if (cursor_blinkrate++ & 0x04)
draw_cursor(scp);
/* update "pseudo" mouse */
if ((scp->status & MOUSE_ENABLED) &&
((scp->status & UPDATE_MOUSE) || (scp->status & UPDATE_SCREEN)))
draw_mouse_image(scp);
/* update cursor image */
if (scp->status & CURSOR_ENABLED) {
if ((configuration & BLINK_CURSOR) && (cursor_blinkrate++ & 0x04))
draw_cursor(scp, FALSE);
else
undraw_cursor(scp);
draw_cursor(scp, TRUE);
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time)) {
scp->status &= ~CURSOR_ENABLED;
scp->status &= ~UPDATE_SCREEN;
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time))
SCRN_SAVER(TRUE);
}
timeout((timeout_func_t)scrn_timer, 0, hz/25);
}
@ -1648,7 +1655,7 @@ exchange_scr(void)
shfts = ctls = alts = agrs = metas = 0;
update_leds(new_scp->status);
delayed_next_scr = FALSE;
new_scp->status |= UPDATE_NEEDED;
new_scp->status |= UPDATE_SCREEN;
}
static inline void
@ -2102,18 +2109,13 @@ scan_esc(scr_stat *scp, u_char c)
}
static inline void
undraw_cursor(scr_stat *scp)
draw_cursor(scr_stat *scp, int show)
{
if (scp->status & CURSOR_SHOWN)
*(Crtat+(scp->cursor_pos - scp->scr_buf)) = *scp->cursor_pos;
scp->status &= ~CURSOR_SHOWN;
}
static inline void
draw_cursor(scr_stat *scp)
{
u_short cursor_image = *scp->cursor_pos;
if (show && !(scp->status & CURSOR_SHOWN)) {
u_short cursor_image =
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf));
scp->cursor_saveunder = cursor_image;
if ((cursor_image & 0x7000) == 0x7000) {
cursor_image &= 0x8fff;
if(!(cursor_image & 0x0700))
@ -2123,9 +2125,15 @@ draw_cursor(scr_stat *scp)
if ((cursor_image & 0x0f00) == 0x0700)
cursor_image &= 0xf8ff;
}
*(Crtat+(cur_console->cursor_pos-cur_console->scr_buf)) = cursor_image;
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf)) =
cursor_image;
scp->status |= CURSOR_SHOWN;
}
if (!show && (scp->status & CURSOR_SHOWN)) {
*(Crtat+(scp->cursor_pos-scp->scr_buf)) = scp->cursor_saveunder;
scp->status &= ~CURSOR_SHOWN;
}
}
static void
ansi_put(scr_stat *scp, u_char *buf, int len)
@ -2191,8 +2199,15 @@ ansi_put(scr_stat *scp, u_char *buf, int len)
scp->xpos = 0;
break;
case '\t': /* non-destructive tab */
scp->cursor_pos += (8 - scp->xpos % 8);
scp->xpos += (8 - scp->xpos % 8);
{
int i = 8 - scp->xpos % 8u;
scp->cursor_pos += i;
if ((scp->xpos += i) >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
}
}
break;
}
ptr++; len--;
@ -2360,7 +2375,7 @@ scput(u_char c)
current_default = &kernel_default;
scp->status &= ~CURSOR_ENABLED;
ansi_put(scp, &c, 1);
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
kernel_console = scp->term;
current_default = &user_default;
scp->term = save;
@ -2406,11 +2421,13 @@ history_to_screen(scr_stat *scp)
{
int i;
scp->status &= ~UPDATE_SCREEN;
for (i=0; i<scp->ysize; i++)
bcopyw(scp->history + (((scp->history_pos - scp->history) +
scp->history_size-((i+1)*scp->xsize))%scp->history_size),
Crtat + (scp->xsize * (scp->ysize-1 - i)),
scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
scp->xsize * sizeof(u_short));
scp->status |= UPDATE_SCREEN;
}
static int
@ -2451,7 +2468,6 @@ scgetc(int noblock)
struct key_t *key;
static u_char esc_flag = 0, compose = 0;
static u_int chr = 0;
static u_short *saved_history_head;
next_code:
kbd_wait();
@ -2582,10 +2598,9 @@ scgetc(int noblock)
cur_console->status &= ~CURSOR_ENABLED;
if (!(cur_console->status & BUFFER_SAVED)) {
cur_console->status &= ~UPDATE_NEEDED;
cur_console->status |= BUFFER_SAVED;
saved_history_head = cur_console->history_head;
/* copy scp->ysize line into history */
cur_console->history_save = cur_console->history_head;
/* copy screen into top of history buffer */
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->scr_buf + (cur_console->xsize * i),
cur_console->history_head,
@ -2763,15 +2778,17 @@ scgetc(int noblock)
if (cur_console->status & SLKED) {
cur_console->status &= ~SLKED;
if (cur_console->status & BUFFER_SAVED){
bcopyw(cur_console->scr_buf, Crtat,
cur_console->xsize *
cur_console->ysize *
sizeof(u_short));
int i;
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->history_save+(cur_console->xsize*i),
cur_console->scr_buf + (cur_console->xsize * i),
cur_console->xsize * sizeof(u_short));
}
cur_console->status&=~BUFFER_SAVED;
cur_console->history_head =
saved_history_head;
cur_console->history_save;
cur_console->status |=
(CURSOR_ENABLED|UPDATE_NEEDED);
(CURSOR_ENABLED|UPDATE_SCREEN);
}
scstart(VIRTUAL_TTY(get_scr_num()));
}
@ -3154,17 +3171,6 @@ copy_font(int operation, int font_type, char* font_image)
outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
}
static void
undraw_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
*(crt_pos) = *(scp->mouse_pos);
*(crt_pos+1) = *(scp->mouse_pos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize);
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1);
}
static void
draw_mouse_image(scr_stat *scp)
{
@ -3198,18 +3204,13 @@ draw_mouse_image(scr_stat *scp)
break;
}
scp->mouse_saveunder[0] = *(crt_pos);
scp->mouse_saveunder[1] = *(crt_pos+1);
scp->mouse_saveunder[2] = *(crt_pos+scp->xsize);
scp->mouse_saveunder[3] = *(crt_pos+scp->xsize+1);
bcopyw(font_buffer+((scp->mouse_saveunder[0] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos) & 0xff)*font_size),
&scp->mouse_cursor[0], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[1] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+1) & 0xff)*font_size),
&scp->mouse_cursor[32], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[2] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize) & 0xff)*font_size),
&scp->mouse_cursor[64], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[3] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize+1) & 0xff)*font_size),
&scp->mouse_cursor[96], font_size);
for (i=0; i<font_size; i++) {
@ -3230,12 +3231,38 @@ draw_mouse_image(scr_stat *scp)
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
}
/*
* if we didn't update entire screen, restore old mouse position
* and check if we overwrote the cursor location..
*/
if ((scp->status & UPDATE_MOUSE) && !(scp->status & UPDATE_SCREEN)) {
u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
if (crt_pos != scp->mouse_oldpos) {
*(scp->mouse_oldpos) = scp->mouse_saveunder[0];
*(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
*(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
*(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
}
scp->mouse_saveunder[0] = *(scp->mouse_pos);
scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
if ((scp->cursor_pos == (ptr)) ||
(scp->cursor_pos == (ptr+1)) ||
(scp->cursor_pos == (ptr+scp->xsize)) ||
(scp->cursor_pos == (ptr+scp->xsize+1)) ||
(scp->cursor_pos == (scp->mouse_pos)) ||
(scp->cursor_pos == (scp->mouse_pos+1)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
scp->status &= ~CURSOR_SHOWN;
}
scp->mouse_oldpos = crt_pos;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
*(crt_pos) = (scp->mouse_saveunder[0]&0xff00)|0xc0;
*(crt_pos+1) = (scp->mouse_saveunder[1]&0xff00)|0xc1;
*(crt_pos+scp->xsize) = (scp->mouse_saveunder[2]&0xff00)|0xc2;
*(crt_pos+scp->xsize+1) = (scp->mouse_saveunder[3]&0xff00)|0xc3;
*(crt_pos) = *(scp->mouse_pos)&0xff00|0xc0;
*(crt_pos+1) = *(scp->mouse_pos+1)&0xff00|0xc1;
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize)&0xff00|0xc2;
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1)&0xff00|0xc3;
set_font_mode();
bcopy(scp->mouse_cursor,
(char *)pa_to_va(address) + 0xc0 * 32, 128);
@ -3273,7 +3300,6 @@ do_bell(scr_stat *scp, int pitch, int duration)
if (configuration & VISUAL_BELL) {
if (blink_in_progress)
return;
scp->status &= ~CURSOR_ENABLED;
blink_in_progress = 4;
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
@ -3296,7 +3322,7 @@ blink_screen(scr_stat *scp)
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
else {
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= UPDATE_SCREEN;
blink_in_progress = FALSE;
}
}

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: syscons.c,v 1.96 1995/01/28 22:16:03 sos Exp $
* $Id: syscons.c,v 1.97 1995/01/30 21:36:28 sos Exp $
*/
#include "sc.h"
@ -97,7 +97,8 @@
#define CURSOR_ENABLED 0x00200
#define CURSOR_SHOWN 0x00400
#define MOUSE_ENABLED 0x00800
#define UPDATE_NEEDED 0x01000
#define UPDATE_MOUSE 0x01000
#define UPDATE_SCREEN 0x02000
/* configuration flags */
#define VISUAL_BELL 0x00001
@ -166,12 +167,14 @@ typedef struct scr_stat {
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
u_short *cursor_pos; /* cursor buffer position */
u_short cursor_saveunder; /* saved chars under cursor */
char cursor_start; /* cursor start line # */
char cursor_end; /* cursor end line # */
u_short *mouse_pos; /* mouse buffer position */
u_short mouse_xpos; /* mouse x coordinate */
u_short mouse_ypos; /* mouse y coordinate */
u_short mouse_saveunder[4]; /* saved chars under cursor */
u_short *mouse_oldpos; /* mouse old buffer position */
u_short mouse_saveunder[4]; /* saved chars under mouse */
short mouse_xpos; /* mouse x coordinate */
short mouse_ypos; /* mouse y coordinate */
u_char mouse_cursor[128]; /* mouse cursor bitmap store */
u_short bell_duration;
u_short bell_pitch;
@ -181,10 +184,11 @@ typedef struct scr_stat {
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
u_short *history;
u_short *history_head;
u_short *history_pos;
int history_size;
u_short *history; /* circular history buffer */
u_short *history_head; /* current head position */
u_short *history_pos; /* position shown on screen */
u_short *history_save; /* save area index */
int history_size; /* size of history buffer */
} scr_stat;
typedef struct default_attr {
@ -225,7 +229,7 @@ static u_char kbd_reply = 0;
static int delayed_next_scr;
static int configuration = 0; /* current setup */
static long scrn_blank_time = 0; /* screen saver timeout value */
static int scrn_blanked = 0; /* screen saver active flag */
static int scrn_blanked = FALSE; /* screen saver active flag */
static int scrn_saver = 0; /* screen saver routine */
static long scrn_time_stamp;
static u_char scr_map[256];
@ -271,8 +275,7 @@ static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
static inline void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
static inline void undraw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp, int show);
static void ansi_put(scr_stat *scp, u_char *buf, int len);
static u_char *get_fstr(u_int c, u_int *len);
static void update_leds(int which);
@ -287,7 +290,6 @@ static void set_vgaregs(char *modetable);
static void set_font_mode();
static void set_normal_mode();
static void copy_font(int operation, int font_type, char* font_image);
static void undraw_mouse_image(scr_stat *scp);
static void draw_mouse_image(scr_stat *scp);
static void save_palette(void);
static void load_palette(void);
@ -599,7 +601,7 @@ scintr(int unit)
scrn_time_stamp = time.tv_sec;
if (scrn_blanked) {
SCRN_SAVER(FALSE);
cur_console->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
cur_console->status |= UPDATE_SCREEN;
}
c = scgetc(1);
@ -756,65 +758,65 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case FONT_16:
fontsize = 16; break;
}
switch (mouse->operation) {
case MOUSE_SHOW:
if (!(scp->status & MOUSE_ENABLED)) {
draw_mouse_image(scp);
scp->status |= MOUSE_ENABLED;
scp->mouse_oldpos =
Crtat + (scp->mouse_pos - scp->scr_buf);
scp->status |= (UPDATE_MOUSE | MOUSE_ENABLED);
}
else
return EINVAL;
break;
case MOUSE_HIDE:
if (scp->status & MOUSE_ENABLED) {
undraw_mouse_image(scp);
scp->status &= ~MOUSE_ENABLED;
scp->status |= UPDATE_MOUSE;
}
else
return EINVAL;
break;
case MOUSE_MOVEABS:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos = mouse->x;
scp->mouse_ypos = mouse->y;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
break;
goto set_mouse_pos;
case MOUSE_MOVEREL:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos += mouse->x;
scp->mouse_ypos += mouse->y;
set_mouse_pos:
if (scp->mouse_xpos < 0)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
if (scp->mouse_xpos >= scp->xsize*8)
scp->mouse_xpos = (scp->xsize*8)-1;
if (scp->mouse_ypos >= scp->ysize*fontsize)
scp->mouse_ypos = (scp->ysize*fontsize)-1;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
scp->status |= UPDATE_MOUSE;
break;
case MOUSE_GETPOS:
mouse->x = scp->mouse_xpos;
mouse->y = scp->mouse_ypos;
break;
return 0;
default:
return EINVAL;
}
/* make screensaver happy */
if (scp == cur_console) {
scrn_time_stamp = time.tv_sec;
if (scrn_blanked)
scp->status |= UPDATE_SCREEN;
SCRN_SAVER(FALSE);
}
return 0;
}
@ -1297,7 +1299,7 @@ scstart(struct tty *tp)
len = q_to_b(rbp, buf, PCBURST);
ansi_put(scp, buf, len);
}
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
s = spltty();
tp->t_state &= ~TS_BUSY;
if (rbp->c_cc <= tp->t_lowat) {
@ -1533,28 +1535,33 @@ scrn_timer()
static int cursor_blinkrate;
scr_stat *scp = cur_console;
if (scp->status & UNKNOWN_MODE) {
/* should we just return ? */
if ((scp->status & UNKNOWN_MODE) || blink_in_progress) {
timeout((timeout_func_t)scrn_timer, 0, hz/10);
return;
}
/* update physical screen */
if (scp->status & UPDATE_NEEDED) {
bcopyw(scp->scr_buf, Crtat,
scp->xsize*scp->ysize*sizeof(u_short));
if (!(configuration&BLINK_CURSOR) && scp->status&CURSOR_ENABLED)
draw_cursor(scp);
scp->status &= ~UPDATE_NEEDED;
if (!scrn_blanked) {
/* update entire screen image */
if (scp->status & UPDATE_SCREEN) {
bcopyw(scp->scr_buf, Crtat, scp->xsize*scp->ysize*sizeof(u_short));
scp->status &= ~CURSOR_SHOWN;
}
if ((configuration & BLINK_CURSOR) && (scp->status & CURSOR_ENABLED)) {
if (cursor_blinkrate++ & 0x04)
draw_cursor(scp);
/* update "pseudo" mouse */
if ((scp->status & MOUSE_ENABLED) &&
((scp->status & UPDATE_MOUSE) || (scp->status & UPDATE_SCREEN)))
draw_mouse_image(scp);
/* update cursor image */
if (scp->status & CURSOR_ENABLED) {
if ((configuration & BLINK_CURSOR) && (cursor_blinkrate++ & 0x04))
draw_cursor(scp, FALSE);
else
undraw_cursor(scp);
draw_cursor(scp, TRUE);
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time)) {
scp->status &= ~CURSOR_ENABLED;
scp->status &= ~UPDATE_SCREEN;
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time))
SCRN_SAVER(TRUE);
}
timeout((timeout_func_t)scrn_timer, 0, hz/25);
}
@ -1648,7 +1655,7 @@ exchange_scr(void)
shfts = ctls = alts = agrs = metas = 0;
update_leds(new_scp->status);
delayed_next_scr = FALSE;
new_scp->status |= UPDATE_NEEDED;
new_scp->status |= UPDATE_SCREEN;
}
static inline void
@ -2102,18 +2109,13 @@ scan_esc(scr_stat *scp, u_char c)
}
static inline void
undraw_cursor(scr_stat *scp)
draw_cursor(scr_stat *scp, int show)
{
if (scp->status & CURSOR_SHOWN)
*(Crtat+(scp->cursor_pos - scp->scr_buf)) = *scp->cursor_pos;
scp->status &= ~CURSOR_SHOWN;
}
static inline void
draw_cursor(scr_stat *scp)
{
u_short cursor_image = *scp->cursor_pos;
if (show && !(scp->status & CURSOR_SHOWN)) {
u_short cursor_image =
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf));
scp->cursor_saveunder = cursor_image;
if ((cursor_image & 0x7000) == 0x7000) {
cursor_image &= 0x8fff;
if(!(cursor_image & 0x0700))
@ -2123,9 +2125,15 @@ draw_cursor(scr_stat *scp)
if ((cursor_image & 0x0f00) == 0x0700)
cursor_image &= 0xf8ff;
}
*(Crtat+(cur_console->cursor_pos-cur_console->scr_buf)) = cursor_image;
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf)) =
cursor_image;
scp->status |= CURSOR_SHOWN;
}
if (!show && (scp->status & CURSOR_SHOWN)) {
*(Crtat+(scp->cursor_pos-scp->scr_buf)) = scp->cursor_saveunder;
scp->status &= ~CURSOR_SHOWN;
}
}
static void
ansi_put(scr_stat *scp, u_char *buf, int len)
@ -2191,8 +2199,15 @@ ansi_put(scr_stat *scp, u_char *buf, int len)
scp->xpos = 0;
break;
case '\t': /* non-destructive tab */
scp->cursor_pos += (8 - scp->xpos % 8);
scp->xpos += (8 - scp->xpos % 8);
{
int i = 8 - scp->xpos % 8u;
scp->cursor_pos += i;
if ((scp->xpos += i) >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
}
}
break;
}
ptr++; len--;
@ -2360,7 +2375,7 @@ scput(u_char c)
current_default = &kernel_default;
scp->status &= ~CURSOR_ENABLED;
ansi_put(scp, &c, 1);
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
kernel_console = scp->term;
current_default = &user_default;
scp->term = save;
@ -2406,11 +2421,13 @@ history_to_screen(scr_stat *scp)
{
int i;
scp->status &= ~UPDATE_SCREEN;
for (i=0; i<scp->ysize; i++)
bcopyw(scp->history + (((scp->history_pos - scp->history) +
scp->history_size-((i+1)*scp->xsize))%scp->history_size),
Crtat + (scp->xsize * (scp->ysize-1 - i)),
scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
scp->xsize * sizeof(u_short));
scp->status |= UPDATE_SCREEN;
}
static int
@ -2451,7 +2468,6 @@ scgetc(int noblock)
struct key_t *key;
static u_char esc_flag = 0, compose = 0;
static u_int chr = 0;
static u_short *saved_history_head;
next_code:
kbd_wait();
@ -2582,10 +2598,9 @@ scgetc(int noblock)
cur_console->status &= ~CURSOR_ENABLED;
if (!(cur_console->status & BUFFER_SAVED)) {
cur_console->status &= ~UPDATE_NEEDED;
cur_console->status |= BUFFER_SAVED;
saved_history_head = cur_console->history_head;
/* copy scp->ysize line into history */
cur_console->history_save = cur_console->history_head;
/* copy screen into top of history buffer */
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->scr_buf + (cur_console->xsize * i),
cur_console->history_head,
@ -2763,15 +2778,17 @@ scgetc(int noblock)
if (cur_console->status & SLKED) {
cur_console->status &= ~SLKED;
if (cur_console->status & BUFFER_SAVED){
bcopyw(cur_console->scr_buf, Crtat,
cur_console->xsize *
cur_console->ysize *
sizeof(u_short));
int i;
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->history_save+(cur_console->xsize*i),
cur_console->scr_buf + (cur_console->xsize * i),
cur_console->xsize * sizeof(u_short));
}
cur_console->status&=~BUFFER_SAVED;
cur_console->history_head =
saved_history_head;
cur_console->history_save;
cur_console->status |=
(CURSOR_ENABLED|UPDATE_NEEDED);
(CURSOR_ENABLED|UPDATE_SCREEN);
}
scstart(VIRTUAL_TTY(get_scr_num()));
}
@ -3154,17 +3171,6 @@ copy_font(int operation, int font_type, char* font_image)
outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
}
static void
undraw_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
*(crt_pos) = *(scp->mouse_pos);
*(crt_pos+1) = *(scp->mouse_pos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize);
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1);
}
static void
draw_mouse_image(scr_stat *scp)
{
@ -3198,18 +3204,13 @@ draw_mouse_image(scr_stat *scp)
break;
}
scp->mouse_saveunder[0] = *(crt_pos);
scp->mouse_saveunder[1] = *(crt_pos+1);
scp->mouse_saveunder[2] = *(crt_pos+scp->xsize);
scp->mouse_saveunder[3] = *(crt_pos+scp->xsize+1);
bcopyw(font_buffer+((scp->mouse_saveunder[0] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos) & 0xff)*font_size),
&scp->mouse_cursor[0], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[1] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+1) & 0xff)*font_size),
&scp->mouse_cursor[32], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[2] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize) & 0xff)*font_size),
&scp->mouse_cursor[64], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[3] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize+1) & 0xff)*font_size),
&scp->mouse_cursor[96], font_size);
for (i=0; i<font_size; i++) {
@ -3230,12 +3231,38 @@ draw_mouse_image(scr_stat *scp)
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
}
/*
* if we didn't update entire screen, restore old mouse position
* and check if we overwrote the cursor location..
*/
if ((scp->status & UPDATE_MOUSE) && !(scp->status & UPDATE_SCREEN)) {
u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
if (crt_pos != scp->mouse_oldpos) {
*(scp->mouse_oldpos) = scp->mouse_saveunder[0];
*(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
*(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
*(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
}
scp->mouse_saveunder[0] = *(scp->mouse_pos);
scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
if ((scp->cursor_pos == (ptr)) ||
(scp->cursor_pos == (ptr+1)) ||
(scp->cursor_pos == (ptr+scp->xsize)) ||
(scp->cursor_pos == (ptr+scp->xsize+1)) ||
(scp->cursor_pos == (scp->mouse_pos)) ||
(scp->cursor_pos == (scp->mouse_pos+1)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
scp->status &= ~CURSOR_SHOWN;
}
scp->mouse_oldpos = crt_pos;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
*(crt_pos) = (scp->mouse_saveunder[0]&0xff00)|0xc0;
*(crt_pos+1) = (scp->mouse_saveunder[1]&0xff00)|0xc1;
*(crt_pos+scp->xsize) = (scp->mouse_saveunder[2]&0xff00)|0xc2;
*(crt_pos+scp->xsize+1) = (scp->mouse_saveunder[3]&0xff00)|0xc3;
*(crt_pos) = *(scp->mouse_pos)&0xff00|0xc0;
*(crt_pos+1) = *(scp->mouse_pos+1)&0xff00|0xc1;
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize)&0xff00|0xc2;
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1)&0xff00|0xc3;
set_font_mode();
bcopy(scp->mouse_cursor,
(char *)pa_to_va(address) + 0xc0 * 32, 128);
@ -3273,7 +3300,6 @@ do_bell(scr_stat *scp, int pitch, int duration)
if (configuration & VISUAL_BELL) {
if (blink_in_progress)
return;
scp->status &= ~CURSOR_ENABLED;
blink_in_progress = 4;
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
@ -3296,7 +3322,7 @@ blink_screen(scr_stat *scp)
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
else {
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= UPDATE_SCREEN;
blink_in_progress = FALSE;
}
}

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: syscons.c,v 1.96 1995/01/28 22:16:03 sos Exp $
* $Id: syscons.c,v 1.97 1995/01/30 21:36:28 sos Exp $
*/
#include "sc.h"
@ -97,7 +97,8 @@
#define CURSOR_ENABLED 0x00200
#define CURSOR_SHOWN 0x00400
#define MOUSE_ENABLED 0x00800
#define UPDATE_NEEDED 0x01000
#define UPDATE_MOUSE 0x01000
#define UPDATE_SCREEN 0x02000
/* configuration flags */
#define VISUAL_BELL 0x00001
@ -166,12 +167,14 @@ typedef struct scr_stat {
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
u_short *cursor_pos; /* cursor buffer position */
u_short cursor_saveunder; /* saved chars under cursor */
char cursor_start; /* cursor start line # */
char cursor_end; /* cursor end line # */
u_short *mouse_pos; /* mouse buffer position */
u_short mouse_xpos; /* mouse x coordinate */
u_short mouse_ypos; /* mouse y coordinate */
u_short mouse_saveunder[4]; /* saved chars under cursor */
u_short *mouse_oldpos; /* mouse old buffer position */
u_short mouse_saveunder[4]; /* saved chars under mouse */
short mouse_xpos; /* mouse x coordinate */
short mouse_ypos; /* mouse y coordinate */
u_char mouse_cursor[128]; /* mouse cursor bitmap store */
u_short bell_duration;
u_short bell_pitch;
@ -181,10 +184,11 @@ typedef struct scr_stat {
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
u_short *history;
u_short *history_head;
u_short *history_pos;
int history_size;
u_short *history; /* circular history buffer */
u_short *history_head; /* current head position */
u_short *history_pos; /* position shown on screen */
u_short *history_save; /* save area index */
int history_size; /* size of history buffer */
} scr_stat;
typedef struct default_attr {
@ -225,7 +229,7 @@ static u_char kbd_reply = 0;
static int delayed_next_scr;
static int configuration = 0; /* current setup */
static long scrn_blank_time = 0; /* screen saver timeout value */
static int scrn_blanked = 0; /* screen saver active flag */
static int scrn_blanked = FALSE; /* screen saver active flag */
static int scrn_saver = 0; /* screen saver routine */
static long scrn_time_stamp;
static u_char scr_map[256];
@ -271,8 +275,7 @@ static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
static inline void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
static inline void undraw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp);
static inline void draw_cursor(scr_stat *scp, int show);
static void ansi_put(scr_stat *scp, u_char *buf, int len);
static u_char *get_fstr(u_int c, u_int *len);
static void update_leds(int which);
@ -287,7 +290,6 @@ static void set_vgaregs(char *modetable);
static void set_font_mode();
static void set_normal_mode();
static void copy_font(int operation, int font_type, char* font_image);
static void undraw_mouse_image(scr_stat *scp);
static void draw_mouse_image(scr_stat *scp);
static void save_palette(void);
static void load_palette(void);
@ -599,7 +601,7 @@ scintr(int unit)
scrn_time_stamp = time.tv_sec;
if (scrn_blanked) {
SCRN_SAVER(FALSE);
cur_console->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
cur_console->status |= UPDATE_SCREEN;
}
c = scgetc(1);
@ -756,65 +758,65 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case FONT_16:
fontsize = 16; break;
}
switch (mouse->operation) {
case MOUSE_SHOW:
if (!(scp->status & MOUSE_ENABLED)) {
draw_mouse_image(scp);
scp->status |= MOUSE_ENABLED;
scp->mouse_oldpos =
Crtat + (scp->mouse_pos - scp->scr_buf);
scp->status |= (UPDATE_MOUSE | MOUSE_ENABLED);
}
else
return EINVAL;
break;
case MOUSE_HIDE:
if (scp->status & MOUSE_ENABLED) {
undraw_mouse_image(scp);
scp->status &= ~MOUSE_ENABLED;
scp->status |= UPDATE_MOUSE;
}
else
return EINVAL;
break;
case MOUSE_MOVEABS:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos = mouse->x;
scp->mouse_ypos = mouse->y;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
break;
goto set_mouse_pos;
case MOUSE_MOVEREL:
if (scp->status & MOUSE_ENABLED)
undraw_mouse_image(scp);
scp->mouse_xpos += mouse->x;
scp->mouse_ypos += mouse->y;
set_mouse_pos:
if (scp->mouse_xpos < 0)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
if (scp->mouse_xpos >= scp->xsize*8)
scp->mouse_xpos = (scp->xsize*8)-1;
if (scp->mouse_ypos >= scp->ysize*fontsize)
scp->mouse_ypos = (scp->ysize*fontsize)-1;
scp->mouse_pos = scp->scr_buf +
(scp->mouse_ypos/fontsize)*scp->xsize +
scp->mouse_xpos/8;
if (scp->mouse_pos >
scp->scr_buf + (scp->xsize * scp->ysize))
scp->mouse_pos = scp->scr_buf +
(scp->xsize * scp->ysize);
else if (scp->mouse_pos < 0)
scp->mouse_pos = 0;
if (scp->status & MOUSE_ENABLED)
draw_mouse_image(scp);
scp->status |= UPDATE_MOUSE;
break;
case MOUSE_GETPOS:
mouse->x = scp->mouse_xpos;
mouse->y = scp->mouse_ypos;
break;
return 0;
default:
return EINVAL;
}
/* make screensaver happy */
if (scp == cur_console) {
scrn_time_stamp = time.tv_sec;
if (scrn_blanked)
scp->status |= UPDATE_SCREEN;
SCRN_SAVER(FALSE);
}
return 0;
}
@ -1297,7 +1299,7 @@ scstart(struct tty *tp)
len = q_to_b(rbp, buf, PCBURST);
ansi_put(scp, buf, len);
}
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
s = spltty();
tp->t_state &= ~TS_BUSY;
if (rbp->c_cc <= tp->t_lowat) {
@ -1533,28 +1535,33 @@ scrn_timer()
static int cursor_blinkrate;
scr_stat *scp = cur_console;
if (scp->status & UNKNOWN_MODE) {
/* should we just return ? */
if ((scp->status & UNKNOWN_MODE) || blink_in_progress) {
timeout((timeout_func_t)scrn_timer, 0, hz/10);
return;
}
/* update physical screen */
if (scp->status & UPDATE_NEEDED) {
bcopyw(scp->scr_buf, Crtat,
scp->xsize*scp->ysize*sizeof(u_short));
if (!(configuration&BLINK_CURSOR) && scp->status&CURSOR_ENABLED)
draw_cursor(scp);
scp->status &= ~UPDATE_NEEDED;
if (!scrn_blanked) {
/* update entire screen image */
if (scp->status & UPDATE_SCREEN) {
bcopyw(scp->scr_buf, Crtat, scp->xsize*scp->ysize*sizeof(u_short));
scp->status &= ~CURSOR_SHOWN;
}
if ((configuration & BLINK_CURSOR) && (scp->status & CURSOR_ENABLED)) {
if (cursor_blinkrate++ & 0x04)
draw_cursor(scp);
/* update "pseudo" mouse */
if ((scp->status & MOUSE_ENABLED) &&
((scp->status & UPDATE_MOUSE) || (scp->status & UPDATE_SCREEN)))
draw_mouse_image(scp);
/* update cursor image */
if (scp->status & CURSOR_ENABLED) {
if ((configuration & BLINK_CURSOR) && (cursor_blinkrate++ & 0x04))
draw_cursor(scp, FALSE);
else
undraw_cursor(scp);
draw_cursor(scp, TRUE);
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time)) {
scp->status &= ~CURSOR_ENABLED;
scp->status &= ~UPDATE_SCREEN;
}
if (scrn_blank_time && (time.tv_sec>scrn_time_stamp+scrn_blank_time))
SCRN_SAVER(TRUE);
}
timeout((timeout_func_t)scrn_timer, 0, hz/25);
}
@ -1648,7 +1655,7 @@ exchange_scr(void)
shfts = ctls = alts = agrs = metas = 0;
update_leds(new_scp->status);
delayed_next_scr = FALSE;
new_scp->status |= UPDATE_NEEDED;
new_scp->status |= UPDATE_SCREEN;
}
static inline void
@ -2102,18 +2109,13 @@ scan_esc(scr_stat *scp, u_char c)
}
static inline void
undraw_cursor(scr_stat *scp)
draw_cursor(scr_stat *scp, int show)
{
if (scp->status & CURSOR_SHOWN)
*(Crtat+(scp->cursor_pos - scp->scr_buf)) = *scp->cursor_pos;
scp->status &= ~CURSOR_SHOWN;
}
static inline void
draw_cursor(scr_stat *scp)
{
u_short cursor_image = *scp->cursor_pos;
if (show && !(scp->status & CURSOR_SHOWN)) {
u_short cursor_image =
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf));
scp->cursor_saveunder = cursor_image;
if ((cursor_image & 0x7000) == 0x7000) {
cursor_image &= 0x8fff;
if(!(cursor_image & 0x0700))
@ -2123,9 +2125,15 @@ draw_cursor(scr_stat *scp)
if ((cursor_image & 0x0f00) == 0x0700)
cursor_image &= 0xf8ff;
}
*(Crtat+(cur_console->cursor_pos-cur_console->scr_buf)) = cursor_image;
*(Crtat + (cur_console->cursor_pos - cur_console->scr_buf)) =
cursor_image;
scp->status |= CURSOR_SHOWN;
}
if (!show && (scp->status & CURSOR_SHOWN)) {
*(Crtat+(scp->cursor_pos-scp->scr_buf)) = scp->cursor_saveunder;
scp->status &= ~CURSOR_SHOWN;
}
}
static void
ansi_put(scr_stat *scp, u_char *buf, int len)
@ -2191,8 +2199,15 @@ ansi_put(scr_stat *scp, u_char *buf, int len)
scp->xpos = 0;
break;
case '\t': /* non-destructive tab */
scp->cursor_pos += (8 - scp->xpos % 8);
scp->xpos += (8 - scp->xpos % 8);
{
int i = 8 - scp->xpos % 8u;
scp->cursor_pos += i;
if ((scp->xpos += i) >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
}
}
break;
}
ptr++; len--;
@ -2360,7 +2375,7 @@ scput(u_char c)
current_default = &kernel_default;
scp->status &= ~CURSOR_ENABLED;
ansi_put(scp, &c, 1);
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= (CURSOR_ENABLED | UPDATE_SCREEN);
kernel_console = scp->term;
current_default = &user_default;
scp->term = save;
@ -2406,11 +2421,13 @@ history_to_screen(scr_stat *scp)
{
int i;
scp->status &= ~UPDATE_SCREEN;
for (i=0; i<scp->ysize; i++)
bcopyw(scp->history + (((scp->history_pos - scp->history) +
scp->history_size-((i+1)*scp->xsize))%scp->history_size),
Crtat + (scp->xsize * (scp->ysize-1 - i)),
scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
scp->xsize * sizeof(u_short));
scp->status |= UPDATE_SCREEN;
}
static int
@ -2451,7 +2468,6 @@ scgetc(int noblock)
struct key_t *key;
static u_char esc_flag = 0, compose = 0;
static u_int chr = 0;
static u_short *saved_history_head;
next_code:
kbd_wait();
@ -2582,10 +2598,9 @@ scgetc(int noblock)
cur_console->status &= ~CURSOR_ENABLED;
if (!(cur_console->status & BUFFER_SAVED)) {
cur_console->status &= ~UPDATE_NEEDED;
cur_console->status |= BUFFER_SAVED;
saved_history_head = cur_console->history_head;
/* copy scp->ysize line into history */
cur_console->history_save = cur_console->history_head;
/* copy screen into top of history buffer */
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->scr_buf + (cur_console->xsize * i),
cur_console->history_head,
@ -2763,15 +2778,17 @@ scgetc(int noblock)
if (cur_console->status & SLKED) {
cur_console->status &= ~SLKED;
if (cur_console->status & BUFFER_SAVED){
bcopyw(cur_console->scr_buf, Crtat,
cur_console->xsize *
cur_console->ysize *
sizeof(u_short));
int i;
for (i=0; i<cur_console->ysize; i++) {
bcopyw(cur_console->history_save+(cur_console->xsize*i),
cur_console->scr_buf + (cur_console->xsize * i),
cur_console->xsize * sizeof(u_short));
}
cur_console->status&=~BUFFER_SAVED;
cur_console->history_head =
saved_history_head;
cur_console->history_save;
cur_console->status |=
(CURSOR_ENABLED|UPDATE_NEEDED);
(CURSOR_ENABLED|UPDATE_SCREEN);
}
scstart(VIRTUAL_TTY(get_scr_num()));
}
@ -3154,17 +3171,6 @@ copy_font(int operation, int font_type, char* font_image)
outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
}
static void
undraw_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
*(crt_pos) = *(scp->mouse_pos);
*(crt_pos+1) = *(scp->mouse_pos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize);
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1);
}
static void
draw_mouse_image(scr_stat *scp)
{
@ -3198,18 +3204,13 @@ draw_mouse_image(scr_stat *scp)
break;
}
scp->mouse_saveunder[0] = *(crt_pos);
scp->mouse_saveunder[1] = *(crt_pos+1);
scp->mouse_saveunder[2] = *(crt_pos+scp->xsize);
scp->mouse_saveunder[3] = *(crt_pos+scp->xsize+1);
bcopyw(font_buffer+((scp->mouse_saveunder[0] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos) & 0xff)*font_size),
&scp->mouse_cursor[0], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[1] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+1) & 0xff)*font_size),
&scp->mouse_cursor[32], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[2] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize) & 0xff)*font_size),
&scp->mouse_cursor[64], font_size);
bcopyw(font_buffer+((scp->mouse_saveunder[3] & 0xff)*font_size),
bcopyw(font_buffer+((*(scp->mouse_pos+scp->xsize+1) & 0xff)*font_size),
&scp->mouse_cursor[96], font_size);
for (i=0; i<font_size; i++) {
@ -3230,12 +3231,38 @@ draw_mouse_image(scr_stat *scp)
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
}
/*
* if we didn't update entire screen, restore old mouse position
* and check if we overwrote the cursor location..
*/
if ((scp->status & UPDATE_MOUSE) && !(scp->status & UPDATE_SCREEN)) {
u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
if (crt_pos != scp->mouse_oldpos) {
*(scp->mouse_oldpos) = scp->mouse_saveunder[0];
*(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
*(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
*(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
}
scp->mouse_saveunder[0] = *(scp->mouse_pos);
scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
if ((scp->cursor_pos == (ptr)) ||
(scp->cursor_pos == (ptr+1)) ||
(scp->cursor_pos == (ptr+scp->xsize)) ||
(scp->cursor_pos == (ptr+scp->xsize+1)) ||
(scp->cursor_pos == (scp->mouse_pos)) ||
(scp->cursor_pos == (scp->mouse_pos+1)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
scp->status &= ~CURSOR_SHOWN;
}
scp->mouse_oldpos = crt_pos;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
*(crt_pos) = (scp->mouse_saveunder[0]&0xff00)|0xc0;
*(crt_pos+1) = (scp->mouse_saveunder[1]&0xff00)|0xc1;
*(crt_pos+scp->xsize) = (scp->mouse_saveunder[2]&0xff00)|0xc2;
*(crt_pos+scp->xsize+1) = (scp->mouse_saveunder[3]&0xff00)|0xc3;
*(crt_pos) = *(scp->mouse_pos)&0xff00|0xc0;
*(crt_pos+1) = *(scp->mouse_pos+1)&0xff00|0xc1;
*(crt_pos+scp->xsize) = *(scp->mouse_pos+scp->xsize)&0xff00|0xc2;
*(crt_pos+scp->xsize+1) = *(scp->mouse_pos+scp->xsize+1)&0xff00|0xc3;
set_font_mode();
bcopy(scp->mouse_cursor,
(char *)pa_to_va(address) + 0xc0 * 32, 128);
@ -3273,7 +3300,6 @@ do_bell(scr_stat *scp, int pitch, int duration)
if (configuration & VISUAL_BELL) {
if (blink_in_progress)
return;
scp->status &= ~CURSOR_ENABLED;
blink_in_progress = 4;
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
@ -3296,7 +3322,7 @@ blink_screen(scr_stat *scp)
timeout((timeout_func_t)blink_screen, scp, hz/10);
}
else {
scp->status |= (CURSOR_ENABLED | UPDATE_NEEDED);
scp->status |= UPDATE_SCREEN;
blink_in_progress = FALSE;
}
}