I've received the following proposed patch and explanation for one of
the long standing 64 bit issues. Please, if you have been affected by
these bugs, test it. I have no 64 bit systems to try it on.
I uploaded the patch to the wiki, too.
For reference, the debian bugs that this patch might solve are:
#406559: Evolution alarm pop-up breaks sawfish
#403100: Infinite loop after middle-clicking root window
----- Forwarded message from Thadeu Lima de Souza Cascardo <cascardo minaslivre org> -----
Subject: Bug#406559: Xlib converts 32 bit data to 64 bit
From: Thadeu Lima de Souza Cascardo <cascardo minaslivre org>
Date: Tue, 1 Jan 2008 10:11:13 -0200
To: 403100 bugs debian org, 406559 bugs debian org
X-Spam-Level:
Envelope-to: rodrigo nul-unu com
Delivery-date: Tue, 01 Jan 2008 06:14:27 -0600
Reply-To: Thadeu Lima de Souza Cascardo <cascardo minaslivre org>,
406559 bugs debian org
X-Debian-PR-Message: report 406559
X-Debian-PR-Package: sawfish
X-Debian-PR-Keywords: help
X-Debian-PR-Source: sawfish
Organization: Minas Livre
X-Spam_bar: --
Hello.
I've spent last day investigating this bug. The problem lies whithin
Xlib and the integer format in librep, but the short-term solution goes
in sawfish. I would like to reopen this bug as soon as it is closed and
reassing it to Xlib.
I will describe what I could find out about this bug and attach a patch
that you should test. I also think #403100 and #406559 are the same
bug, but I will wait for a confirmation before merging them.
In fact, I have done my tests based on the experience of #403100,
opening fbpanel, but have watched the same error as in #406559, the bad
argument for make-vector.
The error is triggered when sawfish receives a _NET_WM_DESKTOP from the
client with 0xFFFFFFFF as a parameter, which EWMH describes as sticking
the window for every desktop/workspace. The rep/lisp code is the
following:
((_NET_WM_DESKTOP)
(when (windowp w)
(let ((desktop (aref data 0)))
(if (eql desktop #xffffffff)
;; making window sticky
(make-window-sticky/workspace w)
;; changing the desktop
(make-window-unsticky/workspace w)
(send-window-to-workspace-from-first w desktop nil)))))
This means the window will be made stick to all workspaces if the
parameter is 0xFFFFFFFF and will be made unstick and sent to the
desktop-nth workspace.
In 64 bits, this number turns to be 0xFFFFFFFFFFFFFFFF, i.e., a 64-bit
-1. In amd64, adding this 8 more digits solves the problem. We could do
an or for both values as a solution. Using -1 as a solution does not
solve it, since sawfish creates this rep number as unsigned and librep
turns these into BigInt, since it uses 2 bits in the number
representation for distinguishing between types.
So, when calling the client-message-hook from C code, sawfish creates
the vector and the numbers for the parameters. X protocol has 3 formats
for these messages: 20 8-bit parameters, 10 16-bit parameters or 5
32-bit parameters. _NET_WM_DESKTOP has format 32. Xlib, however, uses
long as the type of the 32-bit parameters. And it tries to be smart
when sending this data to the user, converting it from 32 bit unsigned
to the native long format of the host. So, a 32-bit 1's is converted to
64-bit 1's.
So, what is my fix? Well, before creating the numbers for rep from the
64-bit data Xlib gives us, I convert them back to unsigned 32-bit,
using uint32_t type. So, we get 0xFFFFFFFF back. This is also a more
generic fix, since any other messages, not only _NET_WM_DESKTOP, will
be fixed.
As a bonus, I attach my XCB code that will trigger the problem. Please,
try it and the fix in 32-bit too, so we can be sure there will be no
regression.
Regards,
Thadeu Cascardo.
--- sawfish-1.3.1.old/src/events.c 2008-01-01 01:46:12.000000000 -0200
+++ sawfish-1.3.1/src/events.c 2008-01-01 01:45:22.000000000 -0200
@@ -21,6 +21,7 @@
#include "sawmill.h"
#include <limits.h>
+#include <stdint.h>
#include <string.h>
#include <time.h>
#include <X11/extensions/shape.h>
@@ -641,7 +642,10 @@
case 32:
data = Fmake_vector (rep_MAKE_INT(5), Qnil);
for (i = 0; i < 5; i++)
- rep_VECTI(data,i) = rep_make_long_uint (ev->xclient.data.l[i]);
+ {
+ unsigned long l = (uint32_t) ev->xclient.data.l[i];
+ rep_VECTI(data,i) = rep_make_long_uint (l);
+ }
break;
default:
#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
xcb_atom_t
X_GetAtom (xcb_connection_t *conn, char *name, size_t name_len)
{
xcb_atom_t atom;
xcb_intern_atom_cookie_t cookie;
xcb_intern_atom_reply_t *reply;
cookie = xcb_intern_atom (conn, 0, name_len, name);
reply = xcb_intern_atom_reply (conn, cookie, NULL);
if (reply)
{
atom = reply->atom;
free (reply);
return atom;
}
return -1;
}
int
main (int argc, char **argv)
{
xcb_connection_t *conn;
xcb_screen_iterator_t iter;
xcb_client_message_event_t event;
xcb_void_cookie_t cookie;
xcb_generic_error_t *error;
xcb_window_t root;
xcb_window_t window;
conn = xcb_connect (NULL, NULL);
iter = xcb_setup_roots_iterator (xcb_get_setup (conn));
root = iter.data->root;
window = xcb_generate_id (conn);
fprintf (stdout, "Root window has ID %x\n", root);
fprintf (stdout, "New window has ID %x\n", window);
cookie = xcb_create_window_checked (conn, 0, window, root, 0, 0,
128, 128, XCB_COPY_FROM_PARENT,
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
XCB_COPY_FROM_PARENT, 0, NULL);
error = xcb_request_check (conn, cookie);
if (error != NULL)
{
xcb_request_error_t *rerror = (xcb_request_error_t *) error;
fprintf (stderr, "Could not create window: ");
fprintf (stderr, "Response is %d and error code is %d\n",
error->response_type, error->error_code);
fprintf (stderr, "Bad value is %x\n", rerror->bad_value);
free (error);
}
cookie = xcb_map_window_checked (conn, window);
error = xcb_request_check (conn, cookie);
if (error != NULL)
{
xcb_request_error_t *rerror = (xcb_request_error_t *) error;
fprintf (stderr, "Could not map window: ");
fprintf (stderr, "Response is %d and error code is %d\n",
error->response_type, error->error_code);
fprintf (stderr, "Bad value is %x\n", rerror->bad_value);
free (error);
}
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0xCAFE;
event.window = window;
/*
event.type = X_GetAtom (conn, "_NET_WM_DESKTOP",
sizeof ("_NET_WM_DESKTOP"));
*/
event.type = 241;
memset (event.data.data8, 0, 20);
event.data.data32[0] = -1;
event.data.data32[1] = -1;
cookie = xcb_send_event_checked (conn, 0, root,
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(char *) &event);
error = xcb_request_check (conn, cookie);
if (error != NULL)
{
fprintf (stderr, "Could not send client message: ");
fprintf (stderr, "Response is %d and error code is %d\n",
error->response_type, error->error_code);
free (error);
}
while (1);
xcb_disconnect (conn);
return 0;
}
----- End forwarded message -----
Attachment:
signature.asc
Description: Digital signature