Skip to main content


Contains the current horizontal position of the cursor.




$X contains the current horizontal position of the cursor. As characters are written to a device, Caché updates $X to reflect the horizontal cursor position.

Each printable character that is output increments $X by 1. A carriage return (ASCII 13) or form feed (ASCII 12) resets $X to 0 (zero).

$X is a 16-bit unsigned integer.

  • On non-Unicode systems, $X wraps to 0 when its value reaches 65536. In other words, if $X is 65535, the next output character resets it to 0.

  • On Unicode systems, $X wraps to 0 when its value reaches 16384 (the two remaining bits are used for Japanese pitch encoding).

You can use the SET command to give a value to $X and $Y. For example, you may use special escape sequences that alter the physical cursor position without updating the $X and $Y values. In this case, use SET to assign the correct values to $X and $Y after you use the escape sequences.


NLS Character Mapping

The National Language Support (NLS) utility $X/$Y tab defines the $X and $Y cursor movement characters for the current locale. For further details, refer to the section on “System Classes for National Language Support” in Caché Specialized System Tools and Utilities.

$X with Terminal I/O

The following table shows the effects of different characters on $X.

Echoed Character ASCII Code Effect on $X
<FORM FEED> 12 $X=0
<RETURN> 13 $X=0
<LINE FEED> 10 $X=$X
<TAB> 9 $X=$X+1
Any printable ASCII character 32-126 $X=$X+1
Nonprintable characters (such as escape sequences) 127-255 See Using Caché ObjectScript.

The S(ecret) protocol of the OPEN and USE commands turns off echoing. It also prevents $X from being changed during input, so it indicates the true cursor position.

WRITE $CHAR() changes $X. WRITE * does not change $X. For example, WRITE $X,"/",$CHAR(8),$X performs the backspace (deleting the / character) and resets $X accordingly, returning 01. In contrast, WRITE $X,"/",*8,$X performs the backspace (deleting the / character) but does not reset $X; it returns 02. (See the WRITE command for further details.)

Using WRITE *, you can send a control sequence to your terminal and $X will still reflect the true cursor position. Since some control sequences do move the cursor, you can use the SET command to set $X directly. For example, the following commands move the cursor to column 20 and line 10 on a Digital VT100 terminal (or equivalent) and set $X and $Y accordingly:

   SET dy=10,dx=20
   WRITE *27,*91,dy+1,*59,dx+1,*72
   SET $Y=dy,$X=dx

ANSI standard control sequences (such as escape sequences) that the device acts on but does not output can produce a discrepancy between the $X and $Y values and the true cursor position. To avoid this problem use the WRITE * (integer expression) syntax and specify the ASCII value of each character in the string. For example, instead of using:

   WRITE !,$CHAR(27)_"[1m"
   WRITE !,$X

use this equivalent form:

   WRITE !,*27,*91,*49,*109
   WRITE !,$X

As a rule, after any escape sequence that explicitly moves the cursor, you should update $X and $Y to reflect the actual cursor position.

You can set how $X handles escape sequences for the current process using the DX()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class. The system-wide default behavior can be established by setting the DXOpens in a new tab property of the Config.MiscellaneousOpens in a new tab class.

$X with TCP and Interprocess Communication

When you use the WRITE command to send data to either a client or server TCP device, Caché first stores the data in a buffer. It also updates $X to reflect the number of characters in the buffer. It does not include the ASCII characters <RETURN> and <LINE FEED> in this count because they are considered to be part of the record.

If you flush the $X buffer with the WRITE ! command, Caché resets $X to 0 and increments the $Y value by 1. If you flush the $X and $Y buffers with the WRITE # command, Caché writes the ASCII character <FORM FEED> as a separate record and resets both $X and $Y to 0.

See Also

FeedbackOpens in a new tab