{
  "id": "terminal-csi/dsr",
  "family": "terminal-csi",
  "slug": "dsr",
  "title": "CSI DSR — Device Status Report (incl. CPR)",
  "summary": "DSR (final 'n') asks the terminal for status. CSI 5 n requests operating status; the terminal replies CSI 0 n ('OK'). CSI 6 n is the Cursor Position Report request (CPR); the terminal replies CSI Pl ; Pc R with the current row;column. The DEC-private form CSI ? 6 n (DECXCPR) additionally reports the page number.",
  "kind": "control-sequence",
  "aliases": [
    "DSR",
    "CPR",
    "device status report",
    "cursor position report",
    "ESC [ 6 n"
  ],
  "status": "standard",
  "verification": "verified",
  "tier": "B",
  "source_url": "https://invisible-island.net/xterm/ctlseqs/ctlseqs.html",
  "source_version": "xterm ctlseqs, patch #410, 2026/04/19",
  "retrieved_date": "2026-05-29",
  "attribution": [
    {
      "claim_ref": "#summary",
      "source_url": "https://invisible-island.net/xterm/ctlseqs/ctlseqs.html",
      "source_version": "xterm patch #410, 2026/04/19",
      "note": "xterm ctlseqs: CSI Ps n = Device Status Report (DSR): Ps = 5 -> reply CSI 0 n (OK); Ps = 6 -> Report Cursor Position (CPR) as CSI r ; c R. DEC private CSI ? 6 n = DECXCPR."
    },
    {
      "claim_ref": "ext.params",
      "source_url": "https://ecma-international.org/publications-and-standards/standards/ecma-48/",
      "source_version": "ECMA-48 5th ed. 1991 (ISO/IEC 6429), clause 8.3.35 (DSR) and 8.3.14 (CPR)",
      "note": "ECMA-48 defines DSR (final 'n') and CPR (final 'R'); CPR reports active line then column."
    }
  ],
  "see_also": [
    "terminal-csi/cup",
    "terminal-csi/da"
  ],
  "ext_type": "terminal-escape@1",
  "ext": {
    "csi_or_osc": "CSI",
    "command_number": "DSR",
    "frame": {
      "introducer_7bit": "\u001b[",
      "introducer_7bit_readable": "ESC [ (0x1B 0x5B)",
      "introducer_8bit": "",
      "introducer_8bit_readable": "0x9B (single-byte CSI, 8-bit C1)",
      "note": "CSI + Ps + final byte 'n' (0x6E) for the request; replies use 'n' (status) or 'R' (CPR). DEC-private requests prefix '?'."
    },
    "terminator": "none",
    "terminator_detail": {
      "note": "No string terminator; the CSI sequence ends at its final byte. Parameters Ps are decimal, ';' (0x3B) separated."
    },
    "params": [
      {
        "id": "status",
        "anchor": "#status",
        "name": "DSR 5 — operating status",
        "meaning": "CSI 5 n requests operating status; a healthy terminal replies CSI 0 n (no malfunction).",
        "required": true,
        "byte_sequence_ST": "\u001b[5n",
        "byte_sequence_ST_readable": "ESC [ 5 n   ==  \\x1b[5n   (request status; reply \\x1b[0n)",
        "subparams": []
      },
      {
        "id": "cpr",
        "anchor": "#cpr",
        "name": "DSR 6 — Cursor Position Report (CPR)",
        "meaning": "CSI 6 n requests the cursor position; the terminal replies CSI Pl ; Pc R with the 1-based row and column.",
        "required": true,
        "byte_sequence_ST": "\u001b[6n",
        "byte_sequence_ST_readable": "ESC [ 6 n   ==  \\x1b[6n   (request CPR; reply e.g. \\x1b[12;40R)",
        "subparams": []
      },
      {
        "id": "decxcpr",
        "anchor": "#decxcpr",
        "name": "DECXCPR — CSI ? 6 n",
        "meaning": "CSI ? 6 n (DEC private) requests an extended CPR; the terminal replies CSI ? Pl ; Pc ; Pp R including the page number Pp.",
        "required": false,
        "byte_sequence_ST": "\u001b[?6n",
        "byte_sequence_ST_readable": "ESC [ ? 6 n   ==  \\x1b[?6n   (reply \\x1b[?row;col;pageR)",
        "subparams": []
      }
    ],
    "gotchas": [
      "The CPR reply (CSI r ; c R) arrives on the terminal's INPUT stream; you must read from the tty and parse it, ideally with a timeout, or your program can block forever if no reply comes.",
      "CPR coordinates in the reply are 1-based, matching CUP.",
      "Querying CPR is the portable way to discover the cursor row/column (e.g. to detect terminal height by moving to row 999 then reading back).",
      "The DEC-private form (CSI ? 6 n / DECXCPR) reply is prefixed with '?' and includes a page number; a parser expecting the plain CPR form may choke on it.",
      "Some DSR sub-values (e.g. printer status CSI ? 15 n) are DEC/printer-specific and rarely implemented."
    ],
    "v1_smoke_test": {
      "asserts": "DSR 5 (status), DSR 6 (CPR), and DEC-private CSI ? 6 n render as byte-exact CSI sequences; reply forms documented.",
      "behavioral_conformance": "deferred to v2."
    }
  },
  "updated": "2026-05-29T00:00:00Z"
}
