1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 45*7c478bd9Sstevel@tonic-gate #include "curses_inc.h" 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate /* 48*7c478bd9Sstevel@tonic-gate * Cursor motion optimization routine. This routine takes as parameters 49*7c478bd9Sstevel@tonic-gate * the screen positions that the cursor is currently at, and the position 50*7c478bd9Sstevel@tonic-gate * you want it to be at, and it will move the cursor there very 51*7c478bd9Sstevel@tonic-gate * efficiently. It isn't really optimal, since several approximations 52*7c478bd9Sstevel@tonic-gate * are taken in the interests of efficiency and simplicity. The code 53*7c478bd9Sstevel@tonic-gate * here considers directly addressing the cursor, and also considers 54*7c478bd9Sstevel@tonic-gate * local motions using left, right, up, down, tabs, backtabs, vertical 55*7c478bd9Sstevel@tonic-gate * and horizontal addressing, and parameterized motions. It does not 56*7c478bd9Sstevel@tonic-gate * consider using home down, or taking advantage of automatic margins on 57*7c478bd9Sstevel@tonic-gate * any of the four directions. (Two of these directions, left and right, 58*7c478bd9Sstevel@tonic-gate * are well defined by the am and bw capabilities, but up and down are 59*7c478bd9Sstevel@tonic-gate * not defined, nor are tab or backtab off the ends.) 60*7c478bd9Sstevel@tonic-gate * 61*7c478bd9Sstevel@tonic-gate * General strategies considered: 62*7c478bd9Sstevel@tonic-gate * CA Direct Cursor Addressing 63*7c478bd9Sstevel@tonic-gate * LM Local Motions from the old position 64*7c478bd9Sstevel@tonic-gate * HR Home + Local Motions from upper left corner 65*7c478bd9Sstevel@tonic-gate * HDR Home Down + Local Motions from lower left corner 66*7c478bd9Sstevel@tonic-gate * CR CR + Local Motions from left margin 67*7c478bd9Sstevel@tonic-gate * 68*7c478bd9Sstevel@tonic-gate * Local Motions can include 69*7c478bd9Sstevel@tonic-gate * Up cuu, cuu1, vpa 70*7c478bd9Sstevel@tonic-gate * Down cud, cud1, vpa 71*7c478bd9Sstevel@tonic-gate * Left cul, cul1, hpa, bs, cbt 72*7c478bd9Sstevel@tonic-gate * Right cuf, cuf1, hpa, tab, char moved over 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate /* This is called _ISMARK2 so it doesn't conflict with _ISMARK1 in wrefresh.c */ 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate #define _ISMARK2(x) (mks[(x) / BITSPERBYTE] & (1<<((x) % BITSPERBYTE))) 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate #define H_UP -1 80*7c478bd9Sstevel@tonic-gate #define H_DO 1 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate static int Newy; 83*7c478bd9Sstevel@tonic-gate static int _homefirst(int, int, int, int), 84*7c478bd9Sstevel@tonic-gate _mvrel(int, int, int, int, int), 85*7c478bd9Sstevel@tonic-gate _mvvert(int, int, int), _mvhor(int, int, int), 86*7c478bd9Sstevel@tonic-gate _mvright(int, int, int), _mvleft(int, int, int); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate int 89*7c478bd9Sstevel@tonic-gate mvcur(int cury, int curx, int newy, int newx) 90*7c478bd9Sstevel@tonic-gate { 91*7c478bd9Sstevel@tonic-gate int hu, /* cost home + relative */ 92*7c478bd9Sstevel@tonic-gate hd, /* cost home-down + relative */ 93*7c478bd9Sstevel@tonic-gate rl, /* cost relative */ 94*7c478bd9Sstevel@tonic-gate cm; /* cost direct cursor motion */ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* obvious case */ 97*7c478bd9Sstevel@tonic-gate if (cury == newy && curx == newx) 98*7c478bd9Sstevel@tonic-gate return (OK); 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate /* not in the right mode for cursor movement */ 101*7c478bd9Sstevel@tonic-gate if (SP->fl_endwin) 102*7c478bd9Sstevel@tonic-gate return (ERR); 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate if (!move_standout_mode && curscr->_attrs && !SP->_mks) 105*7c478bd9Sstevel@tonic-gate _VIDS(A_NORMAL, curscr->_attrs); 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate if (!move_insert_mode && SP->phys_irm) 108*7c478bd9Sstevel@tonic-gate _OFFINSERT(); 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate Newy = newy; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* cost of using cm */ 113*7c478bd9Sstevel@tonic-gate cm = _COST(Cursor_address); 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate rl = hd = hu = LARGECOST; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* baudrate optimization */ 118*7c478bd9Sstevel@tonic-gate if (cm < LARGECOST && SP->baud >= 2400 && 119*7c478bd9Sstevel@tonic-gate cury >= 0 && cury < curscr->_maxy && 120*7c478bd9Sstevel@tonic-gate curx >= 0 && curx < curscr->_maxx) { 121*7c478bd9Sstevel@tonic-gate if (cursor_down && (newy == (cury + 1)) && 122*7c478bd9Sstevel@tonic-gate ((newx == curx) || (newx == 0 && carriage_return))) { 123*7c478bd9Sstevel@tonic-gate if (newx != curx) 124*7c478bd9Sstevel@tonic-gate _PUTS(carriage_return, 1); 125*7c478bd9Sstevel@tonic-gate _PUTS(cursor_down, 1); 126*7c478bd9Sstevel@tonic-gate goto done; 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate /* fast horizontal move */ 130*7c478bd9Sstevel@tonic-gate if (cury == newy && newx < curx - 4 && newx > curx + 4) { 131*7c478bd9Sstevel@tonic-gate if (newx < curx) 132*7c478bd9Sstevel@tonic-gate rl = _mvleft(curx, newx, FALSE); 133*7c478bd9Sstevel@tonic-gate else 134*7c478bd9Sstevel@tonic-gate rl = _mvright(curx, newx, FALSE); 135*7c478bd9Sstevel@tonic-gate if (rl < cm) { 136*7c478bd9Sstevel@tonic-gate if (newx < curx) 137*7c478bd9Sstevel@tonic-gate rl = _mvleft(curx, newx, TRUE); 138*7c478bd9Sstevel@tonic-gate else 139*7c478bd9Sstevel@tonic-gate rl = _mvright(curx, newx, TRUE); 140*7c478bd9Sstevel@tonic-gate goto done; 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* cost using relative movements */ 146*7c478bd9Sstevel@tonic-gate if (rl >= LARGECOST && cury >= 0 && cury < curscr->_maxy && 147*7c478bd9Sstevel@tonic-gate curx >= 0 && curx < curscr->_maxx) 148*7c478bd9Sstevel@tonic-gate rl = _mvrel(cury, curx, newy, newx, FALSE); 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate /* cost of homing to upper-left corner first */ 151*7c478bd9Sstevel@tonic-gate if (cursor_home) 152*7c478bd9Sstevel@tonic-gate hu = _homefirst(newy, newx, H_UP, FALSE); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* cost of homing to lower-left corner first */ 155*7c478bd9Sstevel@tonic-gate if (cursor_to_ll) 156*7c478bd9Sstevel@tonic-gate hd = _homefirst(newy, newx, H_DO, FALSE); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* can't do any one of them */ 159*7c478bd9Sstevel@tonic-gate if (cm >= LARGECOST && rl >= LARGECOST && hu >= LARGECOST && 160*7c478bd9Sstevel@tonic-gate hd >= LARGECOST) 161*7c478bd9Sstevel@tonic-gate return (ERR); 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate /* do the best one */ 164*7c478bd9Sstevel@tonic-gate if (cm <= rl && cm <= hu && cm <= hd) 165*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p2(cursor_address, newy, newx), 1); 166*7c478bd9Sstevel@tonic-gate else 167*7c478bd9Sstevel@tonic-gate if (rl <= hu && rl <= hd) 168*7c478bd9Sstevel@tonic-gate (void) _mvrel(cury, curx, newy, newx, TRUE); 169*7c478bd9Sstevel@tonic-gate else 170*7c478bd9Sstevel@tonic-gate (void) _homefirst(newy, newx, hu <= hd ? 171*7c478bd9Sstevel@tonic-gate H_UP : H_DO, TRUE); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate done: 174*7c478bd9Sstevel@tonic-gate /* update cursor position */ 175*7c478bd9Sstevel@tonic-gate /*LINTED*/ 176*7c478bd9Sstevel@tonic-gate curscr->_curx = (short) newx; 177*7c478bd9Sstevel@tonic-gate /*LINTED*/ 178*7c478bd9Sstevel@tonic-gate curscr->_cury = (short) newy; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate return (OK); 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* Move by homing first. */ 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate static int 186*7c478bd9Sstevel@tonic-gate _homefirst(int ny, int nx, int type, int doit) 187*7c478bd9Sstevel@tonic-gate { 188*7c478bd9Sstevel@tonic-gate char *home; 189*7c478bd9Sstevel@tonic-gate int cy, cost; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate if (type == H_UP) { 192*7c478bd9Sstevel@tonic-gate home = cursor_home; 193*7c478bd9Sstevel@tonic-gate cost = _COST(Cursor_home); 194*7c478bd9Sstevel@tonic-gate cy = 0; 195*7c478bd9Sstevel@tonic-gate } else { 196*7c478bd9Sstevel@tonic-gate home = cursor_to_ll; 197*7c478bd9Sstevel@tonic-gate cost = _COST(Cursor_to_ll); 198*7c478bd9Sstevel@tonic-gate cy = curscr->_maxy - 1; 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate if (!home) 202*7c478bd9Sstevel@tonic-gate return (LARGECOST); 203*7c478bd9Sstevel@tonic-gate if (!doit) 204*7c478bd9Sstevel@tonic-gate return (cost + _mvrel(cy, 0, ny, nx, FALSE)); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate _PUTS(home, 1); 207*7c478bd9Sstevel@tonic-gate return (_mvrel(cy, 0, ny, nx, TRUE)); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* Move relatively */ 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate static int 213*7c478bd9Sstevel@tonic-gate _mvrel(int cy, int cx, int ny, int nx, int doit) 214*7c478bd9Sstevel@tonic-gate { 215*7c478bd9Sstevel@tonic-gate int cv, ch; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* do in this order since _mvhor may need the curscr image */ 218*7c478bd9Sstevel@tonic-gate cv = _mvvert(cy, ny, doit); 219*7c478bd9Sstevel@tonic-gate ch = _mvhor(cx, nx, doit); 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate return (cv + ch); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* Move vertically */ 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate static int 227*7c478bd9Sstevel@tonic-gate _mvvert(int cy, int ny, int doit) 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate char *ve; 230*7c478bd9Sstevel@tonic-gate int dy, st_1, st_n, cv; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (cy == ny) 233*7c478bd9Sstevel@tonic-gate goto out; 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* cost of stepwise movement */ 236*7c478bd9Sstevel@tonic-gate if (cy < ny) { 237*7c478bd9Sstevel@tonic-gate dy = ny-cy; 238*7c478bd9Sstevel@tonic-gate st_1 = _COST(Cursor_down) * dy; 239*7c478bd9Sstevel@tonic-gate st_n = _COST(Parm_down_cursor); 240*7c478bd9Sstevel@tonic-gate } else { 241*7c478bd9Sstevel@tonic-gate dy = cy-ny; 242*7c478bd9Sstevel@tonic-gate st_1 = _COST(Cursor_up) * dy; 243*7c478bd9Sstevel@tonic-gate st_n = _COST(Parm_up_cursor); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* cost of using vertical move */ 247*7c478bd9Sstevel@tonic-gate cv = _COST(Row_address); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* if calculating cost only */ 250*7c478bd9Sstevel@tonic-gate if (!doit) 251*7c478bd9Sstevel@tonic-gate return ((cv < st_1 && cv < st_n) ? cv : 252*7c478bd9Sstevel@tonic-gate (st_n < st_1) ? st_n : st_1); 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate /* do it */ 255*7c478bd9Sstevel@tonic-gate if (cv < st_1 && cv < st_n) 256*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(row_address, ny), 1); 257*7c478bd9Sstevel@tonic-gate else 258*7c478bd9Sstevel@tonic-gate if (st_n < st_1) { 259*7c478bd9Sstevel@tonic-gate if (cy < ny) 260*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_down_cursor, dy), 1); 261*7c478bd9Sstevel@tonic-gate else 262*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_up_cursor, dy), 1); 263*7c478bd9Sstevel@tonic-gate } else { 264*7c478bd9Sstevel@tonic-gate if (cy < ny) 265*7c478bd9Sstevel@tonic-gate ve = cursor_down; 266*7c478bd9Sstevel@tonic-gate else 267*7c478bd9Sstevel@tonic-gate ve = cursor_up; 268*7c478bd9Sstevel@tonic-gate for (; dy > 0; --dy) 269*7c478bd9Sstevel@tonic-gate _PUTS(ve, 1); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate out: 273*7c478bd9Sstevel@tonic-gate return (0); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* Move horizontally */ 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate static int 279*7c478bd9Sstevel@tonic-gate _mvhor(int cx, int nx, int doit) 280*7c478bd9Sstevel@tonic-gate { 281*7c478bd9Sstevel@tonic-gate int st, ch, hl; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate if (cx == nx) 284*7c478bd9Sstevel@tonic-gate goto out; 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* cost using horizontal move */ 287*7c478bd9Sstevel@tonic-gate ch = _COST(Row_address); 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* cost doing stepwise */ 290*7c478bd9Sstevel@tonic-gate st = cx < nx ? _mvright(cx, nx, FALSE) : _mvleft(cx, nx, FALSE); 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate /* cost homeleft first */ 293*7c478bd9Sstevel@tonic-gate hl = (_COST(Carriage_return) < LARGECOST) ? 294*7c478bd9Sstevel@tonic-gate _COST(Carriage_return) + _mvright(0, nx, FALSE) : LARGECOST; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate if (!doit) 297*7c478bd9Sstevel@tonic-gate return ((ch < st && ch < hl) ? ch : (hl < st ? hl : st)); 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate if (ch < st && ch < hl) 300*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(column_address, nx), 1); 301*7c478bd9Sstevel@tonic-gate else 302*7c478bd9Sstevel@tonic-gate if (hl < st) { 303*7c478bd9Sstevel@tonic-gate _PUTS(carriage_return, 1); 304*7c478bd9Sstevel@tonic-gate (void) _mvright(0, nx, TRUE); 305*7c478bd9Sstevel@tonic-gate } else { 306*7c478bd9Sstevel@tonic-gate if (cx < nx) 307*7c478bd9Sstevel@tonic-gate (void) _mvright(cx, nx, TRUE); 308*7c478bd9Sstevel@tonic-gate else 309*7c478bd9Sstevel@tonic-gate (void) _mvleft(cx, nx, TRUE); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate out: 312*7c478bd9Sstevel@tonic-gate return (0); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* Move right. */ 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate static int 318*7c478bd9Sstevel@tonic-gate _mvright(int cx, int nx, int doit) 319*7c478bd9Sstevel@tonic-gate { 320*7c478bd9Sstevel@tonic-gate chtype *scp; 321*7c478bd9Sstevel@tonic-gate char *mks; 322*7c478bd9Sstevel@tonic-gate int nt, tx, x, stcost, iscont; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate if (!cursor_right && !parm_right_cursor) 325*7c478bd9Sstevel@tonic-gate return (LARGECOST); 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate scp = curscr->_y[Newy]; 328*7c478bd9Sstevel@tonic-gate mks = magic_cookie_glitch >= 0 ? SP->_mks[Newy] : NULL; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate if (cursor_right) { 331*7c478bd9Sstevel@tonic-gate /* number of tabs used in stepwise movement */ 332*7c478bd9Sstevel@tonic-gate nt = tab ? (nx / TABSIZE - cx / TABSIZE) : 0; 333*7c478bd9Sstevel@tonic-gate tx = (nt > 0) ? (cx / TABSIZE + nt) * TABSIZE : cx; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* calculate stepwise cost */ 336*7c478bd9Sstevel@tonic-gate stcost = nt * _COST(Tab); 337*7c478bd9Sstevel@tonic-gate iscont = 0; 338*7c478bd9Sstevel@tonic-gate for (x = tx; x < nx; ++x) { 339*7c478bd9Sstevel@tonic-gate if (iscont == 0 && !ISCBIT(scp[x])) 340*7c478bd9Sstevel@tonic-gate iscont = 1; 341*7c478bd9Sstevel@tonic-gate if ((!ceol_standout_glitch && !mks && 342*7c478bd9Sstevel@tonic-gate _ATTR(scp[x]) == curscr->_attrs) || 343*7c478bd9Sstevel@tonic-gate ceol_standout_glitch || (mks && !_ISMARK2(x))) { 344*7c478bd9Sstevel@tonic-gate if (!ISMBIT(scp[x])) 345*7c478bd9Sstevel@tonic-gate stcost += 1; 346*7c478bd9Sstevel@tonic-gate else if (iscont && !(nx - x == 1 && nx < 347*7c478bd9Sstevel@tonic-gate curscr->_maxx && ISCBIT(scp[nx]))) 348*7c478bd9Sstevel@tonic-gate stcost += 1; 349*7c478bd9Sstevel@tonic-gate else 350*7c478bd9Sstevel@tonic-gate stcost += _COST(Cursor_right); 351*7c478bd9Sstevel@tonic-gate } else 352*7c478bd9Sstevel@tonic-gate stcost += _COST(Cursor_right); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate } else 355*7c478bd9Sstevel@tonic-gate stcost = LARGECOST; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if (!doit) 358*7c478bd9Sstevel@tonic-gate return ((_COST(Parm_right_cursor) < stcost) ? 359*7c478bd9Sstevel@tonic-gate _COST(Parm_right_cursor) : stcost); 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* actually move */ 362*7c478bd9Sstevel@tonic-gate if (_COST(Parm_right_cursor) < stcost) 363*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_right_cursor, nx-cx), 1); 364*7c478bd9Sstevel@tonic-gate else { 365*7c478bd9Sstevel@tonic-gate if (SP->phys_irm) 366*7c478bd9Sstevel@tonic-gate _OFFINSERT(); 367*7c478bd9Sstevel@tonic-gate for (; nt > 0; --nt) 368*7c478bd9Sstevel@tonic-gate _PUTS(tab, 1); 369*7c478bd9Sstevel@tonic-gate iscont = 0; 370*7c478bd9Sstevel@tonic-gate for (x = tx; x < nx; ++x) { 371*7c478bd9Sstevel@tonic-gate if (iscont == 0 && !ISCBIT(scp[x])) 372*7c478bd9Sstevel@tonic-gate iscont = 1; 373*7c478bd9Sstevel@tonic-gate if ((!ceol_standout_glitch && !mks && 374*7c478bd9Sstevel@tonic-gate _ATTR(scp[x]) == curscr->_attrs) || 375*7c478bd9Sstevel@tonic-gate ceol_standout_glitch || (mks && !_ISMARK2(x))) { 376*7c478bd9Sstevel@tonic-gate if (!ISMBIT(scp[x])) 377*7c478bd9Sstevel@tonic-gate (void) _outwch(_CHAR(scp[x])); 378*7c478bd9Sstevel@tonic-gate else if (iscont && !(nx - x == 1 && 379*7c478bd9Sstevel@tonic-gate nx < curscr->_maxx && ISCBIT(scp[nx]))) 380*7c478bd9Sstevel@tonic-gate (void) _outwch(_CHAR(scp[x])); 381*7c478bd9Sstevel@tonic-gate else 382*7c478bd9Sstevel@tonic-gate _PUTS(cursor_right, 1); 383*7c478bd9Sstevel@tonic-gate } else 384*7c478bd9Sstevel@tonic-gate _PUTS(cursor_right, 1); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate return (0); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate /* Move left */ 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate static int 394*7c478bd9Sstevel@tonic-gate _mvleft(int cx, int nx, int doit) 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate int tx, nt, x, stcost; 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (!cursor_left && !parm_left_cursor) 399*7c478bd9Sstevel@tonic-gate return (LARGECOST); 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate if (cursor_left) { 402*7c478bd9Sstevel@tonic-gate /* stepwise cost */ 403*7c478bd9Sstevel@tonic-gate tx = cx; 404*7c478bd9Sstevel@tonic-gate nt = 0; 405*7c478bd9Sstevel@tonic-gate if (back_tab) { 406*7c478bd9Sstevel@tonic-gate /* the TAB position >= nx */ 407*7c478bd9Sstevel@tonic-gate x = (nx % TABSIZE) ? (nx / TABSIZE + 1) * TABSIZE : nx; 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate /* # of tabs used and position after using them */ 410*7c478bd9Sstevel@tonic-gate if (x < cx) { 411*7c478bd9Sstevel@tonic-gate nt = (cx / TABSIZE - x / TABSIZE) + 412*7c478bd9Sstevel@tonic-gate ((cx % TABSIZE) ? 1 : 0); 413*7c478bd9Sstevel@tonic-gate tx = x; 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate stcost = nt * _COST(Back_tab) + (tx-nx) * _COST(Cursor_left); 417*7c478bd9Sstevel@tonic-gate } else 418*7c478bd9Sstevel@tonic-gate stcost = LARGECOST; 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate /* get cost only */ 421*7c478bd9Sstevel@tonic-gate if (!doit) 422*7c478bd9Sstevel@tonic-gate return ((_COST(Parm_left_cursor) < stcost) ? 423*7c478bd9Sstevel@tonic-gate _COST(Parm_left_cursor) : stcost); 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate /* doit */ 426*7c478bd9Sstevel@tonic-gate if (_COST(Parm_left_cursor) < stcost) 427*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_left_cursor, cx - nx), 1); 428*7c478bd9Sstevel@tonic-gate else { 429*7c478bd9Sstevel@tonic-gate for (; nt > 0; --nt) 430*7c478bd9Sstevel@tonic-gate _PUTS(back_tab, 1); 431*7c478bd9Sstevel@tonic-gate for (; tx > nx; --tx) 432*7c478bd9Sstevel@tonic-gate _PUTS(cursor_left, 1); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate return (0); 436*7c478bd9Sstevel@tonic-gate } 437