1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-18 15:26:23 -05:00

Compare commits

...

2 Commits

6 changed files with 659 additions and 735 deletions

View File

@ -44,10 +44,8 @@ static unsigned getgoal( line_p dlp) {
col += 2 ; col += 2 ;
else if( c >= 0x80 && c <= 0xA0) /* \xx */ else if( c >= 0x80 && c <= 0xA0) /* \xx */
col += 3 ; col += 3 ;
else { else
int w = utf8_width( c) ; /* work around */ col += utf8_width( c) ;
col += (w < 0) ? 2 : w ; /* unknown unicode width as \u */
}
if( col > curgoal) if( col > curgoal)
break ; break ;

465
display.c
View File

@ -12,7 +12,6 @@
*/ */
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -28,16 +27,16 @@
#include "utf8.h" #include "utf8.h"
#include "window.h" #include "window.h"
struct video { typedef struct {
int v_flag ; /* Flags */ int v_flag ; /* Flags */
#if COLOR #if COLOR
int v_fcolor; /* current forground color */ int v_fcolor ; /* current foreground color */
int v_bcolor ; /* current background color */ int v_bcolor ; /* current background color */
int v_rfcolor; /* requested forground color */ int v_rfcolor ; /* requested foreground color */
int v_rbcolor ; /* requested background color */ int v_rbcolor ; /* requested background color */
#endif #endif
unicode_t v_text[] ; /* Screen data. */ unicode_t v_text[] ; /* Screen data. */
}; } *video_p ;
#define VFCHG 0x0001 /* Changed flag */ #define VFCHG 0x0001 /* Changed flag */
#define VFEXT 0x0002 /* extended (beyond column 80) */ #define VFEXT 0x0002 /* extended (beyond column 80) */
@ -45,15 +44,16 @@ struct video {
#define VFREQ 0x0008 /* reverse video request */ #define VFREQ 0x0008 /* reverse video request */
#define VFCOL 0x0010 /* color change requested */ #define VFCOL 0x0010 /* color change requested */
static struct video **vscreen; /* Virtual screen. */ static video_p *vscreen ; /* Virtual screen. */
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
static struct video **pscreen; /* Physical screen. */ static video_p *pscreen ; /* Physical screen. */
#endif #endif
static int displaying = TRUE ; static int displaying = TRUE ;
#if UNIX #if UNIX
# include <signal.h> # include <signal.h>
#endif #endif
#ifdef SIGWINCH #ifdef SIGWINCH
# include <sys/ioctl.h> # include <sys/ioctl.h>
/* for window size changes */ /* for window size changes */
@ -73,16 +73,20 @@ int discmd = TRUE ; /* display command flag */
int disinp = TRUE ; /* display input characters (echo) */ int disinp = TRUE ; /* display input characters (echo) */
static int reframe(struct window *wp); static int reframe( window_p wp) ;
static void updone(struct window *wp); static void updone( window_p wp) ;
static void updall(struct window *wp); static void updall( window_p wp) ;
static int scrolls( int inserts) ; static int scrolls( int inserts) ;
static void scrscroll( int from, int to, int count) ; static void scrscroll( int from, int to, int count) ;
static int texttest( int vrow, int prow) ; static int texttest( int vrow, int prow) ;
static int endofline( unicode_t *s, int n) ; static int endofline( unicode_t *s, int n) ;
static void upddex( void) ;
static void updext( void) ; static void updext( void) ;
static int updateline(int row, struct video *vp1, struct video *vp2); static void updgar( void) ;
static void modeline(struct window *wp); static void updpos( void) ;
static int updateline( int row, video_p vp1, video_p vp2) ;
static boolean updupd( boolean force_f) ;
static void modeline( window_p wp) ;
static void mlputi( int i, int r) ; static void mlputi( int i, int r) ;
static void mlputli( long l, int r) ; static void mlputli( long l, int r) ;
static void mlputf( int s) ; static void mlputf( int s) ;
@ -91,28 +95,24 @@ static void mlputs( const char *s) ;
static int newscreensize( int h, int w) ; static int newscreensize( int h, int w) ;
#endif #endif
/*
* Initialize the data structures used by the display code. The edge vectors
* used to access the screens are set up. The operating system's terminal I/O
* channel is set up. All the other things get initialized at compile time.
* The original window has "WFCHG" set, so that it will get completely
* redrawn on the first call to "update".
*/
void vtinit(void)
{
int i;
struct video *vp;
/* Initialize the data structures used by the display code. The edge
vectors used to access the screens are set up. The operating system's
terminal I/O channel is set up. All the other things get initialized at
compile time. The original window has "WFCHG" set, so that it will get
completely redrawn on the first call to "update".
*/
void vtinit( void) {
TTopen() ; /* open the screen */ TTopen() ; /* open the screen */
TTkopen() ; /* open the keyboard */ TTkopen() ; /* open the keyboard */
TTrev( FALSE) ; TTrev( FALSE) ;
vscreen = xmalloc( term.t_maxrow * sizeof( struct video *)) ; vscreen = xmalloc( term.t_maxrow * sizeof( video_p )) ;
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
pscreen = xmalloc( term.t_maxrow * sizeof( struct video *)) ; pscreen = xmalloc( term.t_maxrow * sizeof( video_p )) ;
#endif #endif
for( i = 0 ; i < term.t_maxrow ; ++i) { for( int i = 0 ; i < term.t_maxrow ; ++i) {
vp = xmalloc( sizeof( struct video) + term.t_maxcol * sizeof( unicode_t)) ; video_p vp = xmalloc( sizeof *vp + term.t_maxcol * sizeof( unicode_t)) ;
vp->v_flag = 0 ; vp->v_flag = 0 ;
#if COLOR #if COLOR
vp->v_rfcolor = 7 ; vp->v_rfcolor = 7 ;
@ -120,7 +120,7 @@ void vtinit(void)
#endif #endif
vscreen[ i] = vp ; vscreen[ i] = vp ;
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
vp = xmalloc( sizeof( struct video) + term.t_maxcol * sizeof( unicode_t)) ; vp = xmalloc( sizeof *vp + term.t_maxcol * sizeof( unicode_t)) ;
vp->v_flag = 0 ; vp->v_flag = 0 ;
pscreen[ i] = vp ; pscreen[ i] = vp ;
#endif #endif
@ -129,16 +129,14 @@ void vtinit(void)
#if CLEAN #if CLEAN
/* free up all the dynamically allocated video structures */ /* free up all the dynamically allocated video structures */
void vtfree( void) {
void vtfree(void) for( int i = 0 ; i < term.t_maxrow ; ++i ) {
{
int i;
for( i = 0 ; i < term.t_maxrow; ++i ) {
free( vscreen[ i]) ; free( vscreen[ i]) ;
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
free( pscreen[ i]) ; free( pscreen[ i]) ;
#endif #endif
} }
free( vscreen) ; free( vscreen) ;
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
free( pscreen) ; free( pscreen) ;
@ -146,45 +144,41 @@ void vtfree(void)
} }
#endif #endif
/*
* Clean up the virtual terminal system, in anticipation for a return to the /* Clean up the virtual terminal system, in anticipation for a return to
* operating system. Move down to the last line and clear it out (the next the operating system. Move down to the last line and clear it out (the
* system prompt will be written in the line). Shut down the channel to the next system prompt will be written in the line). Shut down the channel
* terminal. to the terminal.
*/ */
void vttidy(void) void vttidy( void) {
{
mlerase() ; /* ends with movecursor( term.t_nrow, 0) and TTflush() */ mlerase() ; /* ends with movecursor( term.t_nrow, 0) and TTflush() */
TTclose() ; TTclose() ;
TTkclose() ; TTkclose() ;
#ifdef PKCODE #ifdef PKCODE
{ int ret = write( 1, "\r", 1) ;
int ret ;
ret = write( 1, "\r", 1) ;
if( ret != 1) { if( ret != 1) {
/* some error handling here */ /* some error handling here */
} }
}
#endif #endif
} }
/*
* Set the virtual cursor to the specified row and column on the virtual /* Set the virtual cursor to the specified row and column on the virtual
* screen. There is no checking for nonsense values; this might be a good screen. There is no checking for nonsense values; this might be a good
* idea during the early stages. idea during the early stages.
*/ */
static void vtmove( int row, int col) { static void vtmove( int row, int col) {
vtrow = row ; vtrow = row ;
vtcol = col ; vtcol = col ;
} }
/*
* Write a character to the virtual screen. The virtual row and /* Write a character to the virtual screen. The virtual row and column are
* column are updated. If we are not yet on left edge, don't print updated. If we are not yet on left edge, don't print it yet. If the
* it yet. If the line is too long put a "$" in the last column. line is too long put a "$" in the last column.
*
* This routine only puts printing characters into the virtual This routine only puts printing characters into the virtual terminal
* terminal buffers. Only column overflow is checked. buffers. Only column overflow is checked.
*/ */
static void sane_vtputc( unicode_t c) { static void sane_vtputc( unicode_t c) {
@ -216,7 +210,7 @@ static void vtputc( unicode_t c) {
sane_vtputc( '\\') ; sane_vtputc( '\\') ;
sane_vtputc( hex[ c >> 4]) ; sane_vtputc( hex[ c >> 4]) ;
sane_vtputc( hex[ c & 15]) ; sane_vtputc( hex[ c & 15]) ;
} else if( utf8_width( c) < 0) { } else if( _utf8_width( c) < 0) {
sane_vtputc( '\\') ; /* show as non printable */ sane_vtputc( '\\') ; /* show as non printable */
sane_vtputc( 'u') ; sane_vtputc( 'u') ;
} else } else
@ -231,14 +225,14 @@ static int vtputs( const char *s) {
s += utf8_to_unicode( s, 0, 4, &c) ; s += utf8_to_unicode( s, 0, 4, &c) ;
vtputc( c) ; vtputc( c) ;
n += utf8_width( c) ; /* To Do: only works if all printable */ n += utf8_width( c) ;
} }
return n ; return n ;
} }
/*
* Erase from the end of the software cursor to the end of the line on which /* Erase from the end of the software cursor to the end of the line on which
* the software cursor is located. * the software cursor is located.
*/ */
static void vteeol( void) { static void vteeol( void) {
@ -270,9 +264,7 @@ static int scrflags;
boolean force_f ; force update past type ahead? boolean force_f ; force update past type ahead?
*/ */
int update( boolean force_f) { boolean update( boolean force_f) {
struct window *wp;
#if TYPEAH && ! PKCODE #if TYPEAH && ! PKCODE
if( force_f == FALSE && typahead()) if( force_f == FALSE && typahead())
return TRUE ; return TRUE ;
@ -286,37 +278,26 @@ int update( boolean force_f) {
#if SCROLLCODE #if SCROLLCODE
/* first, propagate mode line changes to all instances of /* first, propagate mode line changes to all instances of a buffer displayed
a buffer displayed in more than one window */ * in more than one window */
wp = wheadp; window_p wp ;
while (wp != NULL) { for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
if (wp->w_flag & WFMODE) { if( wp->w_flag & WFMODE
if (wp->w_bufp->b_nwnd > 1) { && wp->w_bufp->b_nwnd > 1)
/* make sure all previous windows have this */ /* make sure all previous windows have this */
struct window *owp; for( window_p owp = wheadp ; owp != NULL ; owp = owp->w_wndp)
owp = wheadp;
while (owp != NULL) {
if( owp->w_bufp == wp->w_bufp) if( owp->w_bufp == wp->w_bufp)
owp->w_flag |= WFMODE ; owp->w_flag |= WFMODE ;
owp = owp->w_wndp;
}
}
}
wp = wp->w_wndp;
}
#endif #endif
/* update any windows that need refreshing */ /* update any windows that need refreshing */
wp = wheadp; for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
while (wp != NULL) {
if( wp->w_flag) { if( wp->w_flag) {
/* if the window has changed, service it */ /* if the window has changed, service it */
reframe( wp) ; /* check the framing */ reframe( wp) ; /* check the framing */
#if SCROLLCODE #if SCROLLCODE
if( wp->w_flag & (WFKILLS | WFINS)) { if( wp->w_flag & (WFKILLS | WFINS)) {
scrflags |= scrflags |= wp->w_flag & (WFINS | WFKILLS) ;
(wp->w_flag & (WFINS | WFKILLS));
wp->w_flag &= ~(WFKILLS | WFINS) ; wp->w_flag &= ~(WFKILLS | WFINS) ;
} }
#endif #endif
@ -333,9 +314,6 @@ int update( boolean force_f) {
wp->w_flag = 0 ; wp->w_flag = 0 ;
wp->w_force = 0 ; wp->w_force = 0 ;
} }
/* on to the next window */
wp = wp->w_wndp;
}
/* recalc the current hardware cursor location */ /* recalc the current hardware cursor location */
updpos() ; updpos() ;
@ -366,14 +344,13 @@ int update( boolean force_f) {
return TRUE ; return TRUE ;
} }
/*
* reframe: /* reframe:
* check to see if the cursor is on in the window * check to see if the cursor is on in the window
* and re-frame it if needed or wanted * and re-frame it if needed or wanted
*/ */
static int reframe(struct window *wp) static int reframe( window_p wp) {
{ line_p lp, lp0 ;
struct line *lp, *lp0;
int i = 0 ; int i = 0 ;
/* if not a requested reframe, check for a needed one */ /* if not a requested reframe, check for a needed one */
@ -455,8 +432,7 @@ static int reframe(struct window *wp)
return TRUE ; return TRUE ;
} }
static void show_line(struct line *lp) static void show_line( line_p lp) {
{
int i = 0, len = llength( lp) ; int i = 0, len = llength( lp) ;
while( i < len) { while( i < len) {
@ -466,24 +442,18 @@ static void show_line(struct line *lp)
} }
} }
/*
* updone: /* updone:
* update the current line to the virtual screen * update the current line to the virtual screen
* *
* struct window *wp; window to update current line in * window_p wp; window to update current line in
*/ */
static void updone(struct window *wp) static void updone( window_p wp) {
{
struct line *lp; /* line to update */
int sline; /* physical screen line to update */
/* search down the line we want */ /* search down the line we want */
lp = wp->w_linep; int sline = wp->w_toprow ; /* physical screen line to update */
sline = wp->w_toprow; line_p lp ;
while (lp != wp->w_dotp) { for( lp = wp->w_linep ; lp != wp->w_dotp ; lp = lforw( lp))
++sline ; ++sline ;
lp = lforw(lp);
}
/* and update the virtual line */ /* and update the virtual line */
vscreen[ sline]->v_flag |= VFCHG ; vscreen[ sline]->v_flag |= VFCHG ;
@ -497,22 +467,17 @@ static void updone(struct window *wp)
vteeol() ; vteeol() ;
} }
/*
* updall: /* updall:
* update all the lines in a window on the virtual screen * update all the lines in a window on the virtual screen
* *
* struct window *wp; window to update lines in * window_p wp; window to update lines in
*/ */
static void updall(struct window *wp) static void updall( window_p wp) {
{
struct line *lp; /* line to update */
int sline; /* physical screen line to update */
/* search down the lines, updating them */ /* search down the lines, updating them */
lp = wp->w_linep; line_p lp = wp->w_linep ; /* line to update */
sline = wp->w_toprow; int sline = wp->w_toprow ; /* physical screen line to update */
while( sline < wp->w_toprow + wp->w_ntrows) { while( sline < wp->w_toprow + wp->w_ntrows) {
/* and update the virtual line */ /* and update the virtual line */
vscreen[ sline]->v_flag |= VFCHG ; vscreen[ sline]->v_flag |= VFCHG ;
vscreen[ sline]->v_flag &= ~VFREQ ; vscreen[ sline]->v_flag &= ~VFREQ ;
@ -531,21 +496,16 @@ static void updall(struct window *wp)
vteeol() ; vteeol() ;
++sline ; ++sline ;
} }
} }
/*
* updpos:
* update the position of the hardware cursor and handle extended
* lines. This is the only update for simple moves.
*/
void updpos(void)
{
struct line *lp;
int i;
/* updpos:
update the position of the hardware cursor and handle extended lines.
This is the only update for simple moves.
*/
static void updpos( void) {
/* find the current row */ /* find the current row */
lp = curwp->w_linep; line_p lp = curwp->w_linep ;
currow = curwp->w_toprow ; currow = curwp->w_toprow ;
while( lp != curwp->w_dotp) { while( lp != curwp->w_dotp) {
++currow ; ++currow ;
@ -554,7 +514,7 @@ void updpos(void)
/* find the current column */ /* find the current column */
curcol = 0 ; curcol = 0 ;
i = 0; int i = 0 ;
while( i < curwp->w_doto) { while( i < curwp->w_doto) {
unicode_t c ; unicode_t c ;
@ -565,10 +525,8 @@ void updpos(void)
curcol += 2 ; /* displayed as ^c */ curcol += 2 ; /* displayed as ^c */
else if( c >= 0x80 && c <= 0xA0) else if( c >= 0x80 && c <= 0xA0)
curcol += 3 ; /* displayed as \xx */ curcol += 3 ; /* displayed as \xx */
else { else
int width = utf8_width( c) ; curcol += utf8_width( c) ; /* non printable are displayed as \u */
curcol += (width < 0) ? 2 : width ; /* non printable are displayed as \u */
}
} }
/* if extended, flag so and update the virtual line image */ /* if extended, flag so and update the virtual line image */
@ -579,26 +537,18 @@ void updpos(void)
lbound = 0 ; lbound = 0 ;
} }
/*
* upddex: /* upddex:
* de-extend any line that deserves it * de-extend any line that deserves it
*/ */
void upddex(void) static void upddex( void) {
{ for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
struct window *wp; line_p lp = wp->w_linep ;
struct line *lp; for( int i = wp->w_toprow ; i < wp->w_toprow + wp->w_ntrows ; i++) {
int i;
wp = wheadp;
while (wp != NULL) {
lp = wp->w_linep;
i = wp->w_toprow;
while (i < wp->w_toprow + wp->w_ntrows) {
if( vscreen[ i]->v_flag & VFEXT) { if( vscreen[ i]->v_flag & VFEXT) {
if ((wp != curwp) || (lp != wp->w_dotp) || if( (wp != curwp)
(curcol < term.t_ncol - 1)) { || (lp != wp->w_dotp)
|| (curcol < term.t_ncol - 1)) {
vtmove( i, 0) ; vtmove( i, 0) ;
show_line( lp) ; show_line( lp) ;
vteeol() ; vteeol() ;
@ -608,25 +558,19 @@ void upddex(void)
vscreen[ i]->v_flag |= VFCHG ; vscreen[ i]->v_flag |= VFCHG ;
} }
} }
lp = lforw( lp) ; lp = lforw( lp) ;
++i;
} }
/* and onward to the next window */
wp = wp->w_wndp;
} }
} }
/*
* updgar: /* updgar:
* if the screen is garbage, clear the physical screen and * if the screen is garbage, clear the physical screen and
* the virtual screen and force a full update * the virtual screen and force a full update
*/ */
void updgar(void) static void updgar( void) {
{ for( int i = 0 ; i < term.t_nrow ; ++i) {
unicode_t *txt;
int i, j;
for (i = 0; i < term.t_nrow; ++i) {
vscreen[ i]->v_flag |= VFCHG ; vscreen[ i]->v_flag |= VFCHG ;
#if REVSTA #if REVSTA
vscreen[ i]->v_flag &= ~VFREV ; vscreen[ i]->v_flag &= ~VFREV ;
@ -636,14 +580,14 @@ void updgar(void)
vscreen[ i]->v_bcolor = gbcolor ; vscreen[ i]->v_bcolor = gbcolor ;
#endif #endif
#if MEMMAP == 0 || SCROLLCODE #if MEMMAP == 0 || SCROLLCODE
txt = pscreen[i]->v_text; unicode_t *txt = pscreen[ i]->v_text ;
for (j = 0; j < term.t_ncol; ++j) for( int j = 0 ; j < term.t_ncol ; ++j)
txt[ j] = ' ' ; txt[ j] = ' ' ;
#endif #endif
} }
movecursor( 0, 0) ; /* Erase the screen. */ movecursor( 0, 0) ; /* Erase the screen. */
(*term.t_eeop) (); term.t_eeop() ;
sgarbf = FALSE ; /* Erase-page clears */ sgarbf = FALSE ; /* Erase-page clears */
mpresf = FALSE ; /* the message area. */ mpresf = FALSE ; /* the message area. */
#if COLOR #if COLOR
@ -651,32 +595,30 @@ void updgar(void)
#endif #endif
} }
/*
* updupd: /* updupd:
* update the physical screen from the virtual screen * update the physical screen from the virtual screen
* *
* int force; forced update flag * int force; forced update flag
*/ */
int updupd(int force) static boolean updupd( boolean force_f) {
{
struct video *vp1;
int i;
#if SCROLLCODE #if SCROLLCODE
if( scrflags & WFKILLS) if( scrflags & WFKILLS)
scrolls( FALSE) ; scrolls( FALSE) ;
if( scrflags & WFINS) if( scrflags & WFINS)
scrolls( TRUE) ; scrolls( TRUE) ;
scrflags = 0 ; scrflags = 0 ;
#endif #endif
for (i = 0; i < term.t_nrow; ++i) { for( int i = 0 ; i < term.t_nrow ; ++i) {
vp1 = vscreen[i]; video_p vp1 = vscreen[ i] ;
/* for each line that needs to be updated */ /* for each line that needs to be updated */
if( (vp1->v_flag & VFCHG) != 0) { if( (vp1->v_flag & VFCHG) != 0) {
#if TYPEAH && ! PKCODE #if TYPEAH && ! PKCODE
if (force == FALSE && typahead()) if( force_f == FALSE && typahead())
return TRUE ; return TRUE ;
#endif #endif
#if MEMMAP && ! SCROLLCODE #if MEMMAP && ! SCROLLCODE
@ -686,44 +628,39 @@ int updupd(int force)
#endif #endif
} }
} }
return TRUE ; return TRUE ;
} }
#if SCROLLCODE #if SCROLLCODE
/* /* optimize out scrolls (line breaks, and newlines)
* optimize out scrolls (line breaks, and newlines)
* arg. chooses between looking for inserts or deletes * arg. chooses between looking for inserts or deletes
* returns true if it does something
*/ */
static int scrolls(int inserts) static int scrolls( int inserts) {
{ /* returns true if it does something */
struct video *vpv; /* virtual screen image */
struct video *vpp; /* physical screen image */
int i, j, k ; int i, j, k ;
int rows, cols; int count, target, end ;
int first, match, count, target, end; int to ;
int longmatch, longcount;
int from, to;
if( !term.t_scroll) /* no way to scroll */ if( !term.t_scroll) /* no way to scroll */
return FALSE ; return FALSE ;
rows = term.t_nrow; int rows = term.t_nrow ;
cols = term.t_ncol; int cols = term.t_ncol ;
first = -1; for( i = 0 ; i < rows ; i++) /* find first wrong line */
for (i = 0; i < rows; i++) { /* find first wrong line */ if( !texttest( i, i))
if (!texttest(i, i)) {
first = i;
break ; break ;
}
}
if (first < 0) if( i == rows) /* no text changes */
return FALSE; /* no text changes */ return FALSE ;
vpv = vscreen[first]; int first = i ;
vpp = pscreen[first];
video_p vpv = vscreen[ first] ;
video_p vpp = pscreen[ first] ;
if( inserts) { if( inserts) {
/* determine types of potential scrolls */ /* determine types of potential scrolls */
@ -739,10 +676,10 @@ static int scrolls(int inserts)
} }
/* find the matching shifted area */ /* find the matching shifted area */
match = -1; int match = -1 ;
longmatch = -1; int longmatch = -1 ;
longcount = 0; int longcount = 0 ;
from = target; int from = target ;
for( i = from + 1 ; i < rows - longcount /* P.K. */ ; i++) { for( i = from + 1 ; i < rows - longcount /* P.K. */ ; i++) {
if( inserts ? texttest( i, from) : texttest( from, i)) { if( inserts ? texttest( i, from) : texttest( from, i)) {
match = i ; match = i ;
@ -761,6 +698,7 @@ static int scrolls(int inserts)
} }
} }
} }
match = longmatch ; match = longmatch ;
count = longcount ; count = longcount ;
@ -820,31 +758,28 @@ static int scrolls(int inserts)
return FALSE ; return FALSE ;
} }
/* move the "count" lines starting at "from" to "to" */ /* move the "count" lines starting at "from" to "to" */
static void scrscroll(int from, int to, int count) static void scrscroll( int from, int to, int count) {
{
ttrow = ttcol = -1 ; ttrow = ttcol = -1 ;
(*term.t_scroll) (from, to, count); term.t_scroll( from, to, count) ;
} }
/*
* return TRUE on text match /* return TRUE on text match
* *
* int vrow, prow; virtual, physical rows * int vrow, prow; virtual, physical rows
*/ */
static int texttest(int vrow, int prow) static int texttest( int vrow, int prow) {
{ video_p vpv = vscreen[ vrow] ; /* virtual screen image */
struct video *vpv = vscreen[vrow]; /* virtual screen image */ video_p vpp = pscreen[ prow] ; /* physical screen image */
struct video *vpp = pscreen[prow]; /* physical screen image */
return !memcmp( vpv->v_text, vpp->v_text, 4*term.t_ncol) ; return !memcmp( vpv->v_text, vpp->v_text, 4*term.t_ncol) ;
} }
/*
* return the index of the first blank of trailing whitespace /* return the index of the first blank of trailing whitespace */
*/ static int endofline( unicode_t *s, int n) {
static int endofline(unicode_t *s, int n)
{
int i ; int i ;
for( i = n - 1 ; i >= 0 ; i--) for( i = n - 1 ; i >= 0 ; i--)
if( s[ i] != ' ') if( s[ i] != ' ')
@ -854,17 +789,16 @@ static int endofline(unicode_t *s, int n)
#endif /* SCROLLCODE */ #endif /* SCROLLCODE */
/*
* updext: /* updext:
* update the extended line which the cursor is currently * update the extended line which the cursor is currently
* on at a column greater than the terminal width. The line * on at a column greater than the terminal width. The line
* will be scrolled right or left to let the user see where * will be scrolled right or left to let the user see where
* the cursor is * the cursor is
*/ */
static void updext(void) static void updext( void) {
{
int rcursor ; /* real cursor location */ int rcursor ; /* real cursor location */
struct line *lp; /* pointer to current line */ line_p lp ; /* pointer to current line */
/* calculate what column the real cursor will end up in */ /* calculate what column the real cursor will end up in */
rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin ; rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin ;
@ -884,16 +818,15 @@ static void updext(void)
vscreen[ currow]->v_text[ 0] = '$' ; vscreen[ currow]->v_text[ 0] = '$' ;
} }
/*
* Update a single line. This does not know how to use insert or delete /* Update a single line. This does not know how to use insert or delete
* character sequences; we are using VT52 functionality. Update the physical * character sequences; we are using VT52 functionality. Update the physical
* row and column variables. It does try an exploit erase to end of line. * row and column variables. It does try an exploit erase to end of line.
*/ */
#if MEMMAP #if MEMMAP
/* UPDATELINE specific code for the IBM-PC and other compatables */ /* UPDATELINE specific code for the IBM-PC and other compatables */
static int updateline(int row, struct video *vp1, struct video *vp2) static int updateline( int row, video_p vp1, video_p vp2) {
{
#if SCROLLCODE #if SCROLLCODE
unicode_t *cp1 ; unicode_t *cp1 ;
unicode_t *cp2 ; unicode_t *cp2 ;
@ -920,20 +853,17 @@ static int updateline(int row, struct video *vp1, struct video *vp2)
scwrite( row, vp1->v_text, 7, 0) ; scwrite( row, vp1->v_text, 7, 0) ;
#endif #endif
vp1->v_flag &= ~(VFCHG | VFCOL) ; /* flag this line as changed */ vp1->v_flag &= ~(VFCHG | VFCOL) ; /* flag this line as changed */
} }
#else #else
/* /* updateline()
* updateline()
* *
* int row ; row of screen to update * int row ; row of screen to update
* struct video *vp1; virtual screen image * video_p vp1 ; virtual screen image
* struct video *vp2; physical screen image * video_p vp2 ; physical screen image
*/ */
static int updateline(int row, struct video *vp1, struct video *vp2) static int updateline( int row, video_p vp1, video_p vp2) {
{
/* UPDATELINE code for all other versions */ /* UPDATELINE code for all other versions */
unicode_t *cp1 ; unicode_t *cp1 ;
@ -1063,16 +993,15 @@ static int updateline(int row, struct video *vp1, struct video *vp2)
} }
#endif #endif
/*
* Redisplay the mode line for the window pointed to by the "wp". This is the /* Redisplay the mode line for the window pointed to by the "wp". This is the
* only routine that has any idea of how the modeline is formatted. You can * only routine that has any idea of how the modeline is formatted. You can
* change the modeline format by hacking at this routine. Called by "update" * change the modeline format by hacking at this routine. Called by "update"
* any time there is a dirty window. * any time there is a dirty window.
*/ */
static void modeline(struct window *wp) static void modeline( window_p wp) {
{
int n ; /* cursor position count */ int n ; /* cursor position count */
struct buffer *bp; buffer_p bp ;
int i ; /* loop index */ int i ; /* loop index */
int lchar ; /* character to draw line in buffer with */ int lchar ; /* character to draw line in buffer with */
int firstm ; /* is this the first mode? */ int firstm ; /* is this the first mode? */
@ -1148,7 +1077,7 @@ static void modeline(struct window *wp)
} }
{ /* determine if top line, bottom line, or both are visible */ { /* determine if top line, bottom line, or both are visible */
struct line *lp = wp->w_linep; line_p lp = wp->w_linep ;
int rows = wp->w_ntrows ; int rows = wp->w_ntrows ;
char *msg = NULL ; char *msg = NULL ;
char tline[ 6] ; /* buffer for part of mode line */ char tline[ 6] ; /* buffer for part of mode line */
@ -1172,7 +1101,7 @@ static void modeline(struct window *wp)
} }
} }
if( !msg) { if( !msg) {
struct line *lp; line_p lp ;
int numlines, predlines ; int numlines, predlines ;
lp = lforw( bp->b_linep) ; lp = lforw( bp->b_linep) ;
@ -1191,8 +1120,7 @@ static void modeline(struct window *wp)
int ratio = 0 ; int ratio = 0 ;
if( numlines != 0) if( numlines != 0)
ratio = ratio = (100L * predlines) / numlines ;
(100L * predlines) / numlines;
if( ratio > 99) if( ratio > 99)
ratio = 99 ; ratio = 99 ;
@ -1213,9 +1141,8 @@ static void modeline(struct window *wp)
} }
} }
void upmode(void) void upmode( void) { /* update all the mode lines */
{ /* update all the mode lines */ window_p wp ;
struct window *wp;
wp = wheadp ; wp = wheadp ;
while( wp != NULL) { while( wp != NULL) {
@ -1224,13 +1151,12 @@ void upmode(void)
} }
} }
/*
* Send a command to the terminal to move the hardware cursor to row "row" /* Send a command to the terminal to move the hardware cursor to row "row"
* and column "col". The row and column arguments are origin 0. Optimize out * and column "col". The row and column arguments are origin 0. Optimize out
* random calls. Update "ttrow" and "ttcol". * random calls. Update "ttrow" and "ttcol".
*/ */
void movecursor(int row, int col) void movecursor( int row, int col) {
{
if( row != ttrow || col != ttcol) { if( row != ttrow || col != ttcol) {
ttrow = row ; ttrow = row ;
ttcol = col ; ttcol = col ;
@ -1238,8 +1164,8 @@ void movecursor(int row, int col)
} }
} }
/*
* Erase the message line. This is a special routine because the message line /* Erase the message line. This is a special routine because the message line
* is not considered to be part of the virtual screen. It always works * is not considered to be part of the virtual screen. It always works
* immediately; the terminal buffer is flushed via a call to the flusher. * immediately; the terminal buffer is flushed via a call to the flusher.
*/ */
@ -1272,8 +1198,8 @@ static void mlputc( unicode_t c) {
} }
} }
/*
* output a string of output characters /* output a string of output characters
* *
* char *s; string to output * char *s; string to output
*/ */
@ -1283,8 +1209,8 @@ void ostring( const char *s) {
} }
/*
* Write a message into the message line. Keep track of the physical cursor /* Write a message into the message line. Keep track of the physical cursor
* position. A small class of printf like format items is handled. Assumes the * position. A small class of printf like format items is handled. Assumes the
* stack grows down; this assumption is made by the "++" in the argument scan * stack grows down; this assumption is made by the "++" in the argument scan
* loop. Set the "message line" flag TRUE. * loop. Set the "message line" flag TRUE.
@ -1375,8 +1301,8 @@ void mlwrite( const char *fmt, ...) {
va_end( ap) ; va_end( ap) ;
} }
/*
* Write out a string. Update the physical cursor position. This assumes that /* Write out a string. Update the physical cursor position. This assumes that
* the characters in the string all have width "1"; if this is not the case * the characters in the string all have width "1"; if this is not the case
* things will get screwed up a little. * things will get screwed up a little.
*/ */
@ -1393,8 +1319,8 @@ static void mlputs( const char *s) {
} }
} }
/*
* Write out an integer, in the specified radix. Update the physical cursor /* Write out an integer, in the specified radix. Update the physical cursor
* position. * position.
*/ */
static void mlputi( int i, int r) { static void mlputi( int i, int r) {
@ -1417,9 +1343,8 @@ static void mlputi( int i, int r) {
mlputc( hexdigits[ u % r]) ; mlputc( hexdigits[ u % r]) ;
} }
/*
* do the same except as a long integer. /* do the same except as a long integer. */
*/
static void mlputli( long l, int r) { static void mlputli( long l, int r) {
long q ; long q ;
@ -1436,8 +1361,8 @@ static void mlputli( long l, int r) {
mlputc( (int) (l % r) + '0') ; mlputc( (int) (l % r) + '0') ;
} }
/*
* write out a scaled integer with two decimal places /* write out a scaled integer with two decimal places
* *
* int s; scaled integer to output * int s; scaled integer to output
*/ */
@ -1461,8 +1386,7 @@ static void mlputf( int s) {
Store number of lines into *heightp and width into *widthp. Store number of lines into *heightp and width into *widthp.
If zero or a negative number is stored, the value is not valid. */ If zero or a negative number is stored, the value is not valid. */
void getscreensize(int *widthp, int *heightp) void getscreensize( int *widthp, int *heightp) {
{
#ifdef TIOCGWINSZ #ifdef TIOCGWINSZ
struct winsize size ; struct winsize size ;
*widthp = 0 ; *widthp = 0 ;
@ -1478,8 +1402,7 @@ void getscreensize(int *widthp, int *heightp)
} }
#ifdef SIGWINCH #ifdef SIGWINCH
void sizesignal(int signr) void sizesignal( int signr) {
{
int w, h ; int w, h ;
int old_errno = errno ; int old_errno = errno ;
@ -1496,17 +1419,18 @@ void sizesignal(int signr)
errno = old_errno ; errno = old_errno ;
} }
static int newscreensize(int h, int w) static int newscreensize( int h, int w) {
{
/* do the change later */ /* do the change later */
if( displaying) { if( displaying) {
chg_width = w ; chg_width = w ;
chg_height = h ; chg_height = h ;
return FALSE ; return FALSE ;
} }
chg_width = chg_height = 0 ; chg_width = chg_height = 0 ;
if( h <= term.t_mrow) if( h <= term.t_mrow)
newsize( TRUE, h) ; newsize( TRUE, h) ;
if( w <= term.t_mcol) if( w <= term.t_mcol)
newwidth( TRUE, w) ; newwidth( TRUE, w) ;
@ -1516,8 +1440,8 @@ static int newscreensize(int h, int w)
#endif #endif
/*
* output a character when echo is enabled /* output a character when echo is enabled
* *
* char c ; character to output * char c ; character to output
*/ */
@ -1528,8 +1452,8 @@ void echoc( unicode_t c) {
} }
} }
/*
* output a string of characters when display input is enabled /* output a string of characters when display input is enabled
* *
* char *s; string to output * char *s; string to output
*/ */
@ -1543,6 +1467,7 @@ void echos( const char *s) {
} }
} }
void rubout( void) { void rubout( void) {
if( disinp) { if( disinp) {
TTputc( '\b') ; TTputc( '\b') ;

View File

@ -21,11 +21,7 @@ BINDABLE( upscreen) ;
void vtinit( void) ; void vtinit( void) ;
void vtfree( void) ; void vtfree( void) ;
void vttidy( void) ; void vttidy( void) ;
int update( boolean force_f) ; boolean update( boolean force_f) ;
void updpos( void) ;
void upddex( void) ;
void updgar( void) ;
int updupd( int force) ;
void upmode( void) ; void upmode( void) ;
void movecursor( int row, int col) ; void movecursor( int row, int col) ;
void mlerase( void) ; void mlerase( void) ;

View File

@ -164,8 +164,7 @@ int getccol( int bflg) {
else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */ else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */
col += 3 ; col += 3 ;
else { else {
int w = utf8_width( c) ; /* incomplete wc_width */ col += utf8_width( c) ;
col += (w < 0) ? 2 : w ;
} }
} }

21
utf8.c
View File

@ -7,10 +7,9 @@
#include <assert.h> #include <assert.h>
#include <wchar.h> #include <wchar.h>
/*
* Display width of UTF-8 character /* Display width of UTF-8 character */
*/ int _utf8_width( unicode_t c) {
int utf8_width( unicode_t c) {
#if CYGWIN #if CYGWIN
assert( sizeof( wchar_t) == 2) ; /* wcwidth only supports UTF-16 */ assert( sizeof( wchar_t) == 2) ; /* wcwidth only supports UTF-16 */
return (c < 0x10000) ? wcwidth( (wchar_t) c) : -1 ; return (c < 0x10000) ? wcwidth( (wchar_t) c) : -1 ;
@ -19,8 +18,14 @@ int utf8_width( unicode_t c) {
#endif #endif
} }
/*
* utf8_to_unicode() int utf8_width( unicode_t c) {
int w = _utf8_width( c) ;
return (w < 0) ? 2 : w ; /* display \u if can't figure out width */
}
/* utf8_to_unicode()
* *
* Convert a UTF-8 sequence to its unicode value, and return the length of * Convert a UTF-8 sequence to its unicode value, and return the length of
* the sequence in bytes. * the sequence in bytes.
@ -84,8 +89,8 @@ unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
return bytes; return bytes;
} }
/*
* unicode_to_utf8() /* unicode_to_utf8()
* *
* Convert a unicode value to its canonical utf-8 sequence. * Convert a unicode value to its canonical utf-8 sequence.
* *

3
utf8.h
View File

@ -4,7 +4,8 @@
typedef unsigned int unicode_t ; typedef unsigned int unicode_t ;
int utf8_width( unicode_t c) ; int _utf8_width( unicode_t c) ; /* straight width */
int utf8_width( unicode_t c) ; /* workaround width */
unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len, unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
unicode_t *res) ; unicode_t *res) ;
unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ; unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ;