NetBSD Problem Report #59952
From www@netbsd.org Sat Jan 31 02:27:23 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "R13" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id C525E1A923D
for <gnats-bugs@gnats.NetBSD.org>; Sat, 31 Jan 2026 02:27:23 +0000 (UTC)
Message-Id: <20260131022722.855B51A923E@mollari.NetBSD.org>
Date: Sat, 31 Jan 2026 02:27:22 +0000 (UTC)
From: adrian@freebsd.org
Reply-To: adrian@freebsd.org
To: gnats-bugs@NetBSD.org
Subject: xsetwallpaper: server/client endian mismatch
X-Send-Pr-Version: www-1.0
X-From4GNATS: "adrian@freebsd.org via gnats" <gnats-admin@NetBSD.org>
>Number: 59952
>Category: xsrc
>Synopsis: xsetwallpaper: server/client endian mismatch
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: xsrc-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jan 31 02:30:00 +0000 2026
>Last-Modified: Wed Feb 11 00:10:02 +0000 2026
>Originator: adrian chadd
>Release: 11.99.4
>Organization:
>Environment:
sgimips-r4000$ uname -a
NetBSD sgimips-r4000.home.cacheboy.io 11.99.4 NetBSD 11.99.4 (GENERIC32_IP2x) #0: Mon Jan 12 21:48:13 UTC 2026 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/sgimips/compile/GENERIC32_IP2x sgimips
>Description:
xsetwallpaper assumes the image byte order was decoded into host byte order. however if you run xsetwallpaper on mismatching endian computers - eg amd64 (le) client, sgimips (be) server, then things are corrupted.
>How-To-Repeat:
Do the above: run xsetwallpaper on a different endian client to server.
>Fix:
I did a quick diff that just sets image->byte_order to host endian order so the library/server knows what to do with it.
The alternative solution is to not re-swizzle the endian-ness of the image data and leave it as little-endian.
===
diff --git a/src/xsetwallpaper.c b/src/xsetwallpaper.c
index 8b20050..335acea 100644
--- a/src/xsetwallpaper.c
+++ b/src/xsetwallpaper.c
@@ -104,6 +104,8 @@ main(int argc, char *argv[])
data[i + 2] = p;
}
+ /* At this point it's little endian regardless of host type. */
+
#if _BYTE_ORDER == _BIG_ENDIAN
for (i = 0; i < imagew * imageh * 4; i += 4) {
uint32_t *p = (uint32_t *)&data[i];
@@ -111,6 +113,8 @@ main(int argc, char *argv[])
}
#endif
+ /* It is now in host endian */
+
#ifdef DEBUG
printf("%s: %dx%d %dbpp\n", argv[0], imagew, imageh, imagebpp * 8);
#endif
@@ -168,7 +172,17 @@ main(int argc, char *argv[])
errx(EXIT_FAILURE, "XCreateImage failed");
}
XInitImage(image);
- image->byte_order = byte_order;
+
+ /*
+ * Set the image byte order. Since the above code has converted it
+ * into host endian this will need to be communicated to the display
+ * server so it can re-swizzle if needed.
+ */
+#if _BYTE_ORDER == _BIG_ENDIAN
+ image->byte_order = MSBFirst;
+#else
+ image->byte_order = LSBFirst;
+#endif
/* Create a graphics context for our new pixmap */
gc = XCreateGC(display, window, 0, NULL);
>Audit-Trail:
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sat, 31 Jan 2026 14:30:54 +0300
FWIW, xsetwallpaper photo.jpg DTRT for me when I run it on a
(big-endian) macppc (running 10-stable) host with the display to Xnest
on a (little-endian) linux/amd64.
-uwe
From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sat, 31 Jan 2026 08:51:38 -0800
On Sat, 31 Jan 2026 at 03:35, Valery Ushakov via gnats
<gnats-admin@netbsd.org> wrote:
>
> The following reply was made to PR xsrc/59952; it has been noted by GNATS.
>
> From: Valery Ushakov <uwe@stderr.spb.ru>
> To: gnats-bugs@netbsd.org
> Cc:
> Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
> Date: Sat, 31 Jan 2026 14:30:54 +0300
>
> FWIW, xsetwallpaper photo.jpg DTRT for me when I run it on a
> (big-endian) macppc (running 10-stable) host with the display to Xnest
> on a (little-endian) linux/amd64.
Would you mind adding some printf debugging to see what the image endianness is?
My setup (sgimips/be xserver, amd64/le client) prints that the default
byte_order for the
root window is MSB (big endian), which won't match the little-endian image data.
My diff looks like this (it's from a bigger diff set, but you should
be able to copy/paste
the lines minus the '+' at the beginning into the right place,
recompile and test.)
===
XInitImage(image);
+ printf("byte order: %d (msb=%d lsb=%d)\n",
+ byte_order, MSBFirst, LSBFirst);
===
-adrian
> -uwe
>
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: "Jared D. McNeill" <jmcneill@netbsd.org>
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Sun, 1 Feb 2026 02:10:37 +0300
Ok, I see. The colors where wrong and disabling the big-endian ifdef
makes the image come out right. But in my defense - your report never
really explained properly what you observe and "corrupted" can mean a
lot of different things.
Jared is now having fun with Wii (powerpc), should be easy for him to
reproduce locally :)
-uwe
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 03:41:19 +0300
I'm not sure if the server is guaranteed to handle byte order other
than the ImageByteOrder it announces on the server side. But from a
very quick look it seems that xlib will take care of bswapping the
image as necessary. But instead of relying on someone doing that for
us it might be easier to just provide the image in the right odrder,
as we need to shuffle components anyway.
Something like that? Only very minimally tested.
--- xsetwallpaper.c.~1.4.~ 2026-02-03 00:03:28.073085100 +0300
+++ xsetwallpaper.c 2026-02-04 03:28:37.929559236 +0300
@@ -95,22 +95,6 @@ main(int argc, char *argv[])
data = stbi_load(argv[0], &imagew, &imageh, &imagebpp, 4);
if (data == NULL)
errx(EXIT_FAILURE, "failed to load %s", argv[0]);
-
- /* swap red and blue */
- for (i = 0; i < imagew * imageh * 4; i += 4) {
- uint8_t p;
- p = data[i + 0];
- data[i + 0] = data[i + 2];
- data[i + 2] = p;
- }
-
-#if _BYTE_ORDER == _BIG_ENDIAN
- for (i = 0; i < imagew * imageh * 4; i += 4) {
- uint32_t *p = (uint32_t *)&data[i];
- *p = bswap32(*p);
- }
-#endif
-
#ifdef DEBUG
printf("%s: %dx%d %dbpp\n", argv[0], imagew, imageh, imagebpp * 8);
#endif
@@ -126,6 +110,30 @@ main(int argc, char *argv[])
colormap = DefaultColormap(display, 0);
byte_order = ImageByteOrder(display);
+ /*
+ * stbi loads 4-component image as red, green, blue, alpha -
+ * i.e. little-endian ABGR. We need to provide it to the
+ * server in ARGB in ImageByteOrder(3).
+ */
+ enum { R, G, B, A };
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+# define host_byte_order MSBFirst
+#else
+# define host_byte_order LSBFirst
+#endif
+ uint32_t *data32 = (uint32_t *)data;
+ for (i = 0; i < imagew * imageh; ++i) {
+ uint32_t pixel =
+ data[i*4 + A] << 24
+ | data[i*4 + R] << 16
+ | data[i*4 + G] << 8
+ | data[i*4 + B];
+ if (byte_order != host_byte_order)
+ pixel = bswap32(pixel);
+ data32[i] = pixel;
+ }
+
/* get root window geometry */
if (!XGetGeometry(display, XDefaultRootWindow(display), &window,
&root_x, &root_y, &root_width, &root_height,
-uwe
From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Tue, 3 Feb 2026 17:03:45 -0800
Well, my next diff is handling servers that aren't ARGB. :-P
I'm tempted to lean in here and not bswap at all but let x11 do it. I
believe that's what the API is meant to encourage.
-adrian
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 06:57:11 -0000 (UTC)
gnats-admin@NetBSD.org ("Adrian Chadd via gnats") writes:
> Well, my next diff is handling servers that aren't ARGB. :-P
>
> I'm tempted to lean in here and not bswap at all but let x11 do it. I
> believe that's what the API is meant to encourage.
XCreateImage() gets you an XImage suited for the display and visual.
You then create the pixel data in the appropriate format and
XPutImage() transfers it to the server.
XInitImage() lets you create an XImage yourself for the format you
specify. If the characteristics of the image (for example, byte_order
and bitmap_unit) differ from what the server requires, XPutImage()
makes the necessary conversions.
XImage contains pointers to pixel manipulation functions (that
XInitImage will initialize). So you should not modify the XImage
structure yourself after it is initialized or created by some
Xlib function.
The pixel depth is nothing that could be converted automatically,
operations with different depths always fail with a BadMatch.
You can render a XYBitmap to a deeper display because the XYBitmap
is seen as pixels in background (0-bits) and foreground (1-bits)
color. So there is no depth conversion taking place between pixel
values.
Saying that, automatic conversions was never popular. Any conversion
is slow, especially when done with single pixel operations. The code
I've seen that relied on this was usually handling small pre-rendered
images in a user interface (like button imagery). Everything else would
convert the data once when loading or generating an image and not
every time when it gets rendered for refreshing a window. Something
like xsetwallpaper probably doesn't care, as rendering is done only once.
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 13:28:04 +0300
On Wed, Feb 04, 2026 at 01:05:01 +0000, Adrian Chadd via gnats wrote:
> Well, my next diff is handling servers that aren't ARGB. :-P
I thought about that too, but that's not a rabbit hole I currently
have enough time for.
> I'm tempted to lean in here and not bswap at all but let x11 do it.
> I believe that's what the API is meant to encourage.
I'd rather we handle it explicitly in the xsetwallpaper code. We
almost always need to shuffle the bytes anyway, so it's less cognitive
load on the reader to shuffle it to the order the server wants, than
to shuffle them into some other order and then let some other code
shuffle them some more (doing the work twice, not that xsetwallpaper
is perforamce critical code, as Michael said).
Could you kindly make your extended non-argb patch to go down that
direction?
PS: From a private chat with Jared:
| feel free to commit the fix
-uwe
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 15:07:51 +0300
See also: xsrc/58580
-uwe
From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 07:14:47 -0800
commit what works, heh. I'll go rebase what i'm doing on top of it!
Thanks!
-adrian
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Thu, 5 Feb 2026 01:15:50 +0300
Can you give it some testing for the client/server permutations you
have? Nearly all of my netbsd machines are headless. My macppc mini
is in a closet w/out a monitor and I no longer have anything 13w3 to
hook up to my ultra.
TIA
-uwe
From: Adrian Chadd <adrian@freebsd.org>
To: gnats-bugs@netbsd.org
Cc: xsrc-manager@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Thu, 5 Feb 2026 17:26:35 -0800
i tested both be/le client/server combo, and be server/client.
-a
From: "Valery Ushakov" <uwe@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/59952 CVS commit: xsrc/local/programs/xsetwallpaper
Date: Wed, 11 Feb 2026 00:09:12 +0000
Module Name: xsrc
Committed By: uwe
Date: Wed Feb 11 00:09:12 UTC 2026
Modified Files:
xsrc/local/programs/xsetwallpaper: xsetwallpaper.c
Log Message:
xsetwallpaper: create the image in the server's byte order
PR xsrc/59952
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 xsrc/local/programs/xsetwallpaper/xsetwallpaper.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.