Files
vt1200/xie/xiescheme.c
T
arti 17dfd24340 docs(xie): the VT1200 ROM has no DCT (JPEG) scheme -- measured
The question was whether this ROM answers "unsupported" for XieK_DCT.  It does,
at both layers, and it behaves exactly like an out-of-range scheme value.

SetTransport (minor 20), raw wire request, a fresh bitonal photomap per scheme:
  PCM / G31D / G32D / G42D -> accepted
  DCT (4) and 5            -> BadIDChoice(14), minor_op 20
So the ROM does not even implement the reference server's IsBitonal_ rules
(G42D is accepted on a 256-level photomap, where XieTransport.c would BadMatch),
but it does refuse 4 and above.

Export (minor 21) with the photomap's compression byte forced to each value
(the server never initialises it -- it holds the heap fill 0x55, which is why
harness/mame/xie_fix.lua pokes file 0x1B256):
  0..3 -> pixmap 4096/4096, no X error
  4    -> BadValue, nothing drawn
  5    -> BadValue, nothing drawn

And the ROM carries no JPEG machinery: no "JPEG"/"DCT" string, and the standard
Annex K quantisation table is absent in both zigzag and natural order (no flat
8x8 either).  A DCT codec carries one of those; this ROM carries none.

"DDX_RENDER: unsupported compression scheme" exists in the ROM but did not fire
in these runs, so it belongs to a path these probes do not reach -- recorded as
an open detail rather than claimed as the explanation.

Probes: xie/xiescheme.c (libXie, one scheme per connection) and
xie/xie_schemes_raw.py (raw protocol, exact error codes).
2026-11-01 23:55:27 +02:00

174 lines
6.1 KiB
C

/*
* What does THIS ROM answer for each XieK_ compression scheme?
*
* Built against DEC XIE 2.3 (libXie from DEC's own sources). For every scheme
* value 0..5 it issues a real SetTransport (via XieSetStream) in GetStream mode
* on a bitonal photomap, and then on a grayscale photomap if the server will
* create one -- and reports the protocol error the server returns.
*
* Xlib's default handler exits on an error, so a catching handler is installed.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XieLib.h>
/* the client never calls the DDX dispatch table; satisfy the linker */
unsigned long (*xieDdxProc[1])() = { 0 };
static int last_error;
static int last_req_minor;
static char last_text[64];
static int catch(Display *dpy, XErrorEvent *e)
{
last_error = e->error_code;
last_req_minor = e->minor_code;
XGetErrorText(dpy, e->error_code, last_text, sizeof last_text);
return 0;
}
static const char *scheme_name(int s)
{
switch (s) {
case XieK_PCM: return "PCM ";
case XieK_G31D: return "G31D ";
case XieK_G32D: return "G32D ";
case XieK_G42D: return "G42D ";
case XieK_DCT: return "DCT ";
default: return "5 ";
}
}
/* Create a photomap and push pixel data into it so it is a real image. */
static XiePhotomap make_map(Display *dpy, Window win, int bits, int ncomp,
int cls, const char *tag)
{
XieImage img;
XiePhotomap pm;
unsigned long lvl[3];
unsigned int fill;
int w = 64, h = 64, nbytes;
lvl[0] = lvl[1] = lvl[2] = (unsigned long) bits;
last_error = 0;
img = XieCreateImage((unsigned long) w, (unsigned long) h,
XieK_PCM, (unsigned char) XieK_BandByPlane,
(unsigned char) cls, ncomp, lvl,
(unsigned char) XieK_PP0, (unsigned char) XieK_LP270);
XSync(dpy, False);
if (!img || last_error) {
printf(" [%s] XieCreateImage FAILED err=%d (%s)\n", tag, last_error,
last_error ? last_text : "no error, null handle");
return 0;
}
if (!uBase_(img, 0)) {
nbytes = (int) uArSize_(img, 0);
if (nbytes <= 0) nbytes = (w + 7) / 8 * h;
uBase_(img, 0) = (unsigned char *) calloc(1, (size_t) nbytes);
uArSize_(img, 0) = nbytes;
OwnData_(img) = 1;
}
nbytes = (int) uArSize_(img, 0);
fill = ((bits + 7) / 8) == 1 ? 0xAA : 0x00;
memset(uBase_(img, 0), fill, (size_t) nbytes);
pm = XieCreatePhoto(dpy, XieK_Photomap, (unsigned long) w, (unsigned long) h,
(unsigned char) cls, ncomp, lvl,
(unsigned char) XieK_ZeroDark, 1.0,
(unsigned char) XieK_BandByPlane,
(unsigned char) XieK_BandByPlane);
XSync(dpy, False);
if (!pm || last_error) {
printf(" [%s] XieCreatePhoto FAILED err=%d\n", tag, last_error);
return 0;
}
XiePutTile(pm, img, XieK_AllPlanes, 0, 0, 0, 0,
(unsigned long) w, (unsigned long) h);
XSync(dpy, False);
if (last_error) {
/* SetTransport only needs the photomap to exist, so carry on and let the
* transport test report whatever the server says. */
printf(" [%s] XiePutTile failed err=%d (%s) -- continuing with an empty map\n",
tag, last_error, last_text);
last_error = 0;
}
printf(" [%s] photomap ready (arSize=%d)\n", tag, nbytes);
return pm;
}
static void try_scheme(Display *dpy, XiePhoto pm, int scheme, int mode,
const char *mode_name)
{
int i;
for (i = 0; i < 8; i++) last_text[i] = 0;
last_error = 0;
last_req_minor = -1;
XieSetStream(pm, 0, (unsigned char) mode, (unsigned char) scheme,
0L, (unsigned char) XieK_BandByPlane, 1L, 8L);
XSync(dpy, False);
if (last_error)
printf(" %s in %-9s -> ERROR %d %s (minor %d)\n",
scheme_name(scheme), mode_name, last_error, last_text,
last_req_minor);
else
printf(" %s in %-9s -> ACCEPTED\n", scheme_name(scheme), mode_name);
}
int main(int argc, char **argv)
{
Display *dpy;
Window win;
XSetWindowAttributes swa;
XiePhotomap bm, gm;
const char *disp = argc > 1 ? argv[1] : "192.168.99.2:0";
dpy = XOpenDisplay(disp);
if (!dpy) { fprintf(stderr, "cannot open %s\n", disp); return 1; }
XSetErrorHandler(catch);
printf("display %s, root depth %d\n", disp,
DefaultDepth(dpy, DefaultScreen(dpy)));
swa.background_pixel = 0;
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 150, 200, 64, 64, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWBackPixel, &swa);
XSync(dpy, False);
{
int scheme = argc > 2 ? atoi(argv[2]) : XieK_PCM;
int bits = (argc > 3 && !strcmp(argv[3], "gray")) ? 256 : 2;
int cls = (bits == 2) ? XieK_Bitonal : XieK_GrayScale;
const char *tag = (bits == 2) ? "bitonal" : "gray";
printf("\n--- %s photomap, scheme %s ---\n", tag, scheme_name(scheme));
bm = make_map(dpy, win, bits, 1, cls, tag);
if (bm) {
try_scheme(dpy, bm, scheme, XieK_GetStream, "GetStream");
/* and, if that was accepted, actually ask for the data */
if (!last_error) {
unsigned char *buf = 0;
unsigned long got = 0;
last_error = 0;
printf(" XieSetStream accepted; calling XieGetStream...\n");
XieGetStream(bm, 0, &buf, 65536L, &got);
XSync(dpy, False);
if (last_error)
printf(" XieGetStream -> ERROR %d %s\n", last_error, last_text);
else
printf(" XieGetStream -> ok, %lu bytes, first %02X %02X %02X %02X\n",
got, buf ? buf[0] : 0, buf ? buf[1] : 0,
buf ? buf[2] : 0, buf ? buf[3] : 0);
}
}
}
XCloseDisplay(dpy);
return 0;
}